c - 符号文件命令适用于较旧的 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)
解决方案
在较新的机器(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
内置的)。
推荐阅读
- java - 试图将函数作为用户输入但不工作,不接受 String to Double
- c# - Xamarin 不断出现多个不同的错误
- java - 重新部署到 WebLogic 12.2.1 时需要重新启动托管服务器的 JPA 2.1 应用程序
- python - 寻找与 if 语句相同的功能,但速度更快
- java - 重复键值违反主键的唯一约束
- linux - 使用安装在 Linux 中自定义位置的 Protobuf 和 CMake?
- javascript - 验证二维数组每行长度相同的最快/最优雅的方法?
- python - 如何使用 setup.py sdist 排除 git 未跟踪的文件
- c# - 优化具有多个条件的嵌套 where 子句的最佳方法是什么?
- octave - 如何在使用“lsqnonlin”函数时修复 Octave 中的“fields2cell”错误