我试图使用GDB来解决我正在写的代码中的段错误.使用该backtrace
命令时,GDB不显示行号或函数名.这是一个简短的示例程序,说明了我的问题:
void segfault(int *b) { // This causes a segfault on CentOS7 Intel 64-bit b[-1] = 5; } void main() { int a[10]; segfault(a); }
但是当我编译时
gcc -ggdb -O0 test.c -o segfaulttest
并且用gdb segfaulttest
它来运行它,当我使用gdb的backtrace命令时,我没有得到任何行号或函数名.我希望它列出main()
并segfault()
在跟踪中.
样本输出
Reading symbols from /home/user/test/segfaulttest...done. (gdb) run Starting program: /home/user/test/segfaulttest Program received signal SIGSEGV, Segmentation fault. 0x000000050040051c in ?? () (gdb) bt #0 0x000000050040051c in ?? () #1 0x0000000000000000 in ?? () (gdb)
我正在使用:
CentOS 7(64位)
GCC: gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
GDB是 gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
(旁白:我修复了我的代码中的实际错误,我只是不明白为什么gdb backtrace没有向我显示更多信息).
您已经销毁了堆栈中包含gdb需要知道程序所在位置的信息的部分.
0x000000050040051c in ?? () ^^^^^^^^
这是你的代码编写的数字5,一个4字节的int.
当main()启动时,返回地址存储在堆栈中.返回地址是main()完成后返回的位置.该位置是一个函数,它是运行时调用main()的一部分.
由于您的代码会破坏/覆盖该返回地址,因此执行会尝试跳回某个不存在的地址,从而导致崩溃.
该地址0x000000050040051c现在是程序计数器寄存器,当SIGSEGV信号传送到您的进程时,它会被存储.gdb检查此信息,试图找出与地址0x000000050040051c匹配的代码所在的位置 - 这不存在.