好的,info break 列出了断点,但其格式不适合使用 --command as in this question 重复使用它们。 GDB 是否有一种方法可以将它们转储到可以再次输入的文件中?有时在调试会话中,需要在建立一组断点后重新启动 GDB 以进行测试。
.gdbinit 文件与 --command 有相同的问题。 info break 命令没有列出命令,而是一个供人类使用的表格。
详细地说,这里是信息中断的一个示例:
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x08048517 <foo::bar(void)+7>
从 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>
从文件中恢复保存的断点。
这个答案已经过时了。 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>
编写将其转换为对 .gdbinit
或 --command
文件有用的格式的 AWK 脚本很容易。或者您甚至可以让脚本向 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
save breakpoints
命令。
将 GDB 命令和断点放在 .gdbinit file 中,就像在 gdb>
提示符下键入它们一样,GDB 将在启动时自动加载和运行它们。这是一个按目录的文件,因此您可以为不同的项目使用不同的文件。
anon's extension 到 Johannes' 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
保存的断点。
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 成功测试了它。
将以下内容放入 ~/.gdbinit 以将 bsave 和 brestore 定义为 GDB 命令以保存和恢复断点。
define bsave
save breakpoints ~/.breakpoints
end
define brestore
source ~/.breakpoints
end
我发现对先前答案的以下补充对于将断点保存/加载到特定文件很有用。
保存断点: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
警告:当前输出协议不支持重定向
尝试在 TUI 模式下启用日志记录时,我也在 GDB 中收到此错误/警告。但是,日志记录似乎在“非 TUI”模式下工作。所以每当我想记录一些东西时,我都会离开 TUI 模式。 (使用 Ctrl + X、Ctrl + A 来回切换到 TUI 模式)。
这是我的工作方式:
启动 GDB(在正常模式下)启用日志记录:设置日志记录 - 现在它不应该抱怨了。来回切换到 TUI 模式并在我想要记录某些内容(如巨大的回溯转储)时执行 GDB 操作 - 切换到正常模式
问题是设置断点是上下文相关的。如果你有两个名为 foo 的静态函数怎么办?
如果您已经在调试定义 foo 的模块之一,那么 GDB 将假定您的意思是那个。但是,如果您只是将“break foo”转储到一个文件中,然后在启动时读取该文件,则不清楚您指的是哪个函数 foo。
还有其他想法吗?我有
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
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
set breakpoint pending on
break g_log if log_level==G_LOG_LEVEL_CRITICAL
),那么至少 gdb 7.8.1 将停止解析进一步的命令。如果您有应针对该断点执行的其他命令,请将commands
行放在condition
行之前。