- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 pdb 调试一个名为 a.py
的程序
def f(x) :
x / x
def g(x) :
try :
f(x)
except Exception as e :
assert 0
g(0)
当我使用 python3 -m pdb a.py
运行程序时,程序在 assert 0
行停止,我得到以下错误信息:
Traceback (most recent call last):
File "/tmp/a.py", line 6, in g
f(x)
File "/tmp/a.py", line 2, in f
x / x
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib64/python3.6/pdb.py", line 1667, in main
pdb._runscript(mainpyfile)
File "/usr/lib64/python3.6/pdb.py", line 1548, in _runscript
self.run(statement)
File "/usr/lib64/python3.6/bdb.py", line 434, in run
exec(cmd, globals, locals)
File "<string>", line 1, in <module>
File "/tmp/a.py", line 11, in <module>
g(0)
File "/tmp/a.py", line 9, in g
assert 0
AssertionError
堆栈是(使用bt
命令显示):
(Pdb) bt
/usr/lib64/python3.6/pdb.py(1667)main()
-> pdb._runscript(mainpyfile)
/usr/lib64/python3.6/pdb.py(1548)_runscript()
-> self.run(statement)
/usr/lib64/python3.6/bdb.py(434)run()
-> exec(cmd, globals, locals)
<string>(1)<module>()->None
/tmp/a.py(11)<module>()->None
-> g(0)
> /tmp/a.py(9)g()
-> assert 0
(Pdb)
问题是,我无法使用 up
和 down
去函数 f 调试 x/x
,因为我的堆栈结束于g 函数。
我应该如何在异常中调试此类异常?异常中的异常中的异常......怎么样?
最佳答案
tl;dr:即使您已经对外部异常进行事后调试,您也可以调试内部异常。方法如下:
pdb
进入交互模式(在 pdb
提示符中键入 interact
)。import pdb, sys; pdb.post_mortem(sys.last_value.__context__.__traceback__)
注意:
__context__
替换为 __cause__
;如果嵌套更深,还可以附加更多 __context__
或 __cause__
。sys.last_value
替换为 sys.exc_info()[1]
.如果您不确定,请在继续之前检查异常值。 (感谢 @The Doctor 在评论中指出这一点)pdb
session ,允许您调试内部异常。以下是对这项工作的原因的详细解释。在深入解决方案之前,我将首先解释一些相关概念:
链式异常
这里的“异常(exception)中的异常(exception)”被称为chained exceptions .异常可以显式或隐式链接:
>>>: try:
...: raise ZeroDivisionError
...: except Exception as inner_exc:
...: raise ValueError # implicit chaining
...:
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-6-1ae22e81c853> in <module>
1 try:
----> 2 raise ZeroDivisionError
3 except Exception as inner_exc:
ZeroDivisionError:
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-6-1ae22e81c853> in <module>
2 raise ZeroDivisionError
3 except Exception as inner_exc:
----> 4 raise ValueError # implicit chaining
ValueError:
>>>: try:
...: raise ZeroDivisionError
...: except Exception as inner_exc:
...: raise ValueError from inner_exc # explicit chaining
...:
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-5-63c49fcb10a2> in <module>
1 try:
----> 2 raise ZeroDivisionError
3 except Exception as inner_exc:
ZeroDivisionError:
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-5-63c49fcb10a2> in <module>
2 raise ZeroDivisionError
3 except Exception as inner_exc:
----> 4 raise ValueError from inner_exc # explicit chaining
ValueError:
如果我们将外部异常捕获为 outer_exc
,那么我们可以通过 outer_exc.__cause__
(如果显式链接)或 outer_exc.__context__< 检查内部异常
(如果隐式链接)。
事后调试
使用 python -m pdb
运行脚本允许 Python 调试器输入 post-mortem debugging异常模式。这里的“Post-mortem”是指“异常发生之后”。您可以通过运行 %debug
魔术从 IPython 控制台或 Jupyter 笔记本中执行相同的操作。
如果您有权访问回溯对象,您也可以手动进入事后 Debug模式。幸运的是,回溯对象作为 __traceback__
属性存储在异常对象本身:
>>> try:
... raise ZeroDivisionError:
... except Exception as e:
... # Variable `e` is local to this block, so we store it in another variable
... # to extend its lifetime.
... exc = e
>>> import pdb
>>> pdb.post_mortem(exc.__traceback__)
> <ipython-input-8-e5b5ed89e466>(2)<module>()
-> raise ZeroDivisionError
(Pdb)
调试链式异常
现在我们可以尝试调试链式异常了!假设我们已经处于外部异常的事后 Debug模式。我们需要做的是:
pdb.post_mortem()
。这是我们的工作:# First, enter interactive mode to execute commands.
(Pdb) interact
*interactive*
# The current exception is stored in `sys.exc_info()`. This gives back a tuple
# of (exception type, exception value, traceback).
>>> import sys
>>> sys.exc_info()
(<class 'AssertionError'>, AssertionError(), <traceback object at 0x10c683e00>)
>>> sys.exc_info()[1]
AssertionError()
# In our case, the inner exception is implicitly chained. Access it through
# the `__context__` attribute.
>>> sys.exc_info()[1].__context__
ZeroDivisionError('division by zero')
# Get its traceback, and enter post-mortem debugging.
>>> sys.exc_info()[1].__context__.__traceback__
<traceback object at 0x10c683c80>
>>> import pdb
>>> pdb.post_mortem(sys.exc_info()[1].__context__.__traceback__)
> test.py(2)f()
-> x / x
(Pdb)
给你!您现在可以使用普通的 pdb
命令调试内部异常,例如遍历堆栈或检查局部变量。
关于python - Pdb 在异常中转到异常中的帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52081929/
我正在启动一个 web api 项目,当我尝试在逻辑层(这是一个单独的 csproj)中设置断点时我注意到了这个问题,它显示了未经验证的断点。 深入研究后,我发现调试控制台显示“无法找到或打开 PDB
我已经下载了 FreeImage 源代码并自己为 X64 MT DLL 进行了静态构建。 一切正常,除了当我在 freeimage.lib 文件中使用链接时,我收到很多烦人的链接器警告,我不太了解原因
Ubuntu 16.04 Python 3.5.2 如果我运行 python,在 virtualenv 中,我会得到 Python 3.5.2。 问题是: (photoarchive) admin@s
在 pdb 模式下,我经常想单步执行一个函数。这是一个说明我可能会做什么的情况。给定代码: def f(x): print('doing important stuff..') res
我有父进程调用它的子进程。我把 import pdb; pdb.set_trace() 进入子进程代码。 当我使用 python -m pdb parent.py 启动父级时,它被卡住了。调试器不响应
这个问题在这里已经有了答案: Cannot find or open the PDB file in Visual Studio C++ 2010 (7 个答案) 关闭 8 年前。 我正在使用最近升
我对 python 和 pdb 比较陌生,但我对 gdb 有很多经验。 我的问题是,如果我在某个时候在我的代码中设置了一些断点,我将想要更改某些内容并重新运行我的调试 session ,同时保留这些断
我对编译器和链接器 PDB 文件分别有什么区别感到困惑(即在 Visual Studio 中,Project Properties > C/C++ > Output Files >程序数据库文件名 v
我有一个 PDB 文件列表。我想使用 BioPython 中的 Bio.PDB 模块提取所有文件的配体(因此,杂原子)并将每个单独保存到 PDB 文件中。 我尝试了一些解决方案,例如:Remove h
尝试使用 pdb 调试我的基于 python 的 roguelike。我想弄清楚的是,函数handle_keys()是否像我所问的那样返回0。我有另一个函数没有按预期运行,所以我试图找出问题发生的地方
我有私有(private) pdb 文件,我必须将其转换为公共(public)文件。有工具吗? 最佳答案 使用PDBCopy . pdbcopy 是 Windows 调试工具的一部分,可通过 Wind
在静态编译的链接阶段在 Windows 上构建时可能会出现 LNK4099 警告。 例如使用 nmake 和 VC10 进行构建时,我收到一连串 LNK4099 警告,例如: libcurl_a_de
我的 Visual Studio 2013 ASP.NET webform 应用程序有 3 个 DLL 程序集。调试时,DLL 和 PDB 仅在三个 DLL 中的两个(项目/VB 模块和一个 C# 模
我有一个 Python 程序,里面有一个函数 foo()。 我使用 PDB 运行程序,并在程序中某处的任意断点处停止。 现在,我可以很容易地从 PDB 中调用 foo(),我只需键入: !foo()
我正在尝试使用 this tutorial 学习 pdb引用自 another stackoverflow question ,我正处于“入门”部分的第 3 步。 In [12]: %paste #
我有 DLL,并且有用于创建 DLL 的确切源代码。当我们从客户那里获得转储文件时,我希望我们的本地符号服务器能够工作。 (在我们产品的下一个补丁/版本之前无法在客户站点更新 DLL) 最佳答案 这似
这个问题可能真的很愚蠢,但就是这样。以下语句触发特定电子邮件的异常: File "/Users/me/tools/maildir-deduplicate/maildir_deduplicate/m
在从我的旧 XP 移动到新的 vista PC 后,我在 VS2005 中的一个旧项目中收到以下几个警告: UnitTest++.vsnet2005.lib(TestRunner.obj) : 警告
我正在尝试使用 Visual Studio 编译 Qt 4.8.6 项目(我使用的是用于 Qt4.8.6 的 visual studio 插件)。我在调试和 Release模式 (-debug-and
我想用ipdb而不是 pdb与 py.test --pdb选项。这可能吗?如果是这样,如何? 显然,我可以使用 import ipdb; ipdb.set_trace()在代码中但需要运行测试,观察它
我是一名优秀的程序员,十分优秀!