gcov和lcov使用经验

转自: http://magustest.com/blog/tag/lcov/


使用gcov和lcov做代码覆盖有一段时间了,期间走了一些弯路,算是一些经验教训。

  • gcov可以对shared object进行代码覆盖信息收集。

之前的一篇文章说过,gcov不能收集.so的代码覆盖率信息,其实这个是错的。

如果是C++程序,在CXXFLAGS中加入-fprofile-arcs -ftest-coverage 作为编译选项,并且在LDFLAGS中加入-lgcov作为链接选项。如果没有-lgcov选项编译出来的.so文件在动态加载的时候会提示类似 undefined reference to ‘__gcov_merge_add’ 或者 undefined reference to ‘__gcov_init’这样的错误。

如果是C程序,在CFLAGS中加入-fprofile-arcs -ftest-coverage 作为编译选项,也是在LDFLAGS中加入-lgcov作为链接选项,就OK了。跑测试的时候跟正常测试一样,最后把收集到的.gcda文件处理一下就能得到代码覆盖率报告

  • 用lcov处理.gcda文件的时候,在处理某些文件的时候hang了。

对于这个问题,不知道根本原因是什么,可能是那个文件的某行代码触发了bug,我对此是workaround了一下。lcov本身是一堆Perl脚本,打开它,通常在这里“/usr/bin/geninfo”,然后找到这行,注释掉

push(@gcov_options, “-a”) if ($gcov_caps->{‘all-blocks’});

  • genhtml的一个参数:-f, –frames

Use HTML frames for source code view。这样会在每个结果页的左边生成一个缩略图,review代码的时候很方便。但是,如果你的项目里面用到了一些第三方的库,而那些第三方的库没有提供完整的源代码,那么使用这个参数就会出现问题。

gd-png: fatal libpng error: Image width or height is zero in IHDR
gd-png error: setjmp returns error condition

解决方法可以是1. 尝试找一下源代码;2. 通常这些第三方库,我们都是放在一个单独的文件夹里面的,这样子用lcov处理.gcda文件的时候,可以指定目录,把这些第三方库的目录跳过去

  • genhtml的一个参数:–num-spaces NUM

默认值是8,出来的报告看着很费劲,建议换成4,如果代码有很多层,那设成2也是可以的

 Posted by at 11:53  Tagged with: gcov, lcov,代码覆盖
12 2011
 

lcov是建立在gcov之上的一个可以生成html代码覆盖率报告的工具,最近公司开始尝试引入代码覆盖来提高产品质量,lcov很好地满足了我们的需求,虽然lcov本身支持生成代码覆盖率的diff报告,但是跟我们的需求不太符合。

首先说一下我们的情况,我们有一套自动化回归测试集,可以看做是我们测试的全集。现在已经完成了基于这个回归测试集的代码覆盖率报告,这其中肯定有某些行没有被覆盖到的,如何评估这些没有被测试过的行的风险呢?最开始是DEV跟QA一起review,由开发来评估这些没有被测试过的代码。最近提出了一个新的思路,就是用Production的代码覆盖和本地回归测试的代码覆盖做一个diff,着重看一下那些在Production里面实际被执行过的代码中,有哪些是我们本地回归测试所没有覆盖的,因为这些“裸奔”的代码才是最危险的代码。

查一下文档,lcov在生成html报告的时候可以做这个事情,在genhtml的时候使用参数“–baseline-file baseline-file”,指定了这个参数以后就会在用输入的tracefile里面的counter来减去baseline-file里面的counter,完成这个减法计算以后再生成报告。可以用Local测试的数据作为basefile,两者一减,在报告里面那些cover的行,就是Production上跑到的代码而回归测试集没有能覆盖的部分。但是如果直接用的话,结果可能不是我们想要的,因为我用了genhtml这样的一个特性:“Note that when a count for a particular line in baseline-file is greater than the count in the tracefile, the result is zero.”。

举个例子,如果我们的代码被执行了若干次:

CodeABCD
Local0405060
Production50505050
Actual result50 (local uncover)10 (local uncover)0 (covered)0 (covered)
Expectedlocal uncovercoveredcoveredcovered

主要看第三列,B这行代码。如果在Local测试中某行代码被执行了40次,而同一行代码在Production被执行了50次,那么diff出来的结果是这行代码没有被覆盖,而实际的结果是回归测试已经覆盖到了。解决思路很简单,我们可以让Local的counter增加N倍,这个N要足够大,就能避免这种情况的发生了。当我们按照正常操作生成一个tracefile的时候,接下来就用“–add-tracefile tracefile” 来把这个tracefile的counter加上去,

lcov -a mytest.info -a mytest.info -o mytest_2x.info

lcov -a mytest_2x.info -a mytest_2x.info -o mytest_4x.info

写个shell脚本帮你干这个事情,不到半小时就能把counter增加2的N次方倍。最后以这个放大了counter的tracefile作为基线,生成的diff report

genhtml -o diffresult –num-spaces 4 –legend -b mytest_1024x.info prod.info

最终结果:

CodeABCD
Local0409605120061440
Production50505050
Actual result50 (local uncover)0 (covered)0 (covered)0 (covered)
Expectedlocal uncovercoveredcoveredcovered

