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

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

有帮助吗?

解决方案

是的,gdb 适合较低级别的调试。

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

例如

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

您还可以查看 Python 特定的调试器,例如 温控数据库, , 或者 pydb. 。两者平台独立。

其他提示

使用 温控数据库. 。它是一个 平台无关 图形化 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 或更高版本。

Screenshot
(来源: 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”宏解析对象是什么。 克里斯有一些例子 在他的博客上。

祝你好运。

(大声喊叫 丹的博客 对我来说一些关键信息,特别是线程修复!)

如果你指的是pydb,那就没有办法了。朝这个方向做了一些努力:查看 svn 提交, ,但它被放弃了。据说 winpdb支持它.

我在 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 进程。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top