是否有调试器可以在运行 Python 代码时调试 Python 虚拟机,类似于GDB
使用 C/C++ 的方式?我在网上搜索并遇到过pdb
,但这一步是通过 Python 解释器执行的代码,而不是 Python 解释器运行程序。
2 回答
Python 的参考实现 CPython 是用 C 编写的。您可以使用 GDB 来调试它,就像调试任何其他用 C 编写的程序一样。
也就是说,Python 确实有一些用于 GDB 的小帮手,隐藏在Misc/gdbinit
. 它有注释来描述每个命令的作用,但为了方便起见,我将在这里重复它们:
pyo
:转储一个PyObject *
。pyg
:转储一个PyGC_Head *
。pylocals
:打印当前 Python 栈帧的局部变量。lineno
:获取当前 Python 行号。pyframe
:打印源文件名、行和函数。pyframev
:pyframe
+pylocals
printframe
:pyframe
如果在PyEval_EvalFrameEx
;frame
否则内置pystack
:打印 Python 堆栈跟踪。pystackv
:使用局部变量打印 Python 堆栈跟踪。pu
:打印一个 Unicode 字符串。
看起来 Fedora 项目也组装了他们自己的命令集合来帮助调试,您可能也想查看这些命令。
如果您希望在字节码级别调试 Python,那正是这样pdb
做的。
如果您正在寻找调试 CPython 参考解释器……正如 icktoofay 的回答所说,它只是一个与其他任何 C 程序一样的 C 程序,因此您可以像任何其他 C 程序一样调试它。(如果需要,您也可以获取源代码,使用额外的调试信息等进行编译。)
你几乎肯定想看看EasierPythonDebugging,它展示了如何设置一堆 GDB 助手(当然是 Python 脚本)来让你的生活更轻松。最重要的是:Python 堆栈与 C 堆栈紧密绑定,但尝试手动映射事物却是一团糟。使用正确的助手,您可以毫不费力地以 Python 术语而不是 C 术语或与 C 术语并行获取堆栈跟踪、帧转储等。另一个很大的好处是py-print
命令,它可以查找 Python 名称(以几乎与实时解释器相同的方式),调用它__repr__
并打印出结果(通过适当的错误处理和一切,这样你就不会最终崩溃你的gdb
会话试图PyObject*
手动行走的东西)。
如果您正在寻找介于两者之间的某个级别……那么,两者之间没有级别。(从概念上讲,解释器有多个层,但都是 C 代码,在 gdb 中看起来很像。)
如果您要调试任何Python 解释器,而不是专门调试 CPython,您可能需要查看 PyPy。它是用一种名为 RPython 的类 Python 语言编写的,有多种方法可以pdb
用来调试 (R)Python 解释器代码,尽管它并不像它可能的那么简单(除非你使用平面翻译的 PyPy,这可能运行大约 100 倍,速度太慢,无法忍受)。PyPy 也有 GDB 调试钩子和脚本,就像 CPython 一样,但它们并不完整。