我正在尝试使用pdb调试Python程序。该程序可能是这样的:
def main():
a = 1
print(b)
c = 2
d = 3
显然,print(b)是一个错字,应该是print(a),但并不重要,我可以使用文本编辑器进行修复,但我想绕过此错误并继续调试。
我尝试了跳转,例如跳转4(假设“c = 2”为第4行),但出现错误“跳转失败:f_lineno只能由行跟踪函数设置”,这意味着我需要在以下情况下提供行跟踪函数我正在编程。
因此,有没有一种方法可以解决此问题,或者在使用pdb时是否有其他方法可以绕过错误行?
最佳答案
TLDR:这是 pdb的验尸模式,在该模式下跳跃不起作用。但是它仍然非常有用。
伦勃朗绘画(公共(public)领域)
我通过像这样运行脚本“在pdb下”,以python 3.8.2作为 *** Jump failed: can only jump from a 'line' trace event
来重现它:python3 -m pdb -c c script.py
并尝试跳转到随后出现的pdb提示符下的另一行。
发生了什么:一个未处理的异常,在这种情况下NameError: name 'b' is not defined
导致python停止解释脚本; pdb截获了这种情况,并进入了事后检验模式。
正如阿尔玛·克莱因(Almar Klein)很好地将其放在blog post中一样,
尽管jump
,next
,return
在事后验尸中不起作用,但bt
,up
,down
,ll
和pp
以及可以在pdb的交互式shell中直接导入模块并运行任意python代码的方法,可能是非常有效的获取方式根本原因。在我们的简单示例中,在快速生成NameError
时会立即显示ll
的根本原因:pdb在有问题的代码行之前添加了>>
前缀。
如果我们没有传递-c c
(意思是continue
),pdb会在解释程序的第一行之前显示其提示并暂停,因此您将有机会逐步浏览整个程序或在违规之前或之后设置断点线,并跳过它,永远不要进入验尸。
即使在验尸中,您也可以在程序中的任何位置准备断点,例如第2行的break 2
,说出c
或continue
,以便pdb完成验尸,重新加载文件并使用更新的断点集重新启动程序。
处理它的另一种方法是使用可疑代码import pdb
和pdb.set_trace()
-或从python 3.7开始,只是breakpoint()
-并正常运行python程序(不再位于pdb下),然后允许jump
,next
,return
等以及其他一切-当断点被击中时。
如果您的Python程序是通过behave
启动的:
behave
或类似的调试器(无论是否为事后验尸模式)时,都将--no-capture
与pdb
一起运行,以避免行为的stdin/stdout捕获导致pdb
无响应和/或其提示不可见。 pdb
后验模式结束,请将post_mortem
环境变量(也可以使用不同的名称)设置为任何值(但在dev机器上,仅是,而不是进行自动化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)
关于python - pdb旁路错误/跳转失败: can only jump from a 'line' trace event,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53347730/