什么样的代码最危险?没有被测试过的代码是最危险的。Production和regression test的代码覆盖率diff报告可以给我们提供一些有针对性的信息。

 Posted by at 16:40  Tagged with: gcov, lcov,代码覆盖
16 2010
 

两个PPT的主题其实都是关于代码覆盖的,那为什么分开了2个PPT呢?因为准备在两个会上讲,一个讲代码覆盖,尽量不涉及工具细节,另一个只介绍工具。

PPT写的很粗,主要靠讲,不过PPT本身的话我个人感觉一般般,但是又没有修改的动力了,就先放上来吧,有问题意见请及时给我反馈,多谢先啦。

Using gcov and lcov
Knowledge share on code coverage
 Posted by at 00:02  Tagged with: gcov, lcov,PPT, 代码覆盖
12 2010
 

gcov是一个可用于C/C++的代码覆盖工具,是gcc的内建工具。下面介绍一下如何利用gcov来收集代码覆盖信息。
想要用gcov收集代码覆盖信息,需要在gcc编译代码的时候加上这2个选项 “-fprofile-arcs -ftest-coverage”,把这个简单的程序编译一下

gcc -fprofile-arcs -ftest-coverage hello.c -o hello

编译后会得到一个可执行文件hello和hello.gcno文件,当用gcc编译文件的时候,如果带有“-ftest-coverage”参数,就会生成这个.gcno文件,它包含了程序块和行号等信息
接下来可以运行这个hello的程序

./hello 5
./hello 12

运行结束以后会生成一个hello.gcda文件,如果一个可执行文件带有“-fprofile-arcs”参数编译出来,并且运行过至少一次,就会生成。这个文件包含了程序基本块跳转的信息。接下来可以用gcov生成代码覆盖信息:

gcov hello.c

运行结束以后会生成2个文件hello.c.gcov和myfunc.c.gcov。打开看里面的信息:

-: 0:Source:myfunc.c
-: 0:Graph:hello.gcno
-: 0:Data:hello.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:void test(int count)
1: 4:{
-: 5: int i;
10: 6: for (i = 1; i < count; i++)
-: 7: {
9: 8: if (i % 3 == 0)
3: 9: printf (“%d is divisible by 3 \n”, i);
9: 10: if (i % 11 == 0)
#####: 11: printf (“%d is divisible by 11 \n”, i);
9: 12: if (i % 13 == 0)
#####: 13: printf (“%d is divisible by 13 \n”, i);
-: 14: }
1: 15:}

被标记为#####的代码行就是没有被执行过的,代码覆盖的信息是正确的,但是让人去读这些文字,实在是一个杯具。不用担心,有另外一个工具叫lcov,可以用程序解析这些晦涩的字符,最终输出成html格式的报告,很好吧!

lcov -d . -t ‘Hello test’ -o ‘hello_test.info’ -b . -c

指定lcov在当前目录“.”去找代码覆盖的信息,输出为’hello_test.info’ ,这个hello_test.info是一个中间结果,需要把它用genhtml来处理一下,genhtml是lcov里面的一个工具。

genhtml -o result hello_test.info

指定输出目录是 result。一个完整的html报告就生成了,做一个连接,把这个目录连到随便一个web server的目录下,就可以看报告了。



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,你需要安装gcovlcov工具。然后,你可以按照以下步骤进行操作: 1. 在test.cpp文件所在的目录下创建一个名为"CMakeLists.txt"的文件。 2. 在"CMakeLists.txt"文件中,添加以下内容: ``` cmake_minimum_required(VERSION 3.10) project(Test) set(CMAKE_CXX_STANDARD 11) add_executable(test test.cpp) target_compile_options(test PRIVATE --coverage) target_link_libraries(test PRIVATE gcov) add_custom_target(coverage COMMAND ${CMAKE_COMMAND} -E environment "GCOV_PREFIX=./" "GCOV_PREFIX_STRIP=0" ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR} gcov -b -c ${CMAKE_SOURCE_DIR}/test.cpp COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR} lcov --capture --directory . --output-file coverage.info COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR} lcov --remove coverage.info '/usr/*' "${CMAKE_BINARY_DIR}/*" --output-file coverage.info COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR} lcov --list coverage.info ) ``` 这个CMakeLists.txt定义了一个名为Test的项目,并将test.cpp编译为可执行文件test。编译选项--coverage允许生成代码覆盖信息。target_link_libraries指定链接gcov库。 add_custom_target添加一个名为“coverage”的自定义目标,该目标使用环境变量设置gcov生成代码覆盖信息。使用lcov收集覆盖信息,将其保存在coverage.info文件中,并且从输出中删除一些不必要的信息。 3. 在终端中进入test.cpp所在的目录,创建一个build目录。 ``` mkdir build && cd build ``` 4. 运行cmake命令。 ``` cmake .. ``` 5. 运行make命令,生成可执行文件test。 ``` make ``` 6. 运行test。 ``` ./test ``` 7. 运行覆盖率测试。 ``` make coverage ``` 执行这个命令将生成一个名为coverage.info的文件,其中包含了test.cpp文件的代码覆盖率信息。你可以使用lcov或genhtml工具生成HTML格式的报告。 ``` lcov --list coverage.info genhtml coverage.info --output-directory coverage-report ``` 打开coverage-report目录下的index.html文件,你就可以看到代码覆盖率报告了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值