如何从堆栈跟踪中提取局部变量?

威尔弗雷德·休斯

假设我有一个引发意外异常的函数,因此将其包装在ipdb中:

def boom(x, y):
    try:
        x / y
    except Exception as e:
        import ipdb; ipdb.set_trace()

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    main()

我可以向上移动堆栈以找出x和y的值:

$ python crash.py 
> /tmp/crash.py(6)boom()
      5     except Exception as e:
----> 6         import ipdb; ipdb.set_trace()
      7 

ipdb> u
> /tmp/crash.py(11)main()
     10     y = 0
---> 11     boom(x, y)
     12 

ipdb> p y
0

但是,在调试时,我只想将调试器放在顶层:

def boom(x, y):
    x / y

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        import ipdb; ipdb.set_trace()

我可以显示回溯,但是无法查看函数内部的变量:

$ python crash.py 
> /tmp/crash.py(14)<module>()
     12         main()
     13     except Exception as e:
---> 14         import ipdb; ipdb.set_trace()

ipdb> !import traceback; traceback.print_exc(e)
Traceback (most recent call last):
  File "crash.py", line 12, in <module>
    main()
  File "crash.py", line 8, in main
    boom(x, y)
  File "crash.py", line 3, in boom
    x / y
ZeroDivisionError: integer division or modulo by zero
ipdb> d # I want to see what value x and y had!
*** Newest frame

发生异常时,异常对象显然仍具有对堆栈的引用。我可以访问x,并y在这里,尽管堆栈有解开?

威尔弗雷德·休斯

事实证明,可以从回溯对象中提取变量。

要手动提取值:

ipdb> !import sys
ipdb> !tb = sys.exc_info()[2]
ipdb> p tb.tb_next.tb_frame.f_locals
{'y': 0, 'x': 2}

更好的是,您可以使用异常来对该堆栈进行事后调试:

import sys

def boom(x, y):
    x / y

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        # Most debuggers allow you to just do .post_mortem()
        # but see https://github.com/gotcha/ipdb/pull/94
        tb = sys.exc_info()[2]
        import ipdb; ipdb.post_mortem(tb)

这使我们直接进入有问题的代码:

> /tmp/crash.py(4)boom()
      3 def boom(x, y):
----> 4     x / y
      5 

ipdb> p x
2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Linux进程堆栈被局部变量溢出(堆栈保护)

Java内存(堆栈)分配给局部变量

从JVM的堆栈框架获取局部变量

将堆栈用于局部变量的背后的想法是什么?

返回指向局部变量的指针时的堆栈行为

在Visual Studio或ReSharper中提取局部变量的快捷方式(对于C#)

局部变量:它们始终在堆栈上吗?

堆栈上的局部变量位置未更改

为什么在spark中提取局部变量的参数被认为更安全?

Java字节码:局部变量表与堆栈计算

堆栈上的局部变量地址

作为函数返回值返回的局部变量(堆栈)

流程如何跟踪其局部变量

如何在Python中跟踪局部变量的值?

如何从日志文件中提取Java堆栈跟踪的时间戳?

.NET CLI:如果不在本地,则如何从堆栈中弹出局部变量?

函数调用时如何在堆栈中组织局部变量?

局部变量(大数组)的初始化如何影响堆栈大小?

编译堆栈机的局部变量

为什么要保留局部变量的堆栈空间?

如何创建局部变量以跟踪将输出是否为首次付款的ID

什么时候创建局部变量堆栈?

如何从Javascript函数中正确提取局部变量?

是否可以从Ruby的堆栈跟踪中提取局部变量及其值?

如何正确引用堆栈上的局部变量

如何使用 mockito 模拟局部变量

汇编x86-返回地址被压入堆栈后,堆栈指针如何保持局部变量的正确位置?

错误:与局部变量关联的堆栈内存地址

CompilerError:堆栈太深,尝试删除局部变量