2011-01-17 3 views
20

Ich muss einen Kindprozess debuggen, der von multiprocessing.Process() erzeugt wird. Der pdb Degugger scheint sich der Verzweigung nicht bewusst zu sein und kann nicht an bereits laufende Prozesse anhängen.Wie kann der Debugger an einen Python-Subprocess angehängt werden?

Gibt es intelligentere Python-Debugger, die an einen Subprozess angehängt werden können?

Antwort

9

Winpdb ist so ziemlich die Definition eines intelligenteren Python-Debuggers. Es unterstützt ausdrücklich going down a fork, nicht sicher, dass es gut mit multiprocessing.Process() funktioniert, aber es ist einen Versuch wert.

Eine Liste der Kandidaten, die Sie auf Unterstützung für Ihren Anwendungsfall prüfen können, finden Sie in der Liste der Python Debuggers im Wiki.

+1

Großartig! Winpdb funktioniert gut mit multiprocessing.Process() – grep

+0

Es sollte angemerkt werden, dass Winpdb Multi-Plattform, freie und Freie Software ist. – OliverUv

+0

Ich konnte nicht innerhalb von 20 Minuten nach dem Lesen und Spielen mit winpdb einen Weg finden, einfach eine interaktive Debugging-Sitzung in einem vorhandenen Skript über einen Import zu starten, a la 'import pdb; pdb.set_trace() '. Wie auch immer, die ForkedPdb Antwort funktionierte wie ein Zauber! – Pat

35

Ich habe für dieses Problem eine einfache Lösung zu suchen und kam mit dieser:

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 

es die gleiche Weise verwenden können Sie die klassische Pdb verwenden:

ForkedPdb().set_trace() 
+4

das ist großartig und hat den Trick für mich –

+0

Danke, das hat auch für mich funktioniert. – xamox

+0

Netter Trick. Ich werde vorschlagen, sys.stdin zu speichern, wenn das Programm startet, und das im forked-Prozess zu verwenden, anstatt '/ dev/stdin' zu öffnen. Ich kenne den Grund nicht, aber readline funktioniert gut. Ich werde später etwas darüber nachforschen. – memeplex

2

Diese ist eine Ausarbeitung von Romualds Antwort, die die ursprüngliche stdin unter Verwendung ihres Dateideskriptors wiederherstellt. Dadurch bleibt readline im Debugger aktiv. Außerdem ist die pdb-Spezialverwaltung von KeyboardInterrupt deaktiviert, um den Multiprozessor-Sigint-Handler nicht zu stören.

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