什么情况会导致变量存在于链接器map文件中但不在ELF符号表中?
原因分析
- 符号被剥离或隐藏,未保留在ELF最终符号表中
若你对输出的ELF执行过strip类操作,尤其是strip --strip-unneeded,该操作会移除所有不参与动态链接的内部全局符号,仅保留动态导出符号,因此readelf -s无法查询到该变量。而链接器的map文件是在strip操作前生成的,因此会记录该变量的正确地址。
另外如果编译时全局开启了-fvisibility=hidden,且该变量未显式指定__attribute__((visibility("default"))),或者链接时使用了版本脚本控制符号导出、将该变量标记为不导出,也会导致其不会出现在最终的符号表中。 - 调试信息生成不完整
你当前看到的带DW_AT_declaration标记的DWARF条目,对应的是头文件中该变量的声明信息(哪怕你没有显式写extern,头文件中的变量声明本身也会被标记为declaration),对应定义的DWARF条目缺失有两种常见可能:- 变量定义所在的源文件编译时开启了O2及以上优化等级,或开启了链接时优化(LTO),编译器认为该内部变量不需要生成完整调试信息,因此没有生成带
DW_AT_location的定义类DWARF条目,但变量本身因为被正常使用没有被优化掉,因此map文件中存在地址。 - 编译时使用的是
-g1(最小调试信息)等级,而非默认的-g/-g2,编译器不会生成变量位置、类型展开等完整调试信息,仅会保留最基础的声明信息。
- 变量定义所在的源文件编译时开启了O2及以上优化等级,或开启了链接时优化(LTO),编译器认为该内部变量不需要生成完整调试信息,因此没有生成带
内容的提问来源于stack exchange,提问作者user2052153
相关产品推荐
相关产品推荐

