C\C++ 覆盖率制作过程

 

1      简介

Linux下制作覆盖率需要以下几个步骤:

1、  编译程序时生成gcno文件;

2、  执行程序后生成gcda文件;

3、  使用lcov命令收集覆盖率信息并写入info文件;

4、  使用genhtml命令生成用于展示覆盖率的html文件。

2      生成gcno文件和gcda文件

2.1      生成方法

Gcnogcov note)文件和gcdagcov data)文件,用于生成覆盖率信息。Gcno文件在程序编译时生成,gcda文件在程序执行后生成。

       要在编译时生成gcno文件,运行后生成gcda文件,需要在编译链接过程对相关文件进行插桩,即在编译时添加编译选项-fprofile-arcs -ftest-coverage,在链接时加上选项-fprofile-arcs -ftest-coverage-lgcov。例如$gcc -fprolfile-arcs -ftest-coverage -lgcov -o test test.c

       当工程较复杂,编译链接分多步进行的时候,每一步都需要加上编译选项。例如:

       $gcc -fprofile-arcs -ftest-coverage -c test.c

       $gcc -fprofile-arcs -ftest-coverage -c demo.c

      $gcc -fprofile-arcs -ftest-coverage -lgcov -o Demo demo.o test.o

       正确的编译完毕后,在源程序文件的.o文件生成的地方同时生成了各程序文件的gcno文件(每一个被插桩的源程序文件都有一个gcno文件),然后正确链接生成可执行文件。运行可执行文件后,便在.gcno文件所在文件夹生成了对应的gcda文件(每一个被插桩的源程序文件都有一个gcda文件)。也可以通过修改环境变量GCOV_PREFIXGCOV_PREFIX_STRIP来确定gcda文件的生成位置。

2.2      gcda文件生成目录

可以通过修改环境变量,指定gcda文件的生成目录。例如:

Export GCOV_PREFIX="/home/ckf72739/gcov/output"

Export GCOV_PREFIX_STRIP="20"

前一个命令指定目录,后一个命令指定目录回跳的次数,linux一般20次就可以回跳到根目录。在命令行修改了上面两个环境变量后,执行可执行文件,便可在指定的目录下生成gcda文件。

但是最终在生成info文件时,gcno文件和gcda文件需要在同一个目录下才能生成info文件。

3      生成info文件

上面的过程可以生成gcnogcda文件,这两个文件包含了代码执行相关的覆盖率信息,接下来需要将这两个文件的信息进行整合,生成保存了整个程序完整覆盖率信息的info文件。

这个时候需要使用linux平台代码覆盖率测试工具GCOV的前端工具LCOV

3.1      Lcov常用选项说明

       Lcov的相关命令可以查看帮助:

       $lcov --help

       常用的选项:

3.1.1        -c, --capture                         

Capture coverage data   

获取覆盖率信息;

3.1.2        -d, --directory DIR

Use .da files in DIR instead of kernel

覆盖率文件生成需要的用户数据文件(gcnogcda文件)所在的目录,点号(.)表示当前目录;

3.1.3        -o, --output-file FILENAME

Write data to FILENAME instead of stdout

需要输出的覆盖率信息文件(info文件)。可以加目录,但目录必须存在,否则报错:

3.1.4        -t, --test-name NAME           

Specify test name to be stored with data

指定一个保存这些信息的test名字。这个名字体现在生成的info文件中的TN项;如果没有指定则为空。

3.1.5        -e, --extract FILE PATTERN     

Extract files matching PATTERN from FILE

