35

我正在尝试在多线程 Python 应用程序锁定后调试死锁。有没有办法附加调试器来检查进程的状态?

编辑:我正在 Linux 上尝试这个,但如果有一个跨平台的解决方案会很棒。毕竟是 Python :)

4

9 回答 9

15

使用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

于 2009-02-16T15:18:44.827 回答
11

是的,gdb 适合低级调试。

您可以使用thread命令更改线程。

例如

(gdb) thr 2
[Switching to thread 2 (process 6159 thread 0x3f1b)]
(gdb) backtrace
....

您还可以查看 Python 特定的调试器,例如Winpdbpydb。两者平台独立。

于 2008-09-11T13:19:10.687 回答
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 的博客为我提供了一些关键信息,尤其是线程修复!)

于 2009-02-15T12:18:34.033 回答
4

如果你的意思是 pydb,没有办法做到这一点。在这个方向上做了一些努力: 见 svn commit,但它被放弃了。据说winpdb支持它

于 2008-09-12T14:51:51.753 回答
4

我在 PyDev(Windows XP 上的 Eclipse)中调试多线程程序的经验是,无法挂钩使用 thread.start_new_thread 创建的线程,但可以挂钩使用 threading.Thread 创建的线程。希望信息对您有所帮助。

于 2008-11-10T12:58:24.627 回答
0

你在什么平台上尝试这个?大多数调试器允许您使用进程 ID 附加到正在运行的进程。您可以通过日志记录或使用任务管理器之类的工具输出进程 ID。一旦实现了这一点,就可以检查各个线程及其调用堆栈。

编辑:我对跨平台的 GNU 调试器 (GDB) 没有任何经验,但是我找到了这个链接,它可能会让你走上正确的道路。它解释了如何添加调试符号(便于读取堆栈跟踪)以及如何指示 gdb 附加到正在运行的 python 进程。

于 2008-09-06T19:08:14.230 回答
0

pdbinject允许您将 pdb 注入到已经运行的 python 进程中。

pdbinject 可执行文件只能在 python2 下运行,但也可以很好地注入到 python3 中。

于 2015-03-17T07:18:57.637 回答
0

PyCharm IDE从 4.0 版开始允许附加到正在运行的 Python 进程。

这里描述了如何做到这一点。

于 2015-03-30T19:02:50.973 回答
0

这可以用作一个简单的“远程”调试器:

import sys
import socket
import pdb

def remote_trace():
    server = socket.socket()
    server.bind(('0.0.0.0', 12345))
    server.listen()
    client, _= server.accept()
    stream = client.makefile('rw')
    sys.stdin = sys.stdout = sys.stderr = stream
    pdb.set_trace()

remote_trace()

# Execute in the shell: `telnet 127.0.0.1 12345`

在 Windows 上,使用 Netcat 而不是 Telnet 更容易(它也可以在 linux 上工作)。

于 2019-11-24T22:25:55.487 回答