介绍一下gcov/lcov/gcovr
-
gcov 是一个测试代码覆盖率的程序,正确地使用它搭配GCC可以分析、帮助你将代码写得更高效。帮助你优化程序。类似于一个profiling tool,使用gcov或者gprof,可以收集到一些基础的性能统计数据。比如:
- 每一行代码执行的频度
- 每个代码文件中实际被执行到的行数
- 每一个代码块执行使用的时间
-
gcov创建一个logfile叫做 源文件名称.gcxx (这里的源文件名称指的是.c或者.cc文件的文件名),表示的是这个 源文件.c 中每一行所被执行的次数。这些文件可以配合gprof使用。 gcov要工作只能用gcc编译这些代码。和其他的profiling 或者 测试代码覆盖率的机制不兼容。
-
lcov 是GCC 测试覆盖率的前端图形展示工具。它通过收集多个源文件的 行、函数和分支的代码覆盖信息, 并且将收集后的信息生成HTML页面。生成HTML需要使用genhtml命令下文会解释。
-
gcovr 也是GCC 测试覆盖率的前端图形展示工具。
-
代码覆盖率测试工具可以帮助我们发现代码中未被测试的部分,
-
gcov/lcov/gcovr之间的差异:
- GCOV:与GCC配套,不需要安装,生成纯文本文件
- LCOV:需要安装,跨平台麻烦,生成HTML页面
- GCOVR:需要安装,跨平台容易,且指令比LCOV少,生成HTML页面
-
gcov是随gcc一起发布的,并不需要独立安装,设法装上gcc就OK了。
如何编译检查代码分支覆盖情况
- 编译与执行前,若是在交叉编译环境,需要在板端加入如下内容:
export GCOV_PREFIX=/mnt/xx 表示在板端的目录链接略去编译端前三个目录为 /mnt/xx/workspace
export GCOV_PREFIX_STRIP=3 表示删去原编译端的目录为 /home/1233/test/workspace
- 例程 test_gcov.c
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc >=2) {
printf("=====argc>=2\n");
return 0;
}
printf("helloworld begin\n");
if (argc <2){
printf("=====argc<2\n");
return 0;
}
return 0;
}
- 使用gcc编译,并加入如下编译选项
(指向特定版本的)gcc -fprofile-arcs -ftest-coverage -g -O0 -o test_gcov test_gcov.c
-
注意:这里若为交叉编译环境,需要指定对应板端的gcc编译器,如/opt/rkxxx1234/bin/gcc-10.2.1/gcc
-
我们将得到一个被“改造”过的可执行程序test_gcov ,该程序中包含了一些额外的指令,用于记录程序中每一行被执行的次数。以及一个后缀为.gcno的test_gcov .gcno文件,它是即将被gcov引用的关键数据文件。
-
编译选项说明:
-ftest-coverage选项:添加记录单行代码执行次数的指令
-fprofile-arc选项:添加程序每个分支的检测代码(if或者其它条件语句) -
在运行环境,如板端,运行可执行程序之后,我们会得到一个test_gcov.gcda的文件,它和test_gcov .gcno一样是即将被gcov引用的数据文件(代码覆盖率信息文件)。
./test_gcov
- 通过gcov命令生成代码覆盖率报告
(指定版本和gcc版本一致的)gcov test_gcov.c
File 'test_gcov.c'
Lines executed:86.67% of 15
Creating 'test_gcov.c.gcov'
- 执行指令后,gcov会引用之前的数据文件生成一个代码覆盖率报告test_gcov.c.gcov,查看该文件可以看到每行的执行次数等信息。
-: 0:Source:test_gcov.c
-: 0:Graph:test_gcov.gcno
-: 0:Data:test_gcov.gcda
-: 0:Runs:1
-: 1:#include <stdio.h>
-: 2:#include <string.h>
-: 3:
1: 4:int main(int argc, char *argv[])
-: 5:{
1: 6: if (argc >=2) {
#####: 7: printf("=====argc>=2\n");
#####: 8: return 0;
-: 9: }
1: 10: printf("helloworld begin\n");
-: 11:
1: 12: if (argc <2){
1: 13: printf("=====argc<2\n");
1: 14: return 0;
-: 15: }
#####: 16: return 0;
-: 17:}
- 注意:这里若为交叉编译环境,需要指定gcov与gcc编译版本一致,不一致会导致报错。
- “#####”所标记的是未被执行的语句。
lcov可视化代码分支覆盖率
-
在代码编译和链接的时候,需要加上下面两个编译选项。在gcc链接时需要加上gcov链接参数。
-fprofile-arcs -ftest-coverage
-
使用过程,注意:lcov在执行时会打印出所依赖的版本,要检查是否和编译所使用的gcc版本一致,交叉编译环境下通常存在多个编译器版本,这可能会导致生成相关覆盖率文件时出错。
- 使用
lcov -c -d ./ -o all.info --gcov-tool=arm-linux-gnueabihf-gcov
可以指定gcov版本 - 初始化并创建基准数据文件, -c 捕获,-i初始化,-d应用目录,-o输出文件
lcov -c -i -d ./ -o init.info
- 执行编译后的测试文件,交叉编译环境下需要在板端运行
./test_gcov
- 收集测试文件运行后产生的覆盖率文件
lcov -c -d ./ -o cover.info
- 合并基准数据和执行测试文件后生成的覆盖率数据, -a 合并文件
lcov -a init.info -a cover.info -o total.info
- 过滤不需要关注的源文件路径和信息,–remove 删除统计信息中如下的代码或文件,支持正则
lcov --remove total.info '*/usr/include/*' '*/usr/lib/*' '*/usr/lib64/*' '*/usr/local/include/*' '*/usr/local/lib/*' '*/usr/local/lib64/*' '*/third/*' 'testa.cpp' -o final.info
- 通过final.info生成html文件
genhtml -o cover_report --legend --title "${project_name} commit SHA1:${commitId}" --prefix=${curr_path} final.info
-o 生成的html及相关文件的目录名称,–legend 简单的统计信息说明,–title 项目名称,–prefix 将要生成的html文件的路径
genhtml -o cover_report --legend --title "lcov" --prefix=./ final.info
- test_gcov.gcda、test_gcov.gcno、test_gcov.gcda、test_gcov就是运行可执行文件后gcov产生的统计信息文件。
- cover_report目录就是生成的html信息目录。
- lcov常用的参数:
-d 项目路径,即.gcda .gcno所在的路径
-a 合并(归并)多个lcov生成的info文件
-c 捕获,也即收集代码运行后所产生的统计计数信息
–external 捕获其它目录产生的统计计数文件
-i/–initial 初始化所有的覆盖率信息,作为基准数据
-o 生成处理后的文件
-r/–remove 移除不需要关注的覆盖率信息文件
-z 重置所有执行程序所产生的统计信息为0
- 使用
-
问题1:
报错:geninfo: WARNING: /xx/work/3work/test/test_gcov.gcno: Overlong record at end of file!
/xx/xx/work/3work/test/test_gcov.gcno:version ‘B02*’, prefer ‘A75*’
/xx/xx/work/3work/test/test_gcov.gcno:no functions found
解决方法:lcov -v 查看版本,较低的话需要升级版本。
gcovr可视化代码分支覆盖率
-
相比于lcov,gcovr可能更方便一点。lcov有的功能gcovr都有,并且gcovr也是开源的,它是用Python写的,这意味着只要有Python环境都可以使用gcovr,无论是WINDOWS还是LINUX。
-
安装非常简单
-
Install newest stable gcovr release from PyPI:
pip install gcovr
-
Install development version from GitHub:
pip install git+https://github.com/gcovr/gcovr.git
-
-
使用
GCC可以检测可执行文件以发出覆盖数据。您需要使用以下标志重新编译代码:--coverage -g -O0
接下来,运行测试套件。这将生成原始覆盖率文件。
最后,调用gcovr。这将在控制台上打印一份表格报告。gcovr
还可以生成详细的或嵌套的HTML报告:
gcovr --html-details coverage.html gcovr --html-nested coverage.html 或 gcovr -r . --html --html-details -o coverage.html
gcovr相比lcov指令简单,一句即可生成可视化报告。
-
gcovr工具项目地址:https://github.com/gcovr/gcovr
参考资料
1、https://www.cnblogs.com/ChinaHook/p/5508660.html