为何GDB中list compare_mtime命令显示的是timespec_cmp函数代码?
为什么GDB的
list compare_mtime会显示另一个函数的代码? 这是调试coreutils这类优化过的开源工具时很常见的小问题,我来给你拆解下背后的原因:
1. 编译优化导致的函数内联/合并
coreutils默认是用较高等级的编译优化(比如-O2)构建的,对于像compare_mtime这类简单的static辅助函数,编译器很可能会做内联优化——也就是把这个函数的代码直接嵌入到调用它的地方;甚至如果它只是对timespec_cmp的简单封装(比如只负责传参调用后者),编译器会直接把compare_mtime的实现替换成timespec_cmp的调用,彻底“消除”这个函数的独立存在。
这种情况下,GDB虽然能从符号表中找到compare_mtime的声明(就是你用info functions看到的那行),但对应的实际代码地址已经和timespec_cmp重叠了,所以执行list compare_mtime时,GDB会跳转到timespec_cmp的源码位置。
2. static函数的符号表限制
static函数的作用域只限于当前编译单元,编译优化后,编译器可能会弱化甚至移除这类函数的调试符号信息。当GDB找不到compare_mtime对应的源码行时,就会退而求其次,显示最近的有调试符号的函数代码,也就是timespec_cmp。
怎么验证和解决?
- 用
disassemble compare_mtime查看汇编代码:如果输出里直接是调用timespec_cmp的指令,或者和timespec_cmp的汇编完全一致,就实锤是优化导致的。 - 重新编译coreutils时关闭优化:执行
./configure CFLAGS="-g -O0"再编译,这时候编译器会保留所有调试符号和函数的独立实现,list compare_mtime就能正确显示它的源码了。
内容的提问来源于stack exchange,提问作者user8629136
相关产品推荐
相关产品推荐

