gcov查看代码覆盖率

絮絮叨叨:想写的素材有很多,每次都是拖到最后也没写完,还是要多学习彭同学的 “先找软柿子捏” 。

GCOV 工具简介

gcov是一个测试代码覆盖率的工具。

它是 gcc 自带的查看代码覆盖率的工具,无需额外安装,在嵌入式的 arm-eabi-none-gcc 中同样可以使用(需要重写部分系统函数)。

使用效果如下图所示:

程序运行完成后,可以查看每个文件的代码覆盖率情况,上面报告中展示了每个文件的行覆盖率,函数覆盖率和分支覆盖率。

打开一个文件的覆盖率报告,页面对开始有文件的基本信息描述,以 FreeRTOS 的 task.c 为例,它的有效代码行数为 921 行,共 24 个函数(几千行的文件其实也没多少嘛~)

在覆盖率的正文,有该文件的完整代码,并用不同颜色进行高亮标注了:

  • 蓝色表示运行被覆盖的代码,前面的数字表示代码执行次数。
  • 红色表示未执行代码。
  • 白色表示无效代码,包括注释,空行和未编译代码。

gcov 使用

使用 gcov 的流程非常简单,只需要三步即可。
下面以 hello world 为例,展示生成覆盖率报告。

代码如下:

//main.c

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello world\n");
    return 0;
}

第一步: 添加编译参数 -fprofile-arcs -ftest-coverage

在所需要的生产覆盖率的文件中,添加编译参数,编译代码生成目标文件,同时会生成 *.gcno 文件,其中包含文件的行号等信息。

gcc main.c -c -fprofile-arcs -ftest-coverage -o main.o
ls # 输出文件列表:
# main.c  main.gcno  main.o
gcc main.o -lgcov -o main

第二步: 添加链接参数 -lgcov ,运行程序

运行程序后,会生成一个 *.gcda 文件,里面包含代码执行次数等数据。

gcc main.o -lgcov -o main
# 运行程序
./main
# hello world
ls # 输出文件列表:
#main  main.c  main.gcda  main.gcno  main.o

第三步: 输出覆盖率报告
使用下面命令输出覆盖率报告

# 第一次使用前安装工具
sudo apt install lcov

# 生成覆盖率文本报告
lcov -c -d . -o test.info --rc lcov_branch_coverage=1
# 生成覆盖率网页报告
genhtml --branch-coverage -o result test.info

输入上面两/三条命令后在,执行命令的文件路径可以看到一个 result 文件夹,在里面就是对应的网页覆盖率报告。


用浏览器打开 index.html 就可以看到最开始展示的覆盖率信息了。

特殊环境使用注意点:

在正常使用 gcov 是非常简单的,但是在特殊项目中使用 gcov 需要注意一些坑,否则就会跟我一样掉进去出不来。。。

  1. 链接时,会在 .init_array 段插入 __gcov_init() 函数,该函数在 main 运行之前初始化 gcov 运行环境。

    如果修改过链接脚本,注意 .init_array 的全局构造函数是否执行成功。

  2. 和上面一样,链接时,会在全局析构函数中插入 __gcov_exit() 函数,在 main 执行结束后,输出 *.gcda 文件。

    如果程序为异常退出,则不会生成 *.gcda 文件,此时需要在代码适当位置插入 __gcov_flush() 函数,将文件进行保存。

  3. 默认状态 *.gcda 文件和 *.gcno 文件所在文件夹相同,如果需要修改输出文件夹,可通过添加环境变量:GCOV_PREFIX 和 GCOV_PREFIX_STRIP

    GCOV_PREFIX_STRIP=16 , 为将原有路径裁剪16个文件夹。
    GCOV_PREFIX=/home/tester/build , 为将裁剪后的路径添加前缀
    例如:上文中默认 main.gcda 所在的文件 /home/tester/main.gcda,裁剪后添加前缀后变为/home/tester/build/main.gcda

  4. gcov 内部使用了一些系统函数,需要确保这些哈是函数可用

实现原理

gcov 实现基本原理为在编译时,向代码中插桩,记录运行时的执行流,具体细节可见参考链接两位大佬的详细分析,我就在在此赘述了。

1

2


gcov查看代码覆盖率
https://gary-hobson.github.io/2022/09/04/gcov查看代码覆盖率/
作者
非典型技术宅
发布于
2022年9月4日
许可协议