Есть ли способ остановить фоновый процесс при входе в pdb?

Итак, у меня есть такой код:

class ProgressProc(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)

    def run(self):
        while True:
            markProgress()
            time.sleep(10)

progressProc = ProgressProc()
progressProc.start()
doSomething()
progressProc.terminate()

Проблема в том, что если я делаю pdb.set_trace() внутри функции doSomething(), процесс ProgressProc продолжает работать. Он продолжает выводить данные на консоль, пока активно приглашение pdb. Я хотел бы, чтобы ProgressProc каким-то образом проверял, приостановлен ли основной поток (на самом деле, любой другой поток) в pdb, и тогда я могу пропустить markProgress().

Есть sys.gettrace(), но он работает только для потока, который выполнил pdb.set_trace(), и я не могу понять, как вызвать его в другом потоке, отличном от того, в котором я нахожусь. Что еще я могу сделать ? Есть ли какие-то сигналы, которые я могу поймать? Я мог бы заменить мой основной метод pdb.set_trace, чтобы сначала вызвать некоторый multiprocessing.Event. Есть ли более чистый способ?

ETA: это также для команды python gdb.


person Jason Raff    schedule 26.04.2019    source источник


Ответы (1)


Отладка с несколькими потоками или процессами в настоящее время невозможна с Pdb. Тем не менее, я надеюсь, что следующее может помочь вам.

Это решение приостанавливает основной поток с Pdb, а затем отправляет сигнал другому процессу, где запущен Rpdb. .

Откройте сокет в run. Обязательно установите время ожидания равным 0. Когда процесс получит сигнал, запустите Rpdb с rpdb.set_trace().

signal = 'break'
address = ('localhost', 6000)

def run(self):
    listener = Listener(address=address)
    listener._listener._socket.settimeout(0)
    recvd = False
    while True:
        markProgress()
        if not recvd:
            try:
                conn = listener.accept()
                msg = conn.recv()
                if msg == signal:
                    recvd = True
                    rpdb.set_trace()
            except:
                pass
        time.sleep(2)

Сделайте set_trace() внутри doSomething(), как и раньше, затем подключитесь к сокету и отправьте сигнал.

def doSomething():
    pdb.set_trace()
    conn = Client(address)
    conn.send(signal)
    conn.close()
    for x in range(100):
        time.sleep(1)
        sys.__stdout__.write("doSomething: " + str(x) + "\n")

Теперь вы можете запустить свою программу. После отправки сигнала вы должны получить вывод pdb is running on 127.0.0.1:4444. Теперь откройте второй терминал и подключитесь к Rpdb с помощью nc localhost 4444.

  • Это работает только с двумя процессами/потоками. Если вы хотите работать с большим количеством, вы можете попробовать запустить Rpdb с другим портом для каждого процесса, например: rpdb.Rpdb(port=12345)
  • Возможно, вам придется изменить все ваши print на sys.__stdout__.write, потому что Rpdb изменяет stdout.
person Nbfour    schedule 08.05.2019