gre*_*rep 31 python debugging subprocess multiprocessing
我需要调试由它生成的子进程multiprocessing.Process().该pdbdegugger似乎不知道分叉的,无法连接到已经运行的进程.
有没有更智能的python调试器可以附加到子进程?
Rom*_*net 57
我一直在寻找一个解决这个问题的简单方法,并想出了这个:
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
Run Code Online (Sandbox Code Playgroud)
使用它与使用经典Pdb的方式相同:
ForkedPdb().set_trace()
Run Code Online (Sandbox Code Playgroud)
这是Romuald的回答的详细说明,它使用文件描述符恢复原始stdin.这使readline在调试器中工作.此外,禁用了KeyboardInterrupt的pdb特殊管理,以免干扰多处理sigint处理程序.
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
Run Code Online (Sandbox Code Playgroud)
Remote-pdb可用于调试子进程。安装完成后,将以下几行放入需要调试的代码中:
import remote_pdb
remote_pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)
Remote-pdb 将打印一个端口号,该端口号将接受 telnet 连接以调试该特定进程。关于工作程序启动顺序有一些注意事项,使用各种前端时标准输出的位置等。为了确保使用特定端口(必须是免费的并且当前用户可以访问),请改用以下命令:
from remote_pdb import RemotePdb
RemotePdb('127.0.0.1', 4444).set_trace()
Run Code Online (Sandbox Code Playgroud)
Remote-pdb 也可以通过Python 3.7 中的breakpoint()命令启动。