有没有一种方法可以将调试器添加到多线程Python进程上?
我试图在锁定后在多线程Python应用程序中调试死锁。有没有办法连接调试器来检查进程的状态?
编辑:我正在Linux上尝试此操作,但是如果有跨平台的解决方案,那就太好了。毕竟是Python :)
解决方案
回答
我们正在哪个平台上尝试?大多数调试器允许我们使用进程ID添加到正在运行的进程。
我们可以通过日志记录或者使用"任务管理器"之类的方法输出进程ID。
一旦实现,就可以检查单个线程及其调用堆栈。
编辑:我没有跨平台的GNU调试器(GDB)的任何经验,但是我发现了此链接,它可能会使我们踏上正确的道路。它说明了如何添加调试符号(方便阅读堆栈跟踪信息)以及如何指示gdb添加到正在运行的python进程。
回答
是的,gdb适用于较低级别的调试。
我们可以使用thread命令更改线程。
例如
(gdb) thr 2 [Switching to thread 2 (process 6159 thread 0x3f1b)] (gdb) backtrace ....
我们还可以检出Python特定的调试器,例如Winpdb或者pydb。两者均独立于平台。
回答
如果意思是pydb,则没有办法。在这个方向上做了一些努力:
看到svn commit,但是被放弃了。据说winpdb支持它。
回答
我在PyDev(在Windows XP上为Eclipse)上调试多线程程序的经验是,不能钩住使用thread.start_new_thread创建的线程,但是可以钩住使用threading.Thread创建的线程。希望这些信息对我们有所帮助。
回答
我们可以将调试器添加到多线程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"宏解析对象。克里斯在他的博客上有一些例子。
祝你好运。
(大声疾呼Dan的博客为我提供了一些关键信息,特别是线程修复!)
回答
使用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或者更高版本。
屏幕截图http://winpdb.org/images/screenshot_winpdb_small.jpg