C++代码覆盖率需用gcov生成数据、lcov生成HTML报告,关键在编译(-O0 -g -fprofile-arcs -ftest-coverage)、运行(正常退出生成.gcda)、收集(lcov三步操作)三者路径与环境严格一致。

看C++代码覆盖率,核心是用 gcov 生成基础覆盖率数据,再用 lcov 整理成直观的HTML报告。关键不是跑通命令,而是编译、运行、收集三步都得对上源码路径和构建环境。
编译时必须加覆盖率支持标志
只加 -fprofile-arcs -ftest-coverage 不够,还容易和优化冲突。推荐这样编译:
- 关闭优化:
-O0(否则 gcov 可能跳过某些行,导致“未执行”误报) - 保留调试信息:
-g(让 lcov 能准确定位源码行) - 启用覆盖率:
-fprofile-arcs -ftest-coverage - CMake 用户可在
CMakeLists.txt中设:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -fprofile-arcs -ftest-coverage")
运行程序后自动生成 .gcda 文件
可执行文件运行完,会在每个被编译的源文件同级目录(或指定输出目录)生成 .gcda 文件——这是实际执行轨迹数据。注意:
- 程序必须正常退出(
return或exit()),异常终止可能不写 .gcda - 多次运行会累加数据,适合合并多个测试用例的结果
- 若用
make clean清除了 .gcda,覆盖率就丢了,别手滑
用 lcov 生成可视化 HTML 报告
分三步走,顺序不能错:
立即学习“C++免费学习笔记(深入)”;
-
清空旧数据:
lcov --directory . --zerocounters -
捕获当前覆盖率:
lcov --capture --directory . --output-file coverage_base.info -
过滤掉无关文件(如头文件、第三方库)并生成网页:
lcov --remove coverage_base.info '/usr/*' '*/test/*' '*mock*' --output-file coverage.info && genhtml coverage.info --output-directory coverage-report
打开 coverage-report/index.html 就能看到带颜色标记的源码页:绿色=执行过,红色=完全未执行,黄色=部分分支未走。
常见坑和应对
路径不一致:gcov 读不到源码,报告里全是“source not available”。解决方法是确保编译时的绝对路径和运行时一致,或用 lcov --base-directory 和 --directory 手动对齐。
动态库没覆盖到:如果项目含 .so,需对动态库也加覆盖率编译选项,并在运行时确保它被加载(比如用 LD_PRELOAD 或直接链接)。
模板/内联函数显示为未覆盖:gcc 默认不为模板实例化生成 gcov 数据。加编译选项 -fno-elide-constructors 和 -fno-default-inline 可缓解,但更稳妥的是把关键逻辑拆到普通函数中。











