gdb.execute блокирует все потоки в скриптах Python - PullRequest
0 голосов
/ 30 августа 2018

Я пишу GDB на Python 2.7.

Я просто пошагово делаю инструкции с gdb.execute("stepi"). Если отлаженная программа не работает и ожидает взаимодействия с пользователем, gdb.execute("stepi") не возвращается. Если есть такая ситуация, я хочу остановить сеанс отладки, не прерывая работу GDB.

Для этого я создаю поток, который убивает отлаженный процесс, если текущая инструкция выполнялась дольше, чем x секунд:

from ctypes import c_ulonglong, c_bool
from os import kill
from threading import Thread
from time import sleep
import signal

# We need mutable primitives in order to update them in the thread
it = c_ulonglong(0) # Instructions counter
program_exited = c_bool(False)
t = Thread(target=check_for_idle, args=(pid,it,program_exited))
t.start()

while not program_exited.value:
    gdb.execute("si") # Step instruction
    it.value += 1

# Threaded function that will kill the loaded program if it's idling
def check_for_idle(pid, it, program_exited):
    delta_max = 0.1 # Max delay between 2 instructions, seconds
    while not program_exited.value:
        it_prev = c_ulonglong(it.value) # Previous value of instructions counter
        sleep(delta_max)
        # If previous instruction lasted for more than 'delta_max', kill debugged process
        if (it_prev.value == it.value):
            # Process pid has been retrieved before
            kill(pid, signal.SIGTERM)       
            program_exited.value = True
    print("idle_process_end")

Однако, gdb.execute приостанавливает мой поток ... Есть ли другой способ убить отлаженный процесс, если он простаивает?

1 Ответ

0 голосов
/ 07 сентября 2018

Однако gdb.execute приостанавливает мою цепочку

Здесь происходит то, что gdb.execute не освобождает глобальную блокировку Python при вызове gdb. Таким образом, пока выполняется команда gdb, другие потоки Python застряли.

Это просто недосмотр в GDB. Я подал ошибку .

Есть ли другой способ убить отлаженный процесс, если он простаивает?

Есть еще одна техника, которую вы можете попробовать - я не уверен, что она будет работать. К сожалению, эта часть GDB не полностью реализована (в настоящее время); так что не стесняйтесь подавать отчеты об ошибках.

Основная идея - запускать команды gdb в главном потоке, но не из Python. Итак, попробуйте написать свой пошаговый цикл с помощью интерфейса командной строки gdb, например:

(gdb) while 1
> stepi
> end

Тогда ваша нить должна быть в состоянии kill уступать. Другой подход может заключаться в том, чтобы ваш поток вставлял команду gdb в основной цикл, используя gdb.post_event.

...