为什么GDB不显示行号或函数名称?

时间:2016-11-07 21:51:40

标签: gcc gdb

我正在尝试使用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) 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没有向我显示更多信息)。

1 个答案:

答案 0 :(得分:5)

您已经销毁了包含gdb需要知道程序所在位置信息的堆栈部分。

0x000000050040051c in ?? ()
  ^^^^^^^^

这是你的代码编写的数字5,一个4字节的int。

当main()启动时,返回地址存储在堆栈中。退货地址 是main()完成后会回到的地方。该位置是一个函数,它是运行时调用main()的一部分。

由于代码损坏/覆盖了返回地址,执行会尝试跳回某个不存在的地址,从而导致崩溃。

该地址0x000000050040051c现在是程序计数器寄存器,当SIGSEGV信号传送到您的进程时,它会被存储。 gdb检查此信息,试图找出与地址0x000000050040051c匹配的代码所在的位置 - 这不存在。