на обучение DTrace.

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

Существуют ли более умные отладчики Python, которые можно подключить к подпроцессу?

Ответы на вопрос(6)

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

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
 vks08 янв. 2019 г., 21:14
This keeps readline working inside the debugger что это значит ?
 vks09 янв. 2019 г., 19:48
согласно вашему решению, pdb будет работать, даже если мы охватим новый процесс через многопроцессорность?
 vks09 янв. 2019 г., 19:38
чем это отличается от приведенного выше ответа ... Я имею в виду, что это меняет или что еще добавляет ... прошу прощения за наивность .... меньше информации об этом
 memeplex09 янв. 2019 г., 19:29
Он восстанавливает потоковую линию чтения, к которой привязан stdin текущего процесса.
 memeplex09 янв. 2019 г., 19:45
Насколько я помню, он работает, когда вы отлаживаете несколько процессов, помимо функции sigint.

мне пришлось изменить ее, чтобы она работала сjoblib установивsys.stdin в конструкторе, а также передавая его напрямую через joblib.

<!-- language: lang-py -->
import os
import pdb
import signal
import sys
import joblib

_original_stdin_fd = None

class ForkablePdb(pdb.Pdb):
    _original_stdin = None
    _original_pid = os.getpid()

    def __init__(self):
        pdb.Pdb.__init__(self)
        if self._original_pid != os.getpid():
            if _original_stdin_fd is None:
                raise Exception("Must set ForkablePdb._original_stdin_fd to stdin fileno")

            self.current_stdin = sys.stdin
            if not self._original_stdin:
                self._original_stdin = os.fdopen(_original_stdin_fd)
            sys.stdin = self._original_stdin

    def _cmdloop(self):
        try:
            self.cmdloop()
        finally:
            sys.stdin = self.current_stdin

def handle_pdb(sig, frame):
    ForkablePdb().set_trace(frame)

def test(i, fileno):
    global _original_stdin_fd
    _original_stdin_fd = fileno
    while True:
        pass    

if __name__ == '__main__':
    print "PID: %d" % os.getpid()
    signal.signal(signal.SIGUSR2, handle_pdb)
    ForkablePdb().set_trace()
    fileno = sys.stdin.fileno()
    joblib.Parallel(n_jobs=2)(joblib.delayed(test)(i, fileno) for i in range(10))

чтобы имитировать реализацию методов, которые вы используете из многопроцессорной обработки:

from multiprocessing import Pool


class DummyPool():
    @staticmethod
    def apply_async(func, args, kwds):
        return DummyApplyResult(func(*args, **kwds))

    def close(self): pass
    def join(self): pass


class DummyApplyResult():
    def __init__(self, result):
        self.result = result

    def get(self):
        return self.result


def foo(a, b, switch):
    # set trace when DummyPool is used
    # import ipdb; ipdb.set_trace()
    if switch:
        return b - a
    else:
        return a - b


if __name__ == '__main__':
    xml = etree.parse('C:/Users/anmendoza/Downloads/jim - 8.1/running-config.xml')
    pool = DummyPool()  # switch between Pool() and DummyPool() here
    results = []
    results.append(pool.apply_async(foo, args=(1, 100), kwds={'switch': True}))
    pool.close()
    pool.join()
    results[0].get()
Решение Вопроса

Winpdb это в значительной степени определение более умного отладчика Python. Явно поддерживаетспускаясь вилкой, не уверен, что это хорошо работает сmultiprocessing.Process() но стоит попробовать.

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

 OliverUv28 мая 2014 г., 17:28
Следует отметить, что Winpdb является мультиплатформенным, бесплатным и свободным программным обеспечением.
 grep18 янв. 2011 г., 09:52
Большой! Winpdb хорошо работает с многопроцессорностью. Process ()
 Pat29 окт. 2016 г., 00:20
В течение 20 минут после прочтения и игры с winpdb я не смог найти способ просто запустить сеанс интерактивной отладки в существующем скрипте с помощью импорта, аimport pdb; pdb.set_trace(), Тем не менее, ответ ForkedPdb здесь работал как шарм!

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

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()
 memeplex05 авг. 2015 г., 01:15
Хороший трюк. Я предлагаю сохранить sys.stdin при запуске программы и использовать его в разветвленном процессе вместо открытия/dev/stdin, Я не знаю причину, но readline работает нормально тогда. Я буду исследовать немного позже.
 xamox28 мая 2015 г., 21:26
Спасибо, это сработало и для меня.
 memeplex05 авг. 2015 г., 02:48
Ну, я нашел более надежное решение, поддерживающее стандартную загрузку стандартного ввода при запуске. Я думаю, что readline всегда вызывается с этим, пожалуйста, прочитайте мой ответ.
 David Eads27 июн. 2014 г., 22:06
это потрясающе и помогло мне
 Ishan Srivastava06 мар. 2018 г., 19:00
возражаете немного объяснить, как и почему это работает?

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

Вот вступление автора, Вы можете использовать Dtrace для отладки чего угодно.

Вот ТАК сообщение на обучение DTrace.

Ваш ответ на вопрос