过滤出指定的info文件中的匹配项。根据info文件中SF项进行匹配,提取PATTERN指定的文件的覆盖率信息。PATTERN必须精确到文件,如果需要提取某个目录下的所有源程序的覆盖率信息,需要加通配符星号(*

例如:

$ lcov -e demo.info ‘/home/ckf72739/gcov/LcovDemo/myprint.c’ -o demo1.info

提取demo.info文件中关于/home/ckf72739/gcov/LcovDemo/myprint.c的覆盖率信息,并保存到demo.info中;

$ lcov -e demo.info ‘/home/ckf72739/gcov/LcovDemo/*’ -o demo1.info

提取demo.info文件中关于/home/ckf72739/gcov/LcovDemo/目录下所有源程序的覆盖率信息。

3.1.6        -r, --remove FILE PATTERN      

Remove files matching PATTERN from FILE

删除指定的info文件中的匹配项,用法同-e选项。

3.1.7        -a, --add-tracefile FILE       

Add contents of tracefiles

合并info文件。可以把多个info文件合并到一起。例如:

$lcov -a demo1.info -a demo2.info -a demo3.info -o demo.info

demo1.infodemo2.infodemo3.info合并成一个demo.info文件。

3.1.8        -l, --list FILE                

List contents of tracefile FILE

显示出指定的info文件的覆盖率信息,如图:

3.2      Lcov举例

一个较完整的lcov命令如下

$ lcov -c -d . -o demo.info -t Demo

将在当前目录递归查找.gcno.gcda文件并在当前目录生成一个名为demo.infoinfo文件,其test nameDemo

3.3      Lcov命令流程

执行一个lcov命令,可以在命令行生成如下信息:

可以发现,lcov命令在当前目录下(包括子目录)查找.gcda文件,根据gcda文件去查找gcno文件,生成info文件。

Locv相关操作如果没有-o指定输出文件,lcov执行后的info文件数据将会输出在命令行。

4      生成html

根据lcov命令生成的info文件,可以通过genhtml命令生成html文件,将info文件中的覆盖率信息通过以html的形式直观的展示出来。

4.1      Genhtml常用选项

相关的genhtml命令可以通过查看帮助:

$genhtml --help

常用的选项:

4.1.1        -o, --output-directory OUTDIR    

Write HTML output to OUTDIR

生成的html文件的保存目录。因为生成的html文件很多,最好使用一个文件夹保存起来;

4.1.2        -t, --title TITLE                

Display TITLE in header of all pages

展示在html页面上的一个titlte

4.1.3        --legend                     

Include color legend in HTML output

加上该选项会在页面上显示如下内容:

4.1.4        --no-source

Do not create source code view

创建html文件时,不附带程序源文件(如.c文件)。Genhtml在生成html文件时会根据info文件中的SF指定的源文件路径去查找源文件,并附带到html文件中。如果没有源文件,可以添加这个选项,不附带源文件内容。

4.1.5        --(no-)sort                  

Enable (disable) sorted coverage views

能否对覆盖率显示进行排序。当选项为--no-sort时,生成的html文件无法对覆盖率显示进行排序;当选项为--sort,生成的html可以对覆盖率显示进行排序。默认的选项是—sort

如图,可以点击Line coverage后面的箭头对覆盖率进行排序显示:

排序后:

4.2      Genhtml举例

一个较完整的genhtml命令如下:

$genhtml demo.info -o html -t Demo -legend

该命令会根据当前目录下的demo.info文件生成html文件,保存在当前目录下的html文件夹中,并在页面显示Legend

5      总结

Linux下覆盖率生成过程总结如下:

1、  编译需要生成覆盖率的源程序文件:

$gcc -fprofile-arcs -ftest-coverage -c test.c

生成test.cgcno文件test.gcno

2、  链接生成可执行文件:

$gcc -fprofile-arcs -ftest-coverage -lgcov -o Demo test.o

生成可执行文件test

3、  运行可执行文件:

$./Demo

生成编译过程中加入了-fprofile-arcs -ftest-coverage选项的源程序文件对应的gcda文件,本例中生成test.gcda文件。

4、  生成info文件:

$lcov -c -d . -o demo.info

自动在当前目录查找gcnogcda文件,并生成demo.info文件。

5、  生成html文件:

$genhtml demo.info -o html

读取当前目录的demo.info文件,并生成html文件,生成的html文件保存在当前目录下的html目录下。

6      注意事项以及可能出现的问题

通过上面几个步骤,可以生成一个包含覆盖率信息的html。但需要注意以下事项:

6.1      中文路径问题

问题描述:源程序相关的目录中,如果包含有中文路径,这样的路径在生成的html文件上无法正确显示:

而且点击后无法进入相关链接:

解决方法:查看页面源文件,发现页面编码charset=ISO-8859-1,如果在页面“查看”选项中将“编码”选择为UTF-8,页面可以正确显示及点击。所以问题出现的原因是由genhtml命令生成html文件时的编码格式导致的。找到genhtml代码文件,使用$which genhtml命令可以定位出genhtml文件所在的位置(一般在/usr/bin/genhtml),进入文件查看代码,可以发现在生成html文件时使用了ISO-8859-1

ISO-8859-1修改为UTF-8,重新使用genhtml命令生成html文件,便可正常显示中文:

6.2      复杂工程编译选项问题

当工程较复杂时,需要多步编译链接时,需要在每一步都加上gcov相关的选项,如果不加入选项,就会出现如下问题:

       1$gcc -c test.c

          $gcc -fprofile-arcs -ftest-coverage -o test test.o

这样编译链接的过程中,不会生成任何gcno文件(同样,运行的过程中也不会生成gcda文件),无法生成覆盖率;

       2$gcc -fprofile-arcs -ftest-coverage -c test.c

          $gcc -o test test.o

          如上,在执行第二步的时候,将会报错:

       3$gcc -c test1.c

          $gcc -fprofile-arcs -ftest-coverage -c test2.c

          $gcc -fprofile-arcs -ftest-coverage -o test test1.o test2.o

如上,不会生成test1.c文件的gcno文件(同样在运行时也不会生成.gcda文件),这样在最后生成的覆盖率文件中,不会包含test1.c文件的覆盖率信息。当然,如果你不需要对test1.c文件生成覆盖率信息时,可以这么做。

6.3      -lgcov选项问题

在一些情况下,链接过程中不加入-lgcov选项,也可以正确链接生成可执行文件。但在某些情况下,需要链接gcov静态库(libgcov.a),就需要加上-lgcov选项,否则链接过程会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值