题
我正在尝试调试多线程 Python 应用程序锁定后的死锁。有没有办法附加调试器来检查进程的状态?
编辑:我正在 Linux 上尝试这个,但如果有一个跨平台的解决方案那就太好了。毕竟是 Python :)
其他提示
使用 温控数据库. 。它是一个 平台无关 图形化 GPL Python 调试器,支持通过网络进行远程调试、多线程、命名空间修改、嵌入式调试、加密通信,并且速度比 pdb 快 20 倍。
特征:
- GPL 许可证。Winpdb 是免费软件。
- 与 CPython 2.3 至 2.6 和 Python 3000 兼容
- 与 wxPython 2.6 到 2.8 兼容
- 独立于平台,并在 Ubuntu Gutsy 和 Windows XP 上进行了测试。
- 用户界面:rpdb2 基于控制台,而 winpdb 需要 wxPython 2.6 或更高版本。
(来源: winpdb.org)
您可以将调试器附加到多线程 Python 进程,但需要在 C 级别执行。为了理解正在发生的事情,您需要使用符号来编译 Python 解释器。如果您没有,则需要从 python.org 下载源代码并自行构建:
./configure --prefix=/usr/local/pydbg
make OPT=-g
sudo make install
sudo ln -s /usr/local/pydbg/bin/python /usr/local/bin/dbgpy
确保您的工作负载正在该版本的解释器上运行。然后您可以随时使用 GDB 附加到它。Python 人员在其 Misc 目录中包含了一个示例“.gdbinit”,其中包含一些有用的宏。然而,它对于多线程调试来说是错误的(!)。你需要像这样替换行
while $pc < Py_Main || $pc > Py_GetArgcArgv
具有以下内容:
while ($pc < Py_Main || $pc > Py_GetArgcArgv) && ($pc < t_bootstrap || $pc > thread_PyThread_start_new_thread)
否则像这样的命令 pystack
不会在主线程以外的线程上终止。有了这些东西,你就可以做类似的事情
gdb> attach <PID>
gdb> info threads
gdb> thread <N>
gdb> bt
gdb> pystack
gdb> detach
看看发生了什么。有点儿。
您可以使用“pyo”宏解析对象是什么。 克里斯有一些例子 在他的博客上。
祝你好运。
(大声喊叫 丹的博客 对我来说一些关键信息,特别是线程修复!)
我在 PyDev(Windows XP 上的 Eclipse)中调试多线程程序的经验是,使用 thread.start_new_thread 创建的线程无法被挂钩,但使用 threading.Thread 创建的线程可以被挂钩。希望这些信息有帮助。
您在什么平台上尝试此操作?大多数调试器允许您使用进程 ID 附加到正在运行的进程。您可以通过日志记录或使用任务管理器等工具输出进程 ID。一旦实现了这一点,就可以检查各个线程及其调用堆栈。
编辑:我对跨平台的 GNU 调试器 (GDB) 没有任何经验,但是我发现了这个 关联 它可能会让你走上正确的道路。它解释了如何添加调试符号(方便读取堆栈跟踪)以及如何指示 gdb 附加到正在运行的 python 进程。
数据库注入 允许您将 pdb 注入到已经运行的 python 进程中。
pdbinject 可执行文件仅在 python2 下工作,但也可以很好地注入到 python3 中。
PyCharm 集成开发环境 自 4.0 版起允许附加到正在运行的 Python 进程。
这里 描述了如何做到这一点。