我有一个问题,gdb在一个系统上,我不能让gdb使用一个符号文件,以便在回溯中显示源文件和行号,但在一个旧的系统上,使用完全相同的命令,它可以正常工作。这是工作的旧系统是一个32位的Debian6,而它不工作的现代系统是一个64位的Debian10。
在这两种情况下,我都在同一个系统上构建、运行和运行gdb(因此系统之间没有交叉二进制文件或内核)
我可以用一个简单的玩具程序(test.c
)来重现这一点,该程序的设计目的是立即崩溃:
int main()
{
int *i=0;
*i=0;
return 0;
}
我编译它并将其拆分为一个剥离的可执行文件和一个符号文件,然后运行可执行文件:
gcc -g test.c -o test
objcopy --only-keep-debug test test.dbg
objcopy --strip-debug test
ulimit -c unlimited
./test
然后我在gdb中打开核心转储。在旧系统(32位,gdb 7.0.1-debian)上执行此操作时,我会看到没有任何符号的回溯,但一旦运行
symbol-file test.dbg
后,我就会看到回溯中的源文件和行信息(test.c:4
)(我没有包括一些早期的gdb输出,这些输出会使屏幕混乱,我认为不相关,如果需要,我可以将其放入其中)gdb -c core test
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483a4 in main ()
(gdb) symbol-file test.dbg
Reading symbols from /home/user/test.dbg...done.
(gdb) bt
#0 0x080483a4 in main () at test.c:4
(gdb) quit
在较新的机器(64位,gdb 8.2.1)上运行完全相同的序列,我得到以下结果
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055e5dda71135 in main ()
(gdb) symbol-file test.dbg
Load new symbol table from "test.dbg"? (y or n) y
Reading symbols from test.dbg...done.
(gdb) bt
#0 0x000055e5dda71135 in ?? ()
#1 0x000055e5dda71150 in ?? ()
#2 0x00007eff7035f09b in __libc_start_main (main=0x55e5dda71125, argc=1, argv=0x7fff46187ec8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff46187eb8)
at ../csu/libc-start.c:308
#3 0x000055e5dda7106a in ?? ()
#4 0x00007fff46187eb8 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007fff46188e8f in ?? ()
#8 0x0000000000000000 in ?? ()
加载符号文件不仅不会添加源和行,而且似乎会丢失第一帧中的main()。我还尝试使用
add-symbol-file
而不是symbol-file
,并在命令行中使用-s
选项包含符号文件,但没有更好的结果。我也试过把-s
放在-c
之前,就像我在网上推荐的那样,但这也没有帮助。编辑:以下请求的文本:
$ gcc -g test.c -o test
$ objcopy --only-keep-debug test test.dbg
$ ./test
Segmentation fault (core dumped)
$ gdb test.dbg core
GNU gdb (Debian 8.2.1-2+b1) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.dbg...done.
warning: core file may not match specified executable file.
[New LWP 26602]
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000056477c36d135 in ?? ()
(gdb) bt
#0 0x000056477c36d135 in ?? ()
#1 0x000056477c36d150 in ?? ()
#2 0x00007fa3a18a509b in __libc_start_main (main=0x56477c36d125, argc=1, argv=0x7ffd0b6aed38, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd0b6aed28)
at ../csu/libc-start.c:308
#3 0x000056477c36d06a in ?? ()
#4 0x00007ffd0b6aed28 in ?? ()
#5 0x000000000000001c in ?? ()
#6 0x0000000000000001 in ?? ()
#7 0x00007ffd0b6afe8d in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb)
最佳答案
在较新的机器(64位,gdb 8.2.1)上运行完全相同的序列,我得到以下结果
尝试用test
构建您的-fno-pie -no-pie
二进制文件。
您的工作示例具有非饼图地址(0x0804xxxx
)。您的非工作示例有一个饼图地址(0x000055....
)。debian决定将pie二进制文件设为默认值,这为系统增加了一点安全性。
可能发生的情况是,gdb在重新加载symbol-file
时丢弃了重新定位信息。
另外,您可以使用以下方法来避免整个问题:
gdb test.dbg core
这会让gdb从一开始就走上正轨。
p.p.s.一般来说,命名任何二进制
test
都是一个非常糟糕的主意,因为这可能会干扰shell对条件的求值(如果shell找到./test
而不是/bin/test
,并且没有内置的test
)。关于c - symbol-file命令可用于较旧的gdb,但不适用于较新的gdb,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58330923/