如何将调试器附加到 Python 子进程?

51 投票
10 回答
28693 浏览
提问于 2025-04-16 10:07

我需要调试一个由 multiprocessing.Process() 创建的子进程。可是 pdb 这个调试工具似乎对进程的分叉不太了解,无法连接到已经在运行的进程上。

有没有更聪明的 Python 调试工具,可以连接到子进程上呢?

10 个回答

13

这是对Romuald回答的详细说明,主要是通过文件描述符来恢复原来的标准输入。这么做可以让readline在调试器里继续正常工作。此外,还禁用了pdb对KeyboardInterrupt的特殊处理,以免它干扰多进程的信号处理。

class ForkablePdb(pdb.Pdb):

    _original_stdin_fd = sys.stdin.fileno()
    _original_stdin = None

    def __init__(self):
        pdb.Pdb.__init__(self, nosigint=True)

    def _cmdloop(self):
        current_stdin = sys.stdin
        try:
            if not self._original_stdin:
                self._original_stdin = os.fdopen(self._original_stdin_fd)
            sys.stdin = self._original_stdin
            self.cmdloop()
        finally:
            sys.stdin = current_stdin
104

我一直在寻找这个问题的简单解决方案,最后想到了这个:

import sys
import pdb

class ForkedPdb(pdb.Pdb):
    """A Pdb subclass that may be used
    from a forked multiprocessing child

    """
    def interaction(self, *args, **kwargs):
        _stdin = sys.stdin
        try:
            sys.stdin = open('/dev/stdin')
            pdb.Pdb.interaction(self, *args, **kwargs)
        finally:
            sys.stdin = _stdin

你可以像使用经典的Pdb那样使用它:

ForkedPdb().set_trace()
14

Winpdb 可以说是一个非常聪明的 Python 调试工具。它特别支持 处理分支,不过我不太确定它和 multiprocessing.Process() 一起使用时效果如何,但试试看也是值得的。

如果你想找一些可以支持你需求的调试工具,可以查看这个 Python 调试器 的列表。

撰写回答