让GDB保存断点列表


129

好的,info break列出了断点,但不能采用可以使用--command重用它们的格式,如本问题所述。GDB是否有一种方法可以将它们转储到可以再次输入的文件中?有时在调试会话中,有必要在建立一组用于测试的断点之后重新启动GDB。

.gdbinit文件具有与--command相同的问题。该信息休息命令不会列出命令,而是供人食用的表。

详细说明,这是info break的示例:

(gdb)信息中断
编号类型显示Enb地址什么
1个断点保持y 0x08048517 <foo :: bar(void)+7>

Answers:


204

从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 <filename>从文件还原保存的断点。


2
如果它们来自共享库负载怎么办?默认情况下,它会回答N……Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly 2014年

2
@bjackfly使用方法set breakpoint pending on,如如何在gdb脚本gdb中
aculich 2014年

请注意,当您遇到无法在启动(break g_log if log_level==G_LOG_LEVEL_CRITICAL)时解决的断点条件时,则至少gdb 7.8.1将停止解析其他命令。如果您需要为该断点执行其他命令,请将该commands行放在该行之前condition
Lekensteyn 2014年

@Andry我将您的编辑回滚到我的原始blockquote,因为文本是文档中的逐字引用...如果不是我自己的话,我将同意您的编辑。
aculich

@aculich:我明白了。无论如何,我建议使用引号样式而不是代码样式。
安德里(Andry)2015年

26

这个答案已经过时了。GDB现在支持直接保存。看到这个答案

您可以使用日志记录:

(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文件有用的格式很容易。或者甚至可以使脚本--eval-command向GDB命令行发出单独的。

将此小宏添加到.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

使用剪切和粘贴同样容易,但是脚本方法似乎是一种方法。
Casualcoder

1
我不认为剪切和粘贴比只写一次脚本然后再一次使用它容易得多:)毕竟,这就是您首先问这个问题的原因,我认为:)
Johannes Schaub-litb

嗯,我的意思是使用剪切粘贴而不是日志记录方法。到目前为止,脚本是肯定的。
Casualcoder

哇!gdb失败!我每天都在使用它,并且喜欢它的许多功能。但是缺乏仅仅是愚蠢的。
deft_code

4
该答案现在已有2年以上的历史,因此,如果您使用的是更高版本的gdb,它可能已过时。从gdb 7.2开始,您现在可以使用该save breakpoints命令。
aculich

11

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


1
这实际上无法正常工作,我收到“警告:save-tracepoints:没有要保存的tracepoint”。尽管设置了断点,但仍使用gdb
6.8。– Casualcoder

这对我有用。GDB需要在$ HOME / .gdbinit中存在一个全局.gdbinit,其内容为'add-auto-load-safe-safe-path /home/johnny/src/.gdbinit',因此src /文件夹也具有一个单独的.gdbinit
Trueadjustr

9

的扩展,不久的扩展约翰内斯的回答

.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
George Godik 2011年

6

约翰内斯答案的扩展:您可以将的输出自动重新格式化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成功地对其进行了测试。


1
谢谢您的这段代码!效果很好。已在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)。
食虫性的2010年


3

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

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

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

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

这是我的工作方式:

  1. 启动GDB(在正常模式下)
  2. 启用日志记录:set logging on-现在不应该抱怨。
  3. 来回切换至TUI模式并执行GDB任务
  4. 每当我想记录某些内容(例如巨大的回溯转储)时,请切换至正常模式

哦,而且,如果您喜欢使用“屏幕”(就像我一样),将会有点混乱,因为它使用相同的热键。
Magnux

1

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

  • 保存断点:bsave {文件名}
  • 加载断点:bload {文件名}

与上一个答案一样,将以下代码添加到文件〜/ .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

0

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

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


0

还有其他想法吗?我有

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.