如何在不退出和丢失断点的情况下在 gdb 中重新加载重新编译的二进制文件?

新手上路,请多包涵

根据 这个优秀的指南,应该能够重新编译源文件并简单地使用 ‘r’ 让 gdb 开始调试新的、更改的二进制文件。

这似乎也暗示 在 gdb 手册 中,“如果自 GDB 上次读取其符号以来符号文件的修改时间发生了变化,GDB 丢弃其符号表,并再次读取它。”

我正在尝试在 Ubuntu 16.10 上调试一个简单的单个 .cpp 文件。通过 g++ -ggdb -std=c++11 foo.cpp 编译后,我可以像往常一样调试。

 GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu2) 7.11.90.20161005-git
[...]
(gdb) break main
Breakpoint 1 at 0x2754: file foo.cpp, line 204.
(gdb) r
Starting program: /home/code/foo

Breakpoint 1, main () at foo.cpp:204
(gdb) n
(gdb) k
Kill the program being debugged? (y or n) y

在这里,我对源文件稍作改动,然后重新编译。尝试再次运行文件时:

 (gdb) r
/home/code/foo' has changed; re-reading symbols.
Error in re-setting breakpoint 1: Cannot access memory at address 0x55555555674b
Starting program: /home/code/598
warning: Probes-based dynamic linker interface failed.
Reverting to original interface.

[Inferior 1 (process 20898) exited normally]

有没有办法在保持断点完整的同时成功重新加载二进制文件?

编辑: 这篇文章 有我正在寻找的答案。您使用 file binaryname 命令重新加载可执行文件。

 (gdb) file foo
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
A program is being debugged already.
Load new symbol table from "foo"? (y or n) y
Reading symbols from foo...done.
Error in re-setting breakpoint 1: Cannot access memory at address 0x274b
Error in re-setting breakpoint 2: Cannot access memory at address 0x274b

我们看到断点仍然存在,只是被禁用了:

 (gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep n   0x0000555555556754
        breakpoint already hit 1 time
2       breakpoint     keep n   0x000055555555677b

所以我们只是启用它们:

 (gdb) enable
(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000555555556754
        breakpoint already hit 1 time
2       breakpoint     keep y   0x000055555555677b
(gdb)

这行得通,但我很想听听是否有人对仅使用 run 是否确实有效有进一步的建议或意见。

原文由 user280937 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

断点和 PIE 的问题似乎已在 gdb 8.3.1 中得到修复 - 请参阅 https://www.gnu.org/software/gdb/news/ 和 PR 25011。

由于该问题是由与位置无关的可执行文件 (PIE) 引起的,因此使用 -no-pie 链接程序也应该可以解决这个问题。

让我想到这个问题的问题是符号的自动重新加载似乎在新的 gdb 中被破坏了,但似乎变化不在 gdb 中,而是 Linux 发行版默认在 gcc 中开始启用 PIE。与 -no-pie 链接也为我修复了符号重新加载。

原文由 olsner 发布,翻译遵循 CC BY-SA 4.0 许可协议

当我使用 gdb 5 时,重新编译后仅使用“运行”就足以重新加载符号。现在,使用 gdb 8.1,我需要在“运行”之前键入“可执行文件”,以强制 gdb 在重新编译后重新加载符号。

原文由 user61383 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题