根据this excellent guide,我们应该能够重新编译源文件并简单地使用' r'让gdb开始调试新的,更改的二进制文件。
这似乎也隐含了in the gdb manual"如果自上次GDB读取符号后符号文件的修改时间发生了变化,GDB将丢弃其符号表,并再次读取它。&#34 ;
我正在尝试在Ubuntu 16.10上调试一个简单的单个.cpp文件。通过g++ -ggdb -std=c++11 589.cpp
进行编译后,我可以像往常一样进行调试。
GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu2) 7.11.90.20161005-git
[...]
(gdb) break main
Breakpoint 1 at 0x2754: file 589.cpp, line 204.
(gdb) r
Starting program: /home/code/589
Breakpoint 1, main () at 589.cpp:204
(gdb) n
(gdb) k
Kill the program being debugged? (y or n) y
在这里,我对源文件进行了一些小改动,然后重新编译。尝试再次运行该文件时:
(gdb) r
/home/code/589' 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]
有没有办法成功重新加载二进制文件,同时保持断点不变?
编辑:This post得到了我正在寻找的答案。使用file binaryname
命令重新加载可执行文件。
(gdb) file 589
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 "589"? (y or n) y
Reading symbols from 589...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
是否确实有效提供了进一步的建议或意见。
答案 0 :(得分:4)
当我使用gdb 5时,在重新编译后仅使用'run'就足以重新加载符号。现在,对于gdb 8.1,我需要在“运行”之前键入“文件可执行文件”,以强制gdb在重新编译后重新加载符号。
答案 1 :(得分: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
链接还可以为我修复符号重新加载。
答案 2 :(得分:0)
这是我在gdb 8.3中使用的脚本(略微适合此答案):
define make
shell make
python gdb.execute("file " + gdb.current_progspace().filename)
# clear cache
directory
end
您需要使用Python的gdb。
请注意directory
命令,该命令将更新源文件缓存。