You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC能否排除crt*.o的DWARF5调试信息同时保留自有代码调试信息?

问题原因

你添加的-gdwarf-4 -gstrict-dwarf参数仅会控制当前编译流程中,编译器、汇编器处理自有源码生成的目标文件的DWARF版本,不会影响链接阶段GCC自动引入的系统预编译C运行时启动文件(crt1.o、crti.o、crtn.o、Scrt1.o等crt*.o系列文件)。这些文件是发行版构建glibc时预编译生成的,目前多数新发行版默认使用DWARF 5格式生成调试信息,因此哪怕自有代码全部生成DWARF 4信息,最终链接出的二进制仍会携带DWARF 5编译单元,触发Ghidra抛出异常。

可行解决方案

可以通过ld链接器的段丢弃规则实现需求:仅剔除来自crt系列文件的调试信息,完整保留自有代码的DWARF 4调试信息,不需要修改系统文件。

  1. 新建一个极简链接脚本片段,比如命名为strip-crt-dwarf.ld,内容如下:
    SECTIONS {
      /DISCARD/ : {
        */crt*.o(.debug*)
        */Scrt1.o(.debug*)
        */gcrt1.o(.debug*)
      }
    }
    
    这段规则的作用是告诉链接器:所有匹配通配符路径的启动目标文件中,所有以.debug开头的段(即全部DWARF调试信息段)直接丢弃,不链接进最终二进制。
  2. 编译代码时,在原有编译参数基础上追加参数,把这个链接脚本传给ld即可:
    gcc -gdwarf-4 -gstrict-dwarf foo.c -o foo -Wl,-T,strip-crt-dwarf.ld
    
    编译完成后用readelf -w foo验证,就看不到来自crt文件的DWARF 5编译单元了,自有代码的DWARF 4调试信息会完整保留,Ghidra可以正常加载。

小提示:如果你的项目中存在以crt开头命名的自有目标文件,担心被通配符误匹配,可以把链接脚本里的路径改成对应系统库的实际路径,比如Debian/Ubuntu x86_64环境下可以写成/usr/lib/x86_64-linux-gnu/crt*.o(.debug*),就只会剔除系统路径下的启动文件调试信息。

其他可选方案

如果你不想维护额外的链接脚本,也可以手动重排链接顺序控制strip规则的生效范围:先单独编译自有源码为目标文件,再手动调用ld,在引入crt文件时开启调试段剥离,引入自有目标文件和系统库时关闭剥离。不过这种方式需要手动指定所有链接依赖,操作复杂度更高,不如链接脚本方案易用。

内容的提问来源于stack exchange,提问作者Tavian Barnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:48:21