gdb.execute阻塞了python脚本中的所有线程

7

我正在使用Python 2.7编写GDB脚本。

我只是使用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个回答

4
然而,gdb.execute会暂停我的线程。
这里发生的情况是,在调用gdb时,gdb.execute没有释放Python的全局锁。因此,在gdb命令执行时,其他Python线程被卡住了。
这只是gdb中的一个疏忽。我已经为此提交了一个错误报告
还有一种技术可以尝试,如果被调试的进程处于空闲状态,你可以尝试另一种方法。不幸的是,gdb的这部分功能目前并不完善,所以请随时提交错误报告。
主要思路是在主线程上运行gdb命令,但不要从Python中运行。因此,尝试使用gdb CLI编写步进循环,可能像这样:
(gdb) while 1
> stepi
> end

然后你的线程应该能够 kill 进程。另一种方法是让你的线程使用 gdb.post_event 向主循环注入 gdb 命令。

感谢您的建议和提交错误报告。我的脚本旨在进行批量汇编处理以构建数据库,因此我无法使用CLI,因为脚本需要完全自动化。此外,我不能使用gdb.post_event,因为我需要按顺序将gdb.execute命令的输出检索到一个字符串中。 - Antoine C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接