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

如何防止未使用函数被链接器/编译器剔除以准确统计代码覆盖率?

解决GCC/gcov统计库覆盖率时未使用函数被链接器剔除的问题

在Linux环境下用GCC和gcov统计库L的代码覆盖率时,未被测试用例引用的L::foo()会被链接器默认剔除,导致覆盖率统计虚高。以下是几种可行的解决方法:

方法一:强制链接整个库

通过链接器选项--whole-archive强制链接库的所有目标文件,即使其中的函数未被引用。修改链接命令时需注意,该选项仅作用于紧跟其后的库,之后要用--no-whole-archive恢复默认行为,避免影响其他库:

gcc test.o -Wl,--whole-archive -lL -Wl,--no-whole-archive -o test
  • -Wl,xxx:将xxx参数传递给链接器ld
  • --whole-archive:链接指定库的所有目标文件,不剔除未引用符号
  • --no-whole-archive:恢复链接器默认的只链接引用符号的行为

方法二:标记单个函数为必须保留

如果只想保留特定未使用的函数(比如L::foo()),可以在函数的声明或定义中添加__attribute__((used))属性,告诉编译器和链接器该函数必须保留:

// 函数声明时添加
void L::foo() __attribute__((used));

// 或者函数定义时添加
void L::foo() __attribute__((used)) {
    // 函数实现
}

这个方法适合只需要保留少量未使用函数的场景,不会引入整个库的冗余代码。

方法三:调整符号可见性设置

如果库编译时使用了-fvisibility=hidden(默认隐藏非导出符号),链接器会更积极地剔除未引用的隐藏符号。此时可以:

  1. 给需要保留的函数添加可见性属性:
void L::foo() __attribute__((used, visibility("default")));
  1. 或者暂时移除-fvisibility=hidden编译选项(如果不影响库的正常使用)

关键注意事项

  • 编译库L时必须添加-fprofile-arcs -ftest-coverage选项,生成gcov所需的.gcno覆盖信息文件:
gcc -c -fprofile-arcs -ftest-coverage libL.cpp -o libL.o
ar rcs libL.a libL.o
  • 测试程序编译链接时也需要带上上述覆盖率选项,确保能生成.gcda执行数据文件
  • 验证函数是否被保留:可以用nm命令检查测试程序的符号表,确认L::foo()存在:
nm test | grep "L::foo"

完成上述设置后,运行测试用例生成.gcda文件,再用gcov或lcov工具统计覆盖率,就能看到L::foo()显示为未覆盖状态,统计结果更准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:28:17