GCC11+编译Cortex-M0代码时GDB显示错误源文件的问题排查
问题分析与解决方案
这个现象是GCC 11及以上版本针对ARM Cortex-M0平台,在启用函数/数据段垃圾回收(GC)后调试信息清理不彻底导致的GDB错误关联,并非你的操作失误,属于GCC版本相关的已知问题范畴。
排查与解决步骤:
- 调整调试信息生成选项:GCC 11对调试信息的存储和关联机制做了调整,尝试将调试信息生成选项从
-g3降级为-g2,或添加-fno-eliminate-unused-debug-types,避免未使用的调试符号残留。 - 补充链接器清理参数:在现有链接选项基础上,添加
-Wl,--discard-locals,--print-gc-sections,前者清理本地调试符号,后者可打印被GC的段信息,确认调试相关段是否被正确回收。 - 调整GCC版本:该问题在GCC 13+的arm-none-eabi工具链中已被部分修复,可尝试升级到最新稳定版;若暂时无法升级,降级回GCC 10可直接恢复正常调试。
- 检查自定义链接器脚本:如果项目使用了自定义链接器脚本,确认脚本中是否存在对0x0000地址段的特殊定义,避免GC后的无效调试条目被错误映射到该地址。
- 手动清理无效调试信息:使用
objcopy --strip-unneeded --only-keep-debug分离调试信息后重新关联,或用eu-strip工具清理ELF中无效的调试条目,减少GDB解析错误。
关键现象解释:
objdump -dlr看到被移除函数出现在0x0000地址,是因为GC后这些函数的代码段被释放,但调试信息里的行号映射未被删除,GDB解析时将无符号的0x0000地址错误关联到了已被GC的函数源码上;而readelf -a看不到符号,是因为符号表已被正确清理,仅调试信息残留了无效映射。
内容的提问来源于stack exchange,提问作者Trampas
相关产品推荐
相关产品推荐

