首页 > 解决方案 > 在gdb中遇到断点后如何继续执行?

问题描述

在 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

任何建议将不胜感激!提前致谢。

标签: gdb

解决方案


看来,continue内部hook-stop工作不正常。你看到我昨天发的这个问题了吗?

我认为,这里最好的方法是在 python 中编写一个方便的函数并设置一个条件断点。或者使用commands——参见 GDB 用户手册的“断点命令列表”部分。

这是如何做的(也在手册中描述)。

蟒蛇模块:

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 堆栈帧永远不会被破坏。

您可以增加解释器的最大堆栈大小,但就像我说的,这个脚本对我来说似乎不是最好的解决方案。


推荐阅读