【问题标题】:Getting GDB to save a list of breakpoints让 GDB 保存断点列表
【发布时间】:2010-10-04 19:53:06
【问题描述】:

好的,info break 列出了断点,但其格式不适合使用 --command as in this question 重复使用它们。 GDB 是否有一种方法可以将它们转储到可以再次输入的文件中?有时在调试会话中,需要在建立一组断点后重新启动 GDB 进行测试。

.gdbinit 文件的问题与 --command 相同。 info break 命令并没有列出命令,而是一个供人类使用的表格。

为了详细说明,这里是 info break 中的一个示例:

(gdb) 信息中断 Num 类型 Disp Enb 地址 什么 1个断点保持y 0x08048517 <:bar>

【问题讨论】:

    标签: c++ c debugging gdb breakpoints


    【解决方案1】:

    从 GDB 7.2 (2011-08-23) 开始,您现在可以使用 save breakpoints 命令。

    save breakpoints <filename>
      Save all current breakpoint definitions to a file suitable for use
      in a later debugging session.  To read the saved breakpoint
      definitions, use the `source' command.
    

    使用source &lt;filename&gt;从文件中恢复保存的断点。

    【讨论】:

    • 如果它们来自共享库负载怎么办?它默认回答 N 似乎...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
    • 请注意,当您有一个在启动时无法解析的断点条件 (break g_log if log_level==G_LOG_LEVEL_CRITICAL),那么至少 gdb 7.8.1 将停止解析进一步的命令。如果您有其他命令需要针对该断点执行,请将commands 行放在condition 行之前。
    • @Andry 我将您的编辑回滚到我原来的块引用,因为该文本是文档中的逐字引用...如果是我自己的话,我会同意您的编辑。
    • @aculich:我明白了。在任何情况下,我都建议使用引用样式而不是代码样式。
    【解决方案2】:

    这个答案已经过时了。 GDB 现在支持直接保存。见this answer

    您可以使用日志记录:

    (gdb) b main
    Breakpoint 1 at 0x8049329
    (gdb) info break
    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   0x08049329 <main+16>
    (gdb) set logging file breaks.txt
    (gdb) set logging on
    Copying output to breaks.txt.
    (gdb) info break
    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   0x08049329 <main+16>
    (gdb) q
    

    breaks.txt 文件现在包含:

    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   0x08049329 <main+16>
    

    编写一个 AWK 脚本将其转换为对.gdbinit--command 文件有用的格式很容易。或者您甚至可以让脚本向 GDB 命令行发出单独的 --eval-command...

    将这个小宏添加到.gdbinit 将帮助您做到这一点:

    # Call with dump_breaks file.txt
    define dump_breaks
        set logging file $arg0
        set logging redirect on
        set logging on
        info breakpoints
        set logging off
        set logging redirect off
    end
    

    【讨论】:

    • 可以很容易地使用剪切和粘贴,但脚本方法似乎是要走的路。
    • 我不认为剪切和粘贴比只编写一次脚本,然后每次都使用它更容易:) 毕竟,这就是你第一次问这个问题的原因地方,我想:)
    • 嗯,我的意思是使用剪切和粘贴而不是记录方法。到目前为止,脚本是肯定的。
    • 哇! gdb 失败!我每天都使用它,并且喜欢它的许多功能。但缺乏是愚蠢的。
    • 这个答案现在已经超过 2 年了,所以如果你使用的是新版本的 gdb,它可能已经过时了。从 gdb 7.2 开始,您现在可以使用 save breakpoints 命令。
    【解决方案3】:

    将您的 GDB 命令和断点放在 .gdbinit file 中,就像您在 gdb&gt; 提示符下键入它们一样,GDB 将在启动时自动加载并运行它们。这是每个目录的文件,因此您可以为不同的项目使用不同的文件。

    【讨论】:

    • 这实际上无法正常工作,我收到“警告:保存跟踪点:没有要保存的跟踪点。”这尽管设置了断点。使用 gdb 6.8。
    • 这对我有用。 GDB 需要在您的 $HOME/.gdbinit 中存在一个全局 .gdbinit,其内容为“add-auto-load-safe-path /home/johnny/src/.gdbinit”,因此 src/ 文件夹也有一个单独的 .gdbinit
    【解决方案4】:

    anon's extensionJohannes' answer 的扩展:

    .gdbinit:
    
    define bsave
        shell rm -f brestore.txt
        set logging file brestore.txt
        set logging on
        info break
        set logging off
        # Reformat on-the-fly to a valid GDB command file
        shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
    end
    document bsave
      store actual breakpoints
    end
    
    define brestore
      source brestore.gdb
    end
    document brestore
      restore breakpoints saved by bsave
    end
    

    使用brestore,您可以恢复使用bsave 保存的断点。

    【讨论】:

    • 这是一个更好的正则表达式: perl -ne "print \"break \$1 \n\" if /at\s(.*:\d+)/" brestore.txt
    【解决方案5】:

    扩展至the answer from Johannes:您可以自动将info break 的输出重新格式化为有效的GDB 命令文件:

    .gdbinit:
    
    define bsave
       shell rm -f brestore.txt
       set logging file brestore.txt
       set logging on
       info break
       set logging off
       # Reformat on-the-fly to a valid gdb command file
       shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
    end
    document bsave
      store actual breakpoints
    end
    

    之后您在brestore.gdb 中有一个有效的命令文件。

    当应用程序使用 -g 编译时,这对我有用。

    我还在Ubuntu 9.10 (Karmic Koala) 上使用 GDB v6.8 成功测试了它。

    【讨论】:

    • 谢谢你的这个sn-p!效果很好。在 CarbonEmacs 中使用 GNU gdb 6.3.50-20050815(Apple 版本 gdb-966)在 Mac OS 10.5.8 上成功测试 GNU Emacs 22.3.1(i386-apple-darwin9.6.0,Carbon 版本 1.6.0)。
    【解决方案6】:

    也许是这样的:

    save breakpoints [filename]

    【讨论】:

    【解决方案7】:

    将以下内容放入~/.gdbinit 以将bsavebrestore 定义为GDB 命令以保存和恢复断点。

    define bsave
        save breakpoints ~/.breakpoints
    end
    
    define brestore
       source ~/.breakpoints
    end
    

    【讨论】:

      【解决方案8】:

      我发现以下对先前答案的补充对于将断点保存/加载到特定文件很有用。

      • 保存断点:bsave {filename}
      • 加载断点:bload {filename}

      和上一个答案一样,将以下代码添加到文件~/.gdbinit

      # Save breakpoints to a file
      define bsave
          if $argc != 1
              help bsave
          else
          save breakpoints $arg0
          end
      end
      document bsave
      Saves all current defined breakpoints to the defined file in the PWD
      Usage: bsave <filename>
      end
      
      # Loads breakpoints from a file
      define bload
          if $argc != 1
              help bload
          else
              source $arg0
          end
      end
      document bload
      Loads all breakpoints from the defined file in the PWD
      Usage: bload <filename>
      end
      

      【讨论】:

        【解决方案9】:

        警告:当前输出协议不会 不支持重定向

        当我尝试在TUI 模式下启用日志记录时,我也会在 GDB 中收到此错误/警告。但是,日志记录似乎在“非 TUI”模式下工作。所以每当我想记录一些东西时,我都会离开 TUI 模式。 (使用 Ctrl + XCtrl + A 来回切换到 TUI 模式)。

        这是我的工作方式:

        1. 启动 GDB(在正常模式下)
        2. 启用日志记录:set logging on - 现在它不应该抱怨了。
        3. 来回切换到 TUI 模式并执行 GDB 操作
        4. 每当我想记录一些东西时(比如一个巨大的回溯转储) - 切换到正常模式

        【讨论】:

        • 哦,如果你喜欢使用“屏幕”(就像我一样),它会有点乱,因为它使用相同的热键。
        【解决方案10】:

        问题在于设置断点是上下文相关的。 如果你有两个名为 foo 的静态函数怎么办?

        如果您已经在调试定义 foo 的模块之一,那么 GDB 会假设您的意思是那个。但如果你只是将“break foo”转储到一个文件中,然后在启动时读取该文件,则不清楚你指的是哪个函数foo

        【讨论】:

          【解决方案11】:

          还有其他想法吗?我有

          warning: Current output protocol does not support redirection
          

          之后

          set logging on
          

          编辑:

          我知道问题是“如何保存断点列表”,但是我刚刚发现,使用 GDB,我们可以简单地设置“保存在文件中”的断点

          gdb> source breakpoints.txt
          

          breakpoints.txt 是这样的文件:

          break main.cpp:25
          break engine.cpp:465
          break wheel.cpp:57
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-17
            • 2013-04-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-11
            • 2010-12-03
            相关资源
            最近更新 更多