我按下n键来评估一行代码后,如果出错了,我想回到之前的位置然后按s键进入函数内部执行。这有可能吗?
文档中写道:
j(ump) lineno 设置将要执行的下一行代码。只能在最底层的帧中使用。这允许您返回并重新执行代码,或者向前跳过不想运行的代码。
我按下n键来评估一行代码后,如果出错了,我想回到之前的位置然后按s键进入函数内部执行。这有可能吗?
文档中写道:
j(ump) lineno 设置将要执行的下一行代码。只能在最底层的帧中使用。这允许您返回并重新执行代码,或者向前跳过不想运行的代码。
GNU调试器GDB:它极其缓慢,因为它一次撤销一个机器指令。
Python调试器PDB:命令jump
可以让你回到代码中,但不会撤销程序的状态。
对于Python语言,出于这个原因,扩展的Python调试器原型EPDB被创建。这是论文,这里有程序和代码。
我以EPDB为起点,在我的MSc学位项目中创建了一个实时反向调试器。该论文可在网上找到:结合反向调试和实时编程以实现计算机编程中的视觉思维。在第1章和第2章中,我也涵盖了大多数历史方法的反向调试。
PyPy已经开始实现RevDB,支持反向调试。
截至2017年2月,它仍处于alpha阶段,仅支持Python 2.7,只能在Linux或OS X上运行,并需要您从特殊版本构建Python。 它也非常慢且使用大量RAM。引用Bitbucket页面的话:
请注意,日志文件通常以每秒1-2 MB的速度增长。假设大小不是问题,则限制因素为:
- 重放时间。如果记录的执行时间超过几分钟,重放将非常缓慢。有时需要在单个会话中多次查看整个日志。 如果错误随机但很少发生,您应该运行记录几分钟,然后杀死进程并重复尝试,直到崩溃发生。
- 重放时的RAM使用情况。重放的RAM需求比录制的RAM需求高10到15倍。 如果太多,您可以尝试在_revdb / process.py中使用较低的MAX_SUBPROCESSES值,但它始终会大几倍。
详细信息请查看PyPy博客,安装和使用说明请查看RevDB bitbucket页面。
反向调试(返回以前记录的应用程序状态或向后单步调试)通常是汇编或C级别的调试器功能。例如,gdb可以做到:
https://sourceware.org/gdb/wiki/ReverseDebug
反向调试非常复杂,可能会导致性能下降 50,000 倍。 它还需要来自调试工具的广泛支持。 Python虚拟机不提供反向调试支持。
如果您正在交互式评估Python代码,则建议尝试IPython Notebook,它提供基于HTML的交互式Python shell。您可以轻松编写代码并混合匹配顺序。但是,它没有pdb调试支持。有ipdb,它为输入的调试命令提供更好的历史记录和搜索功能,但据我所知它也不直接进行后向跳转。
虽然你可能无法及时地逆转代码执行,但 pdb
的下一个最佳选择是堆栈帧跳转。
使用 w
查看您在堆栈帧中的位置(底部是最新的),并使用 u(p)
或 d(own)
遍历堆栈帧以访问将您步入当前帧的函数调用所在的帧。