【问题标题】:How to continue the exection after hitting breakpoints in gdb?在gdb中遇到断点后如何继续执行?
【发布时间】:2019-06-26 21:51:46
【问题描述】:

在 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


    【解决方案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 堆栈帧永远不会被破坏。

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

    【讨论】:

    • 非常感谢。向断点添加条件不是我想要的。正如您所提到的,我之前尝试增加最大堆栈大小,这对我来说也不是一个更好的解决方案。但是在我的情况下使用commands 效果很好。看来我之前误用了commands。虽然,我不知道如何在单个 gdb.execute() 调用中使用 commands
    猜你喜欢
    • 2017-10-11
    • 1970-01-01
    • 2022-08-02
    • 2022-11-25
    • 1970-01-01
    • 2010-12-03
    • 2018-03-15
    • 2020-12-30
    • 1970-01-01
    相关资源
    最近更新 更多