gcov#

gcov 是 GCC 工具链中的代码覆盖率分析工具,能够精确展示单元测试对源代码的覆盖情况。

使用方法#

在编译阶段,由 .c 源文件生成 .o 目标文件时,需添加 --coverage 编译选项:

$(OBJS): %.o: %.c
	$(CC) $(CFLAGS) --coverage -c $< -o $@

在链接生成可执行文件时,同样需要添加 --coverage 选项:

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) --coverage -o $@ $^

Note

--coverage 是 GCC 提供的宏选项,等价于同时使用以下三个选项:

  • -fprofile-arcs:编译时插桩,记录代码执行路径

  • -ftest-coverage:生成程序结构信息文件

  • -lgcov:链接覆盖率运行时支持库

生成覆盖率报告#

运行程序生成数据文件:执行编译后的程序:

./your_program

程序运行后会生成 .gcda(运行时数据)和 .gcno(程序结构信息)文件。

生成原始覆盖率数据:对每个需要分析的源文件执行 gcov 命令:

gcov main.c

此命令会生成对应的 .gcov 文本格式报告文件。

生成可视化报告:使用 lcov + genhtml 工具链:

# 1. 收集覆盖率数据
lcov -c -d . -o coverage.info

# 2. 可选:过滤系统头文件
lcov -r coverage.info '/usr/include/*' -o coverage_filtered.info

# 3. 生成 HTML 报告
genhtml coverage_filtered.info -o coverage_report

# 4. 查看报告
firefox coverage_report/index.html
lcov 常用参数
# 仅收集指定目录的覆盖率数据
lcov -c -d src/ -o coverage.info

# 合并多个覆盖率数据文件
lcov -a coverage1.info -a coverage2.info -o total.info

覆盖率报告解读

双击 lcov 生成的 index.html 文件,即可在浏览器中查看覆盖率报告。报告主要包含以下三列数据:

列名

说明

Branch data

分支覆盖率,显示代码中每个分支(如 if/elseswitch 等)的执行情况

Line Data

行覆盖率,显示每行代码是否被执行过

Source code

对应的源代码,通过颜色高亮显示覆盖情况

屏蔽相关代码的统计

如需从覆盖率统计中排除特定代码,请在源代码中添加对应的屏蔽注释并重新编译。重新生成的库文件在运行时将忽略被标记的代码,使其不参与覆盖率统计。

支持以下屏蔽方式:

  • 多行屏蔽:在目标代码段起始处添加 // LCOV_EXCL_START,在结束处添加 // LCOV_EXCL_STOP

  • 单行屏蔽:在代码行末尾添加 // LCOV_EXCL_LINE

  • 分支屏蔽:仅排除分支统计,保留代码执行统计,在分支判断语句后添加 // LCOV_EXCL_BR_LINE

示例:

// LCOV_EXCL_START
void unused_function() {
    // 此函数不会被统计
}
// LCOV_EXCL_STOP

void active_function() {
    log("running");  // LCOV_EXCL_LINE
    if (condition) { // LCOV_EXCL_BR_LINE
        // 此分支不纳入分支统计
    }
}