首页 > 解决方案 > 符号文件命令适用于较旧的 gdb,但不适用于较新的 gdb

问题描述

我有一个问题,一个系统上的 gdb 我无法让 gdb 使用符号文件来在回溯中显示源文件和行号,但是在具有完全相同命令的旧系统上它可以正常工作。可以正常工作的旧系统是 32 位 Debian 6,而不能正常工作的现代系统是 64 位 Debian 10。

在这两种情况下,我都在同一个系统上构建、运行和运行 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(I'我没有包含一些早期的 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)

标签: clinuxdebugginggdb

解决方案


在较新的机器(64 位,gdb 8.2.1)上运行完全相同的序列,我得到以下信息

尝试test使用-fno-pie -no-pie.

您的工作示例有一个非 PIE 地址 ( 0x0804xxxx)。您的非工作示例有一个 PIE 地址 ( 0x000055....)。Debian 决定将 PIE 二进制文件设为默认值,这为系统增加了一点安全性。

可能发生的情况是 GDB 在重新加载symbol-file.

PS您可以使用以下方法避免整个问题:

gdb test.dbg core

这将从一开始就在右脚启动 GDB。

PPS 命名任何二进制文件通常是一个非常糟糕的主意test,因为这可能会干扰 shell 对条件的评估(如果 shell 找到./test而不是/bin/test,并且没有test内置的)。


推荐阅读