2011-01-17 7 views
20

Ho bisogno di eseguire il debug di un processo figlio generato da multiprocessing.Process(). Il degadger pdb sembra non essere in grado di eseguire il fork e non è in grado di collegarsi a processi già in esecuzione.Come collegare il debugger a una subproccessa python?

Esistono debugger Python più intelligenti che possono essere collegati a un sottoprocesso?

risposta

9

Winpdb è praticamente la definizione di un debugger Python più intelligente. Supporta esplicitamente going down a fork, non è sicuro che funzioni bene con multiprocessing.Process() ma vale la pena provare.

Per un elenco di candidati per verificare l'assistenza del caso d'uso, consultare l'elenco di Python Debuggers nella wiki.

+1

Grande! Winpdb funziona bene con multiprocessing.Process() – grep

+0

Va notato che Winpdb è un software multipiattaforma, gratuito e gratuito. – OliverUv

+0

Non potevo, entro 20 minuti di lettura e riproduzione con winpdb, trovare il modo di avviare una sessione di debugging interattivo in uno script esistente tramite un'importazione, un 'import dpb; pdb.set_trace() '. Tuttavia, la risposta di ForkedPdb qui ha funzionato come un incantesimo! – Pat

-1

Se ci si trova su una piattaforma supportata, provare DTrace. La maggior parte della famiglia BSD/Solaris/OS X supporta DTrace.

Here is an intro by the author. Puoi usare Dtrace per eseguire il debug di qualsiasi cosa.

Here is a SO post sull'apprendimento di DTrace.

35

Sono stato alla ricerca di un semplice soluzione a questo problema e arrivato fino a questo:

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 

Usa allo stesso modo è possibile utilizzare il classico Pdb:

ForkedPdb().set_trace() 
+4

questo è fantastico e ha fatto il trucco per me –

+0

Grazie, questo ha funzionato anche per me. – xamox

+0

Bel trucco. Suggerirò di memorizzare sys.stdin all'avvio del programma e di utilizzarlo nel processo forked invece di aprire '/ dev/stdin'. Non conosco la ragione, ma readline funziona bene allora. Cercherò un po 'su questo più tardi. – memeplex

2

Questo è un'elaborazione della risposta di Romuald che ripristina lo stdin originale usando il suo descrittore di file. Ciò mantiene la lettura funzionante all'interno del debugger. Inoltre, la gestione speciale di pdb di KeyboardInterrupt è disabilitata, per non interferire con il gestore di sigint multiprocessing.

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 
Problemi correlati