2017-05-06 26 views
-1

我试图找到一种方法来使用remote_pdbentr作为快速测试和开发Python 3多处理应用程序的环境,但它们并没有很好地结合在一起。在entr的控制下运行的调试子进程

考虑下面的琐碎测试用例:

import time 
from multiprocessing import Process 
from remote_pdb import RemotePdb 
def child(): 
    RemotePdb('localhost', 4444).set_trace() 
    while True: 
     print("I am the child") 
     time.sleep(1) 
proc = Process(target=child) 
proc.start() 
proc.join() 

如果我将它保存在一个文件,说, 'mp.py',并与运行:

python mp.py

它的工作原理很友好地。它打破,正如预期,在显示

CRITICAL:root:RemotePdb session open at 127.0.0.1:4444, waiting for connection ... 
RemotePdb session open at 127.0.0.1:4444, waiting for connection ... 

子进程,我可以从,netcat的或socat另一个终端会话连接和使用Python调试器。退出调试器会让孩子和父母一直运行,直到我明确杀死他们。

如果我现在注释掉RemotePdb()调用,并与

ls mp.py | entr -r python mp.py 

下运行的entr控制脚本它可以让我编辑mp.py每次我保存自动获得干净的重新启动。

当我取消注释RemotePdb()调用时出现问题。

的脚本由ENTR重新启动,它打破了孩子像以前一样显示相同的“等待连接”的消息,但如果我尝试在另一个终端窗口netcat连接PDB会议是反应迟钝,没有产出,没有回声 - 只是响应CR的空行。我得到与socat相同的结果。

我正在使用python 3.5.3,entr 3.7,remote_pdb 1.2开发OS X 10.11.6。

就是我要问的: 我会接受,其提供结合了entrremote_pdb或解释清楚为什么不能这样做的好处命令行解的答案。

谢谢!

更新 进一步的测试表明,该-r(重启)选项ENTR需要产生问题,即

ls mp.py | entr python mp.py 

允许调试器连接工作。不幸的是,重启选项对于工作流程是必不可少的。

更新2:问题似乎与设置进程组有关。这是通过entr -r完成的,以确保所有的子进程都可以被杀死。在尝试使用Python脚本替换entr时,我发现如果从IPython shell(!python mp.py)启动脚本,但在父进程中调用os.setpgrp()将产生相同的故障(无调试器I/O)从bash推出。

更新3:remote_pdb的作者和我已独立验证问题不在Linux中发生。这是一个OS X问题,显然与Python套接字和进程组有关。我已经添加到相应的标签。

+0

没有留下解释性评论的downvoting是无益的。 –

回答

0

解决!这是一个旧的OS X python问题,它已经悄悄进入或从未在Pdb中修复过。解决方法是在导入readline之前设置为忽略SIGTTOU。详情请参阅http://bugs.python.org/issue14892

我通过修补我的本地副本pdb.Pdb来解决问题,如下所示。

class Pdb(bdb.Bdb, cmd.Cmd): 

    _previous_sigint_handler = None 

    def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, 
       nosigint=False): 
     bdb.Bdb.__init__(self, skip=skip) 
     cmd.Cmd.__init__(self, completekey, stdin, stdout) 
     if stdout: 
      self.use_rawinput = 0 
     self.prompt = '(Pdb) ' 
     self.aliases = {} 
     self.displaying = {} 
     self.mainpyfile = '' 
     self._wait_for_mainpyfile = False 
     self.tb_lineno = {} 
     # Try to load readline if it exists 
     try: 
############ FIX OSX BUG ###################################### 
      import sys 
      if sys.platform == 'darwin': 
       import signal 
       signal.signal(signal.SIGTTOU, signal.SIG_IGN) 
############ END FIX ########################################## 
      import readline 
      # remove some common file name delimiters 
      readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?') 
     except ImportError: 
      pass    

非常感谢ionelmc,对慷慨的帮助跟踪问题的remote_pdbhunter作者。

相关问题