gcov与 lcov简介 通过gcov和lcov,可以很直观的看到代码的运行情况,同时也可以查看代码的行覆盖率,函数覆盖率等等信息,为开发提供一个方便的测试手段。 gcov gcov是Linux下GCC自带的一个C/C++代码覆盖率分析工具,因此只要安装了gcc,就不需要再次安装了 lcov介绍 gcov能够生成代码覆盖信息,但是不够直观,因此需要借助lcov直观展示覆盖率 下面简单介绍linux下,使用gcov和locov进行代码覆盖率的测试。 Processing file gcov_lcov/test.c Writing directory view page. 总结 结合使用gcov和locv,可以比较直观的观察到运行的程序是否按照自己的设计,跑到了对应的代码中。当然对于以上过程,完全可以写成脚本,而无需每一次都进行如此繁杂的操作。
当我再次重新调查代码覆盖率的时候,我很惭愧的发现原来正在使用的 GCC 其实有内置的代码覆盖率的工具的,叫 Gcov[2] 前提条件 对于想使用 Gcov 的人,为了说明它是如何工作的,我准备了一段示例程序 sh-4.2$ lcov -v lcov: LCOV version 1.14 Gcov 是如何工作的 Gcov 工作流程图 flow 主要分三步: 在 GCC 编译的时加入特殊的编译选项,生成可执行文件 Processing file gcov-example/main.c Processing file gcov-example/foo.c Writing directory view page. main.c foo.c 即可生成 .gcov 代码覆盖率文件。 /2019/05/squishcoco/ [2] Gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html [3] GCC: https://gcc.gnu.org
一、gcov简单介绍Gcov是一个测试C/C++代码覆盖率的工具,伴随GCC发布,配合GCC共同实现对C/C++文件的语句覆盖、功能函数覆盖和分支覆盖测试。 二、gcov统计生成覆盖率流程图1 gcov覆盖率生成过程Gcc在编译阶段指定 –ftest-coverage 等覆盖率测试选项后,GCC会:1、 在输出目标文件中留出一段存储区保存统计数据;2、 在源代码中每行可执行语句生成的代码之后附加一段更新覆盖率统计结果的代码,也就是插桩(后面详细介绍);3、 Gcc编译,会生成*.gcno文件,它包含重建基本块图和相应块的源码的行号信息;4、 在最终可执行文件中,进入main函数之前调用gcov_init 内部函数初始化统计数据区,并将gcov_init内部函数注册为exit_handers,用户代码调用exit正常结束时,gcov_exit函数得到调用,并继续调用__gcov_flush输出统计数据到* 三、原理(插桩)gcov是使用 基本块BB 和 跳转ARC 计数,结合程序流图来实现代码覆盖率统计的:图2 程序流图基本块BB:如果一段程序的第一条语句被执行过一次,这段程序中的每一个都要执行一次,称为基本块
NSDictionary *)launchOptions方法中调用以下方法(也可以在main.m文件中调用) void initTestCoverage(void) { const char* prefix = "GCOV_PREFIX setenv(prefix, prefixValue, 1); setenv(prefixStrip, prefixStripValue, 1); } 然后在需要产生代码覆盖率的地方调用__gcov_flush ()方法产生覆盖率文件,需要注意,必须先添加声明extern void __gcov_flush(void); 5、查看生成的gcno和gcda文件 gcno是编译时产生,可以点击Xcode的product 建议先检查gcno是否生成,在查看gcda是否生成; 2、编译的时候链接失败 链接时出现以下错误 Undefined symbols for architecture armv7: "___gcov_flush ", referenced from: 检查步骤2、3设置的属性是否在当前环境下打开; 3、调用___gcov_flush卡死 ___gcov_flush是同步方法,并且耗时较长,如果在主线程调用会造成卡死
·输出详细的覆盖率报告(.gcov 文件),便于分析。 6.2.2. 3使用Gcov生成覆盖率报告 bash gcov my_program.c ·生成my_program.c.gcov文件,显示每行代码的执行次数。 6.2.8 与jenkins集成 stage('gcov'){ steps { echo "开始gcov" sh ''' gcov -a process-process ·适用于大型项目,比Gcov更易于管理。 ·开源免费,与 Gcov 无缝集成。 2缺点 ·依赖 Gcov,仅适用于 GCC 编译的代码(不适用于 Clang/MSVC)。 ·HTML 报告较大,可能不适合超大型项目。
背景 最近想统计一个c++的server 的http接口的对代码的覆盖率情况,但之前做的覆盖率统计都是Unittest的覆盖率,而且一般都是统计非daemon程序的,查了一下,daemon也可以使用gcov +lcov来生成覆盖率信息,简单记录了一下; 准备 damon进程与可执行进程不同的地方是需要注册一个gcov_flush的触发条件,一般通过注册信号量的方式实现,例子是ctrl+C时触发__gcov_flush ; extern "C" void __gcov_flush();void cs(int n){ signal(SIGINT, cs);if(n==SIGINT){__gcov_flush();std: cmake -DCMAKE_BUILD_TYPE=Debug make 会在CMakeFiles里产生相关工程的.gcno和.o文件 运行 运行程序,后执行接口测试case,按下CTRL+C 触发gcov_flush
install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9 --slave /usr/bin/gcov gcov /usr/bin/gcov-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 --slave / usr/bin/g++ g++ /usr/bin/g++-8 --slave /usr/bin/gcov gcov /usr/bin/gcov-8 sudo update-alternatives -- install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 --slave /usr/bin/gcov gcov /usr/bin/gcov-7 后面,如果你想更改你的默认版本,你可以使用update-alternatives命令: sudo update-alternatives --config gcc
覆盖率测试原理 在 App 运行时调用__gcov_flush() 输出 GCDA 文件, 记录每行代码的执行次数。 然后用 lcov 命令从 CGDA + GCOV 生成报告文件,可以看到运行过程中每行代码的执行次数。 问题定位 搜到很多人讨论,尝试文中提到的方法均无效,怀疑是 Xcode7 bug:生成 GCDA 文件的 __gcov_flush() 函数的问题。 故找到其llvm compiler-rt 开源代码,导入Xcode项目中: GCDAProfiling.c / InstrProfiling.c / InstrProfiling.h 将调用__gcov_flush ()的文件声明 extern void __gcov_flush() 改成 #import “GCDAProfiling.c”,就可以自行 debug 了。
工具链 - 覆盖率统计gcov C++代码的覆盖率可以采用gcc自带的gcov来实现了。具体的原理和使用过程可以参见其它文章。 工具链 - 覆盖率报告lcov/gcovr gcov生成的覆盖率结果文件可读性很差,一般都需要额外的工具对gcov的结果文件进行解析和进一步优化,生成可读性更好的xml或者html文件。 lcov和gcovr是两个比较流行的gcov报告解析器。其中lcov的功能更为强大一些,有覆盖率结果累加等功能,但是只提供了html报告。 如果关注C++覆盖率统计的同学,可以阅读gcov/gcovr/lcov等工具的说明文档,以了解这些高阶应用。 public --enable=all --inconclusive --xml-version=2 . 2> reports/cppcheck.xml 4、在工程根目录下,生成覆盖率检测报告(假设已完成gcov
准备工具 请参考教程安装即可: GCC CMake Google Test gcov lcov gcovr 代码覆盖率 代码覆盖率一般包含以下几种类型: 函数覆盖率:描述有多少比例的函数经过了测试。 gcov gcov是由gcc工具链提供的代码覆盖率生成工具,可以很方便的和GCC编译器配合使用,通常情况下,直接安装gcc工具链,也就同时包含了gcov命令行工具。 通过gcov指定源码文件的名称,便可以得到该源码文件的覆盖率结果: gcov TestMain.cpp.gcno lcov gcov得到的结果是文本形式的,而且不同的源码文件需要一一执行gcov命令, lcov是gcov工具的图形前端,收集多个源文件的gcov数据,生成描述覆盖率的HTML页面。生成的结果中会包含概述页面,方面浏览。 gcovr 一般场景下使用gcov和lcov能满足代码覆盖率的获取和展示工作,lcov和genhtml配合生成的HTML报告内容详尽,简洁直观,行覆盖率、分支覆盖率都有,但是HTML文件在常用的持续集成工具
XcodeCoverage是通过gcc编译的时候加入gcov统计代码覆盖率,Gcov可以执行函数覆盖、语句覆盖和分支覆盖。同样的,我们也可以按照这种思路来实现手工测试的代码覆盖率统计。 ? 设置scheme,将运行的scheme设置为刚才添加的configuration gcov ? 4. 我们还需要在工程中配置触发方法,可以在AppDelegate中添加代码__gcov_flush(),这样当按Home键退出的时候测试覆盖率数据会写到统计文件中 ?
配置成YES,如下图: 最后给 Preprocessor Macros 增加一个字段 COVERAGE=1,如下图: 5、在项目源码中添加生成覆盖率的相关代码,这里我们在应用退出的时候调用__gcov_flush () 来生成.gcda文件,这个文件中记录了我们应用的代码覆盖率数据,具体代码如下: 注意:__gcov_flush() 方法可重复调用,覆盖率数据会累计。 NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; setenv("GCOV_PREFIX ", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1); setenv("GCOV_PREFIX_STRIP", "13", 1); extern void __gcov_flush(void); __gcov_flush(); #endif 6、编译运行并打包,然后装到手机上使用即可。
可以看到系统上已经新增了这么多交叉编译工具: helloworld@ubuntu:~$ arm-linux-gnueabihf- arm-linux-gnueabihf-addr2line arm-linux-gnueabihf-gcov -7 arm-linux-gnueabihf-ar arm-linux-gnueabihf-gcov-dump arm-linux-gnueabihf-as arm-linux-gnueabihf-gcov-dump-7 arm-linux-gnueabihf-c++filt arm-linux-gnueabihf-gcov-tool arm-linux-gnueabihf-cpp arm-linux-gnueabihf-gcov-tool-7 arm-linux-gnueabihf-cpp-7 arm-linux-gnueabihf-gprof arm-linux-gnueabihf-size arm-linux-gnueabihf-gcc-ranlib-7 arm-linux-gnueabihf-strings arm-linux-gnueabihf-gcov
lcov代码覆盖率统计工具,是gcov的延伸版本,提供程序实际执行的信息(统计某行代码被执行的次数),其基于HTML的输出通过浏览器以清晰的图表形式呈现覆盖率统计结果。 如果是交叉编译移植到实机上需要执行这步: 修改文件:lcov-1.11/bin/genifo vim lcov-1.11/bin/genifo 然后将第65行的:our $gcov_tool = “gcov” 改为自己的交叉编译器的gcov 比如我的交叉编译工具是/usr/local/arm/4.3.2/bin/arm-linux-gcc 那么就改为:our $gcov_tool = “/usr/local/arm/4.3.2/bin/arm-linux-gcov” 可以使用:find / -name *gcov来查找下自己的交叉编译工具在什么目录下 (5)sudo make install
NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; setenv("GCOV_PREFIX ", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1); setenv("GCOV_PREFIX_STRIP ", "13", 1); #endif extern void __gcov_flush(void); __gcov_flush();
bin/g++ sudo ln -sf g++-4.3 /usr/bin/i686-linux-gnu-g++ sudo ln -sf gcc-4.3 /usr/bin/gcc sudo ln -sf gcov -4.3 /usr/bin/gcov sudo ln -sf gcc-4.3 /usr/bin/i686-linux-gnu-gcc 然后编译,OK。
x86_64-w64-mingw32-gcc-10-win32 x86_64-w64-mingw32-gcc-ranlib x86_64-w64-mingw32-gcov-tool-posix x86_64-w64-mingw32-gcc-ar x86_64-w64-mingw32-gcc-ranlib-posix x86_64-w64-mingw32-gcov-tool-win32 x86_64-w64-mingw32-gcc-ar-posix x86_64-w64-mingw32-gcc-ranlib-win32 x86_64-w64-mingw32-gcov-win32 x86_64-w64-mingw32-elfedit x86_64-w64-mingw32-gcc-nm x86_64-w64-mingw32-gcov x86_64-w64-mingw32-gcc-10-posix x86_64-w64-mingw32-gcc-posix x86_64-w64-mingw32-gcov-posix
当前使用 GCC 编译时支持该特性,并且需要gcov和lcov程序。一个典型的工作流程看起来是: ./configure --enable-coverage ... 如果没有lcov或者更喜欢文本输出而不是HTML报告,还可以运行 make coverage 来取代make coverage-html,它将为每个与测试相关的源文件产生.gcov输出文件(make
gcov gcov是由GCC工具链提供的代码覆盖率生成工具。它可以很方便的和GCC编译器配合使用。 通常情况下,安装好GCC工具链,也就同时包含了gcov命令行工具。 使用 这里我们以另外一个简单的代码示例来说明gcov的使用。 要通过gcov生成代码覆盖率。 只需要通过gcov指定源文件的名称(不需要带后缀):gcov test,便可以得到包含覆盖率的结果文件 test.c.gcov了。 lcov是gcov工具的图形前端。它收集多个源文件的gcov数据,并生成描述覆盖率的HTML页面。生成的结果中会包含概述页面,以方便浏览。 lcov支持我们前面提到的所有四种覆盖率。
答:覆盖率的计算gtest是不包含的,需要借助于gcov以及lcov来进行统计。gcov统计覆盖率数据,lcov用来生成可视化的图形界面。