GDB 没有停止 python 脚本中的“中断”命令

Posted

技术标签:

【中文标题】GDB 没有停止 python 脚本中的“中断”命令【英文标题】:GDB not stopping with "interrupt" command from python script 【发布时间】:2017-12-12 21:28:57 【问题描述】:

我一直在为此扯头发。我搜索了互联网,似乎无法找到解决我的问题的方法。我正在尝试使用 python 中的 gdb 模块自动测试一些代码。除了停止在后台运行的进程外,我可以执行基本命令并且一切正常。目前我在断点后在后台继续我的程序:

gdb.execute("c&")

然后我与正在运行的程序进行交互,读取不同的常量值并从程序中获取响应。 接下来我需要获得一块内存,所以我运行这些命令:

gdb.execute("interrupt") #Pause execution gdb.execute("dump binary memory montiormem.bin 0x0 (&__etext + 4)") #dump memory to file

但是当我运行内存转储时,我收到一个错误,说在目标运行时无法运行命令,错误后运行中断命令并暂停目标,然后从 gdb 控制台窗口我可以运行内存转储。

我不久前发现了一个类似的问题,似乎没有答案here。

我正在使用python2.7。

我还发现这个链接似乎是issue,但没有迹象表明它是否在我的 gdb 构建中(这似乎不太可能)。

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,但发现如果您尝试从 python 编写所有内容,那么这里的其他答案都不起作用。我遇到的问题是,当我调用gdb.execute('continue') 时,任何其他 python 线程中的代码都不会执行。这似乎是因为gdb does not release the python GIL 而 continue 命令正在等待程序被中断。

我发现实际上对我有用的是:

def delayed_interrupt():
    time.sleep(1)
    gdb.execute('interrupt')
gdb.post_event(delayed_interrupt)
gdb.execute('continue')

【讨论】:

【参考方案2】:

我在编写一些自动化测试脚本时遇到了同样的问题。我注意到的是,“中断”命令在当前脚本退出之前不会停止应用程序。

不幸的是,这意味着您需要在任何时候造成中断时对脚本进行分段。

脚本 1:

gdb.execute('c&')
gdb.execute('interrupt')

脚本 2:

gdb.execute("dump binary memory montiormem.bin 0x0 (&__etext + 4)")

【讨论】:

【参考方案3】:

我使用多线程来解决这个问题:

def post(cmd):
    def _callable():
        print("exec " + cmd , flush=True)
        gdb.execute(cmd)

    print("schedule " + cmd , flush=True)
    gdb.post_event(_callable)

class ScriptThread (threading.Thread):
    def run (self):

        while True:
            post("echo hello\n")
            time.sleep(1)

x = ScriptThread()
x.start()

将此保存为“test_script.py”

使用脚本如下:

gdb
> source test_script.py

注意:您也可以通过管道传输“source test_script.py”,但需要保持管道打开。

一旦线程启动,GDB 将等待线程结束并处理您通过“post_event”函数发送给它的任何命令。甚至“打断”!

【讨论】:

【参考方案4】:

我遇到了同样的问题,从谷歌搜索可以看出这是 gdb 的当前限制:interrupt 在批处理模式下根本不起作用(使用--ex-x file 指定命令时,或在标准输入或从文件中获取),它在实际停止执行之前运行以下命令(插入延迟没有帮助)。基于@dwjbosman 的解决方案,这里有一个紧凑的版本,适合使用--ex 参数提供给gdb,例如:

python import threading, gdb
python threading.Timer(1.0, lambda: gdb.post_event(lambda: gdb.execute("interrupt"))).start()
cont
thread apply all bt full # or whatever you wanted to do

它会在 1 秒后安排中断并恢复程序,然后您可以在主脚本中暂停后做任何您想做的事情。

【讨论】:

以上是关于GDB 没有停止 python 脚本中的“中断”命令的主要内容,如果未能解决你的问题,请参考以下文章

在 GDB 中的第一条机器代码指令处停止

GDB 多线程调试:只停止断点的线程,其他线程任然执行; 或只运行某些线程 其他线程中断

脚本停止运行按钮

GDB:断点没有被命中

中断 gdb (llvm) 中的命名空间函数

覆盆子pi crontab和python中断