How to attach debugger to a python subproccess?

前端 未结 8 2276
旧巷少年郎
旧巷少年郎 2020-12-22 23:49

I need to debug a child process spawned by multiprocessing.Process(). The pdb degugger seems to be unaware of forking and unable to attach to alrea

相关标签:
8条回答
  • 2020-12-23 00:39

    Building upon @memplex idea, I had to modify it to get it to work with joblib by setting the sys.stdin in the constructor as well as passing it directly along via joblib.

    import os
    import pdb
    import signal
    import sys
    import joblib
    
    _original_stdin_fd = None
    
    class ForkablePdb(pdb.Pdb):
        _original_stdin = None
        _original_pid = os.getpid()
    
        def __init__(self):
            pdb.Pdb.__init__(self)
            if self._original_pid != os.getpid():
                if _original_stdin_fd is None:
                    raise Exception("Must set ForkablePdb._original_stdin_fd to stdin fileno")
    
                self.current_stdin = sys.stdin
                if not self._original_stdin:
                    self._original_stdin = os.fdopen(_original_stdin_fd)
                sys.stdin = self._original_stdin
    
        def _cmdloop(self):
            try:
                self.cmdloop()
            finally:
                sys.stdin = self.current_stdin
    
    def handle_pdb(sig, frame):
        ForkablePdb().set_trace(frame)
    
    def test(i, fileno):
        global _original_stdin_fd
        _original_stdin_fd = fileno
        while True:
            pass    
    
    if __name__ == '__main__':
        print "PID: %d" % os.getpid()
        signal.signal(signal.SIGUSR2, handle_pdb)
        ForkablePdb().set_trace()
        fileno = sys.stdin.fileno()
        joblib.Parallel(n_jobs=2)(joblib.delayed(test)(i, fileno) for i in range(10))
    
    0 讨论(0)
  • 2020-12-23 00:43

    remote-pdb can be used to debug sub-processes. After installation, put the following lines in the code you need to debug:

    import remote_pdb
    remote_pdb.set_trace()
    

    remote-pdb will print a port number which will accept a telnet connection for debugging that specific process. There are some caveats around worker launch order, where stdout goes when using various frontends, etc. To ensure a specific port is used (must be free and accessible to the current user), use the following instead:

    from remote_pdb import RemotePdb
    RemotePdb('127.0.0.1', 4444).set_trace()
    

    remote-pdb may also be launched via the breakpoint() command in Python 3.7.

    0 讨论(0)
提交回复
热议问题