C 符号文件命令用于旧gdb,但不用于新gdb
我有一个问题,gdb在一个系统上,我不能让gdb使用一个符号文件,以便在回溯中显示源文件和行号,但在一个使用完全相同命令的旧系统上,它可以正常工作。它运行的旧系统是32位Debian 6,而不工作的现代系统是64位Debian 10 在这两种情况下,我都在同一个系统上构建、运行和运行了gdb(因此系统之间没有交叉的二进制文件或内核) 我可以用一个简单的玩具程序(C 符号文件命令用于旧gdb,但不用于新gdb,c,linux,debugging,gdb,C,Linux,Debugging,Gdb,我有一个问题,gdb在一个系统上,我不能让gdb使用一个符号文件,以便在回溯中显示源文件和行号,但在一个使用完全相同命令的旧系统上,它可以正常工作。它运行的旧系统是32位Debian 6,而不工作的现代系统是64位Debian 10 在这两种情况下,我都在同一个系统上构建、运行和运行了gdb(因此系统之间没有交叉的二进制文件或内核) 我可以用一个简单的玩具程序(test.c)来重现这一点,该程序设计为立即崩溃: int main() { int *i=0; *i=0; r
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输出,这些输出会使屏幕变得杂乱无章,我认为这与此无关,如果需要的话,我可以把它放进去)
在一台较新的机器(64位,GDB8.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 ?? ()
在一台较新的机器(64位,GDB8.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 ?? ()
尝试使用-fno pie-no pie
构建您的测试
二进制文件
您的工作示例有一个非饼图地址(0x0804xxx
)。您的非工作示例有一个饼图地址(0x000055..
)。Debian决定将饼图二进制文件设为默认值,这为系统增加了一点安全性
可能发生的情况是,GDB在重新加载符号文件时会丢弃重新定位信息
另外,您可以使用以下方法避免整个问题:
gdb test.dbg core
这将从一开始就用右脚启动GDB
p.p.S.通常,命名任何二进制test
是一个非常糟糕的主意,因为这可能会干扰shell对条件的求值(如果shell找到/test
而不是/bin/test
,并且没有内置的test
).谢谢。禁用PIE确实解决了问题,尽管启用了PIE,您推荐的替代gdb命令行:“gdb test.dbg core”没有什么区别。也许objcopy--只保留调试会丢失PIE工作所需的一些信息,尽管我在搜索Google时还没有找到任何相关信息。@bdk“启用PIE后,您推荐的另一种gdb命令行:‘gdb test.dbg core’不会有什么不同”——我不相信您。我只是尝试了一下,效果很好(显示了源代码和所有内容)。是否提供成绩单?我编辑了本期以添加额外的成绩单。请告诉我我做错了什么。感谢您在这方面的帮助。@bdk您使用的objcopy
的版本是什么?现在我相信您了。我想binutils中有一个bug(我找不到)这就是原因。我使用的是binutils-2.31.1objcopy——版本报告“GNU objcopy(GNU binutils for Debian)2.31.1”,所以看起来是一样的。我看到2.32在GNU的网站上可用,我将看看我是否可以在我的系统上编译它,以及它是否有区别。
gdb test.dbg core