c++ 如何在gdb中重新加载重新编译的二进制文件而不退出并丢失断点?

6pp0gazn  于 2023-05-30  发布在  其他
关注(0)|答案(3)|浏览(213)

根据这个优秀的指南,应该能够重新编译源文件,并简单地使用'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]

有没有一种方法可以成功地重新加载二进制文件,同时保持断点不变?
编辑:This post有了我想要的答案。使用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是否真的可行有进一步的建议或意见。

n9vozmp4

n9vozmp41#

当我使用gdb 5时,在重新编译后只使用run就足以重新加载符号。现在,在gdb 8.1中,我需要在run之前输入file /path/to/executable,以强制gdb在重新编译后重新加载符号。

oyt4ldly

oyt4ldly2#

下面是我在gdb 8.3中使用的一个脚本(稍微适应了这个答案):

define make
    shell make
    python gdb.execute("file " + gdb.current_progspace().filename)
    # clear cache
    directory
end

你需要有gdb w/Python。请注意directory命令用于更新源文件缓存。

bz4sfanl

bz4sfanl3#

在gdb 8.3.1中似乎已经修复了断点和PIE的问题-参见https://www.gnu.org/software/gdb/news/和PR 25011。
由于该问题是由位置无关可执行文件(PIE)引起的,因此使用-no-pie重新链接程序也应该可以解决该问题。
让我想到这个问题的问题是,自动重新加载符号似乎在新的gdb中被破坏了,但似乎变化不是在gdb中,而是Linux发行版开始在gcc中默认启用PIE。与-no-pie链接也为我修复了符号重载。

相关问题