11

我一直在玩事后调试,但遇到了一些问题。考虑以下名为的python脚本example.py

k = 0
print 1. / k
print 'continue ...'

我可以运行它:

> python -m pdb example.py

然后进入第 2 行print 1. / k,然后设置k = 1,然后继续执行 pdb 命令c

现在,如果我通过事后调试来执行此操作,我将无法继续执行程序。我运行:

> python -i example.py

然后在我落入外壳后,我做了一个:

import pdb
pdb.pm()

然后我可以像以前一样更改 的值k,但我无法继续执行任何程序。Pdb 只是简单地退出。

我找不到任何地方明确指出您不能在事后逐步执行程序。似乎是这样。那么我想了解事后调试的价值。发生错误时检查代码状态的唯一值是什么?

4

1 回答 1

14

当抛出异常时调用事后分析。

此时,堆栈不再“活动”,您无法再单步执行代码。毕竟刚刚抛出了一个异常,表明代码路径不能再继续了。例如result,如果你有这个表达式,你会期望是什么?result = 1. / k

字面上的验尸用于查看患者死亡后(验尸,拉丁文),死因是什么。pdb 事后分析也不例外。你可以看到程序在死亡那一刻的状态,但你不能重新激活死者。

换句话说,事后分析的目的是通过详细检查失败时的程序状态来了解程序失败的原因

该术语尚未在 pdb 手册中明确记录,可能是因为“事后”一词被认为是常用的。Wikipedia 关于调试的文章顺便提到了它,Python 并不是唯一提供该技术的语言;Windows 调试器也提供此功能,R也提供此功能,其他调试器也提供此功能。

如果您希望从追溯中“重新激活”尸体,请知道有巨大的障碍需要克服。虽然异常的回溯确实包括对堆栈中每个帧的全局和本地命名空间的引用,但实时堆栈包含更多未包含在回溯中的状态,即无法重建的状态。这包括附加到嵌套函数的闭包单元(尤其是当产生闭包的父函数本身不是回溯的一部分时),或处理或块所需的内部簿记try..except,或活动或循环使用的迭代器对象。try..finallywithforasync for

对于那些不希望的人,我这样说:程序被传递了!这个程序没有了!它已经不复存在了!'t's过期去见'是制造商!这不是一个僵硬的!生不如死,不能安息!如果你没有把它钉在追溯上,那就不会推高雏菊了!它的评估循环簿记现在是“历史!'t't off the twig!它踢了水桶,摆脱了它的凡人线圈,跑下窗帘,加入了隐形的流血合唱团!这是一个前程序。

(向 John Cleese 和 Michael Palin 道歉)。

于 2012-12-21T17:58:11.993 回答