pdb旁路错误/跳转失败:只能从“行”跟踪事件中跳转

时间:2018-11-17 02:44:44

标签: python debugging pdb

我正在尝试使用pdb调试Python程序。该程序可能是这样的:

def main():
    a = 1
    print(b)
    c = 2
    d = 3

显然,print(b)是一个错字,应该是print(a),但这并不重要,我可以使用文本编辑器修复它,但我想绕过此错误并继续调试。

我尝试了跳转,例如跳转4(假设“ c = 2”为第4行),但出现错误“跳转失败:f_lineno只能由行跟踪函数设置”,这意味着我需要给一行编程时跟踪功能。

那么,有没有一种方法可以解决这个问题,或者在使用pdb时还有其他方法可以绕过错误行?

2 个答案:

答案 0 :(得分:3)

TLDR:这是 pdb的验尸模式,在该模式下,跳跃不起作用。但这仍然非常有用。

enter image description here

伦勃朗(公共领域)绘画

我使用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很好地将其放在他的blog post中,

事后调试是指在某些故障之后进入调试模式的概念。没有涉及断点的设置,因此它非常快速,您可以检查整个堆栈跟踪,从而使其成为跟踪错误的有效方法。

尽管jumpnextreturn在验尸,btupdown,{{ 1}}和ll,以及导入模块和直接在pdb的交互式shell中运行任意python代码的可能性,可能是获得根本原因的非常有效的方法。在我们的简单示例中,pp的根本原因会在快速NameError后面立即显示:pdb在有问题的代码行之前加上ll

如果我们没有通过>>(意思是-c c),pdb将在提示程序的第一行之前显示其提示并暂停,因此您将有机会逐步完成整个程序,或在违规行之前或之后设置一个断点,然后跳过它,永远不要进入验尸。

即使在验尸中,您也可以在程序中的任何位置准备断点,例如continue代表第2行,并说break 2c,这样pdb将完成验尸,重新加载文件并使用更新的断点集重新启动程序。


处理它的另一种方法是使用可疑代码continueimport pdb-或从python 3.7开始,只需pdb.set_trace()-并正常运行python程序(而不是“在pdb下” ),然后允许breakpoint()jumpnext等,以及其他所有操作-在遇到断点时。


如果您的Python程序是通过return启动的:

  • 无论何时使用behave或类似的调试器(无论是否验尸模式),都希望与behave一起运行--no-capture,以避免行为的stdin / stdout捕获使{{1 }}反应迟钝和/或它不可见。
  • 最棒的是,如果您希望在可能仍支持捕获的情况下自动进入pdb事后检验模式,请将pdb环境变量(也可以使用不同的名称)设置为任何值(但在开发机上,而不用于自动化CI或生产!),并将以下内容永久提交到pdb中:
post_mortem

答案 1 :(得分:0)

我不确定,但这可能是2018年3月修复的错误,因此您可能需要(修补,升级,重新安装?)您的Python。