2017-05-06 1 views
-1

J'essaie de trouver un moyen d'utiliser remote_pdb et entr ensemble comme un environnement pour le test rapide et le développement d'applications multitraitement Python 3, mais ils ne jouent pas bien ensemble.Déboguer le processus enfant s'exécutant sous le contrôle d'entr

Prenons le cas de test trivial ci-dessous:

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() 

Si je l'enregistrer dans un fichier, par exemple, 'mp.py' et la course avec:

python mp.py

il fonctionne très gentiment. Il se brise, comme prévu, dans le processus de l'enfant affichage

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 ... 

et je peux connecter à partir d'une autre session de terminal avec netcat ou socat et utiliser le débogueur de python. Quitter le débogueur laisse l'enfant et le parent en cours d'exécution jusqu'à ce que je les tue explicitement.

Si je maintenant en commentaire l'appel et exécutez le script RemotePdb() sous le contrôle de entr avec

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

il me permet d'éditer mp.py et obtenir un redémarrage automatique propre à chaque fois que je sauve.

Le problème se pose lorsque je décommente l'appel RemotePdb().

Le script est relancé par ENTR et il se brise l'enfant affiche le même message « attente de connexion » comme avant, mais si je tente de me connecter avec netcat dans une autre fenêtre de terminal la session pdb ne répond pas sans sortie et pas echo - juste des lignes vides en réponse à CR. J'obtiens le même résultat avec socat.

Je développe sur OS X 10.11.6 avec python 3.5.3, entr 3.7, remote_pdb 1.2.

Ce que je vous demande: Je vais accepter une réponse qui fournit une solution de ligne de commande qui combine les avantages de entr et remote_pdb ou une explication claire pourquoi il ne peut pas être fait.

Merci!

Mise à jour D'autres tests montre que l'option -r (redémarrage) à ENTR est nécessaire pour produire le problème, à savoir

ls mp.py | entr python mp.py 

permet la connexion débogueur au travail. Malheureusement, l'option de redémarrage est essentielle pour le flux de travail.

Mise à jour 2: Le problème semble être lié à la définition du groupe de processus. Ceci est fait par entr -r pour s'assurer que tous les processus enfants peuvent être tués. Tout en essayant de trouver un script Python pour remplacer entr, j'ai trouvé que l'appel os.setpgrp() dans le processus parent produira le même échec (pas d'E/S au débogueur) si le script est lancé à partir d'un shell IPython (!python mp.py) mais pas si lancé à partir de bash.

Mise à jour 3: L'auteur de remote_pdb et moi-même avons vérifié de manière indépendante que le problème ne se produisait pas sous Linux. C'est un problème d'OS X qui a apparemment quelque chose à voir avec les sockets et les groupes de processus Python. J'ai ajouté aux tags en conséquence.

+0

Diminuer le champ sans laisser de commentaire explicatif n'est pas utile. –

Répondre

0

Résolu! Il s'agit d'un ancien problème python OS X qui s'est replié ou n'a jamais été corrigé dans Pdb. Le correctif consiste à configurer pour ignorer SIGTTOU avant d'importer readline. Voir http://bugs.python.org/issue14892 pour plus de détails.

J'ai résolu le problème en corrigeant ma copie locale de pdb.Pdb comme indiqué ci-dessous.

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    

Un grand merci à ionelmc, auteur de remote_pdb et hunter pour l'aide généreuse traquer le problème.