【问题标题】:GDB says "no symbol table," but nm shows file has debug symbolsGDB 说“没有符号表”,但 nm 显示文件有调试符号
【发布时间】:2013-10-07 16:24:58
【问题描述】:

我正在尝试使用 GDB 调试一个简单的 C 项目,但无论我如何编译,GDB 似乎都找不到该程序的调试符号。

当我将程序加载到 GDB 中时,它声称已成功读取符号,因为它会打印

Reading symbols from /home/edward/<executable>...done.

但是,当我运行程序时,由于分段错误而中断,然后键入 info locals,它会显示

No symbol table info available.

另外,bt 显示执行在我编写的函数(不是系统或库调用)内停止,但没有行号信息,只有原始内存地址。

为什么 GDB 不能找到或使用它之前成功读取的符号?我在正在运行的二进制文件上运行了nmobjdump,它们都显示了.debug_info.debug_line 等部分,因此该文件实际上包含调试符号。

我通常使用设置以下标志的 Makefile 进行编译:

CFLAGS = -mno-red-zone -fno-omit-frame-pointer -ggdb -O0 -I. -Wdeclaration-after-statement -Wall

当 make 调用 gcc 时,我可以看到正在使用它。但是,我尝试更改为仅-g,并通过在一个简单的测试文件上调用gcc -g -O0 手动编译,结果仍然相同:二进制文件包含调试符号,GDB 读取它们,但调用任何GDB 命令导致调试信息不​​可用的消息。

更新

我运行的是 Ubuntu 12.04,我的 GDB 版本是 7.4,我的 GCC 版本是 4.8.1。

如果我在 GDB 中 set complaints 10000 然后加载文件,它会打印以下投诉:

Reading symbols from /home/edward/<snip>/minithread...
DW_AT_low_pc 0x400690 is not < DW_AT_high_pc 0x33 for DIE at 0x205 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x4006c3 is not < DW_AT_high_pc 0xa9 for DIE at 0x235 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x40076c is not < DW_AT_high_pc 0xad for DIE at 0x287 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400819 is not < DW_AT_high_pc 0xe7 for DIE at 0x2d3 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400900 is not < DW_AT_high_pc 0x4f for DIE at 0x345 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x40094f is not < DW_AT_high_pc 0x55 for DIE at 0x39d [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x4009a4 is not < DW_AT_high_pc 0x38 for DIE at 0x3e7 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x4009dc is not < DW_AT_high_pc 0x43 for DIE at 0x433 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400a20 is not < DW_AT_high_pc 0x2e for DIE at 0x56c [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400a4e is not < DW_AT_high_pc 0x2e for DIE at 0x5aa [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400a7c is not < DW_AT_high_pc 0x29 for DIE at 0x5d4 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400aa5 is not < DW_AT_high_pc 0x49 for DIE at 0x620 [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400aee is not < DW_AT_high_pc 0xca for DIE at 0x66c [in module /home/edward/<snip>/minithread]
...DW_AT_low_pc 0x400bb8 is not < DW_AT_high_pc 0x7bb for DIE at 0x6f0 [in module /home/edward/<snip>/minithread]...done.

这些错误是问题的原因吗?他们是否意味着我的 GDB 是“错误”版本?

【问题讨论】:

  • gcc -g 为您提供符号信息。毫无疑问。您能否发布您的测试文件或我们可以编译的测试文件的某些部分。您是否尝试过在 p 选项的帮助下打印任何符号
  • 一个开始的地方是运行普通的“gdb”,然后“设置投诉 10000”,然后是“file .../myexecutable”。如果在 DWARF 中发现奇怪的东西,这将使 DWARF 读者抱怨。你也没有提到你使用的是什么版本的 GCC 或 gdb。有时更新的 gcc 需要更新的 gdb。

标签: c debugging gcc gdb


【解决方案1】:

gcc 4.8.1 生成 gdb 7.4 无法理解的 dwarf4 调试信息。您需要安装 gdb 7.6

【讨论】:

  • 我得到了 gdb 7.11 并且遇到了同样的问题。
  • gcc 4.8.5 和 gdb 7.6.1 有同样的问题
  • gcc 4.9.1 和 gdb 7.2-90.el6 有同样的问题
【解决方案2】:

除了 Chris Dodd 的回答之外,您还可以使用 gcc -gdwarf-3 编译您的代码,它使用 dwarf3 调试信息进行编译。哪个与您的 GDB 版本兼容。

【讨论】:

  • 这更好,因为不能总是升级 gdb 版本
  • 非常感谢。从 -ggdb 切换到 -gdwarf-3 对我的环境有用:gbd 7.4-2012.04 和 gcc 4.9.4
【解决方案3】:

gdb 在 .symtab .dynsym 之前读取 .debug_info 部分。

nm 只是读取 .symtab .dynsym。

这是因为您的 ELF 文件中的 .debug_info 部分是条带化的。

你可以使用:

readelf -S youelf | grep -i debug

检查是否存在 debug_info。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2012-08-09
    • 2016-07-22
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多