在gdb中调试简单程序时,我想在遇到断点后自动继续执行。据我所知,有两种方法可以实现它:
1)使用hook-stop
。
define hook-stop
continue
end
但是似乎hook-stop
仅触发了一次。下次遇到另一个断点时,执行仍会停止。
2)使用gdb.events.stop.connect()
。
def handle_stop_event(event):
if isinstance(event, gdb.BreakpointEvent):
gdb.execute('continue')
gdb.events.stop.connect(handle_stop_event)
此方法效果很好。但是,如果命中了太多的断点,则会发生错误"Fatal Python error: Cannot recover from stack overflow."
。
看来是因为递归调用。我想知道为什么gdb.execute('continue')
会导致此问题。
我在网上搜索,但仍然找不到解决方案。
PS:Ubuntu 16.04上的gdb版本7.11.1
任何建议将不胜感激!预先感谢。
答案 0 :(得分:1)
似乎continue
中的hook-stop
无法正常工作。您看到我昨天发布的this question吗?
我认为,最好的方法是在python中编写便利函数并设置条件断点。或使用commands
-请参阅GDB用户手册的“断点命令列表”部分。
这里是怎么做的(在手册中也有介绍)。
python模块:
import gdb
class should_skip_f(gdb.Function):
def __init__ (self):
super (should_skip_f, self).__init__("should_skip")
def invoke(self):
return True # Your condition here
should_skip_f()
(gdb) b <your target> if !$should_skip()
或使用
将条件添加到现有断点(gdb) condition <BNUM> !$should_skip()
唯一的缺点是您必须为每个断点分别设置条件,但这是可编写脚本的。另外,我认为commands
语法允许您立即将命令添加到断点列表中。
'commands [LIST...]'
'... COMMAND-LIST ...'
'end'
Specify a list of commands for the given breakpoints. The commands
themselves appear on the following lines. Type a line containing
just 'end' to terminate the commands.
关于递归-是的,这是调试器脚本的糟糕“设计”(如果应该谈论一次性的东西的设计)。如果您像这样扩展python脚本,则可以检查在那里发生了什么
import inspect
...
def handle_stop_event(event):
...
print(len(inspect.stack())) # Or you can print the frames themselves...
Python解释器不知道执行不会从gdb.execute("continue")
返回,因此用于调用此函数的Python堆栈框架永远不会被破坏。
您可以增加解释器的最大堆栈大小,但是就像我说的那样,此脚本似乎不是我的最佳解决方案。