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 脚本中的“中断”命令的主要内容,如果未能解决你的问题,请参考以下文章