有没有办法将调试器附加到多线程的Python进程?
我正在调试一个多线程的Python应用程序,它在运行时出现了死锁,导致程序卡住了。请问有没有办法连接调试工具来查看这个进程的状态?
补充一下:我是在Linux上进行这个操作,但如果有跨平台的解决方案就更好了,毕竟这是Python嘛 :)
10 个回答
8
你可以把调试工具连接到一个多线程的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”宏来解析对象是什么。Chris在他的博客上有一些示例。
祝你好运。
(特别感谢Dan的博客,提供了一些关键的信息,特别是关于线程的修复!)
14
可以使用 Winpdb。它是一个跨平台的图形化 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)