总而言之:这是pdb 的事后分析模式其中跳跃不应该起作用。但它仍然非常有用。
伦勃朗的绘画(公共领域)
我用 python 3.8.2 重现它 *** Jump failed: can only jump from a 'line' trace event
通过在“pdb 下”运行脚本,如下所示:python3 -m pdb -c c script.py
并尝试跳转到随后出现的 pdb 提示符中的另一行。
发生了什么:在本例中是未处理的异常NameError: name 'b' is not defined
导致 python 停止解释脚本; pdb 拦截了这种情况并进入事后分析模式。
正如阿尔玛·克莱因(Almar Klein)在他的书中很好地指出的那样博客文章 https://almarklein.org/pm-debugging.html,
事后调试是指进入调试模式的概念after有东西坏了。不涉及断点设置,因此速度非常快,您可以检查完整的堆栈跟踪,使其成为跟踪错误的有效方法。
虽然jump
, next
, return
死后不会起作用,bt
, up
, down
, ll
and pp
,以及导入模块并直接在 pdb 的交互式 shell 中运行任意 python 代码的可能性,可以是找到根本原因的非常有效的方法。在我们的简单示例中,根本原因是NameError
快速显示后立即显示ll
: pdb 在有问题的代码行前面加上前缀>>
.
如果我们没有通过-c c
(意义continue
),pdb 会在解释程序的第一行之前显示其提示并暂停,因此您有机会单步执行整个程序或在有问题的行之前或处设置断点,然后跳过它,永远不会进入尸检。
即使在事后分析中,您也可以在程序中的任何位置准备断点,例如break 2
对于第 2 行,并说c
or continue
因此 pdb 将完成事后分析,重新加载文件,并使用更新的断点集重新启动程序。
另一种处理方法是import pdb
and pdb.set_trace()
在可疑代码中 - 或者从 python 3.7 开始,简单地breakpoint()
- 并正常运行 python 程序(不再是“在”pdb 下),这样就可以jump
, next
, return
等等,以及其他一切 - 当断点被击中时。
如果你的Python程序是通过behave
:
- 更喜欢跑步
behave
with --no-capture
每当使用pdb
或类似的调试器(无论是否为事后分析模式),以避免行为的 stdin/stdout 捕获出现问题pdb
无响应和/或其提示不可见。
- 最重要的是,如果你想最终进入
pdb
自动事后模式,同时可能仍支持捕获,设置post_mortem
环境变量(也可以以不同的方式命名)为任何值(但是only在开发机器上,不适用于自动化 CI 或生产!)并将以下内容永久提交到environment.py
:
def after_step(context, step):
import os
if 'post_mortem' in os.environ and step.status == 'failed':
import pdb
# Similar to "behave --no-capture" calling stop_capture() ensures visibility of pdb's prompts,
# while still supporting capture until an uncaught error occurs.
# Warning: this does rely on behave's internals which might change
context._runner.stop_capture() # pylint: disable=protected-access
pdb.post_mortem(step.exc_traceback)