2011-01-17 3 views
20

Мне нужно отладить дочерний процесс, порожденный multiprocessing.Process(). Дезаггер pdb, похоже, не знает о разветвлении и не может подключиться к уже запущенным процессам.Как подключить отладчик к подпроцессу python?

Есть ли более умные отладчики python, которые можно подключить к подпроцессу?

ответ

9

Winpdb - это в значительной степени определение более умного отладчика Python. Он явно поддерживает going down a fork, не уверен, что он отлично работает с multiprocessing.Process(), но стоит попробовать.

Список кандидатов для проверки на предмет использования вашего прецедента см. В списке Python Debuggers в вики.

+1

Отлично! Winpdb хорошо работает с multiprocessing.Process() – grep

+0

Следует отметить, что Winpdb - это многоплатформенное, бесплатное и бесплатное программное обеспечение. – OliverUv

+0

Я не мог, в течение 20 минут читать и играть с winpdb, найти способ просто запустить интерактивный сеанс отладки в существующем скрипте через импорт, a la 'import pdb; pdb.set_trace() '. Однако ответ ForkedPdb здесь работал как шарм! – Pat

-1

Если вы находитесь на поддерживаемой платформе, попробуйте DTrace. Большинство семейств BSD/Solaris/OS X поддерживают DTrace.

Here is an intro by the author. Вы можете использовать Dtrace для отладки практически всего.

Here is a SO post по обучению DTrace.

35

Я искал простой в решении этой проблемы и пришел с этим:

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 

Используйте его таким же образом вы можете использовать классический PDB:

ForkedPdb().set_trace() 
+4

это потрясающе и сделал трюк для меня –

+0

Спасибо, это сработало и для меня. – xamox

+0

Красивый трюк. Я предлагаю хранить sys.stdin при запуске программы и использовать это в разветвленном процессе вместо открытия '/ dev/stdin'. Я не знаю причины, но readline отлично работает. Я немного поразмыслил об этом позже. – memeplex

2

Этот является разработкой ответа Ромуальда, который восстанавливает исходный stdin, используя его файловый дескриптор. Это приводит к тому, что readline работает внутри отладчика. Кроме того, специальное управление KeyboardInterrupt pdb отключено, чтобы не мешать многопроцессорному обработчику синтаксиса.

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 
Смежные вопросы