使用Gcov统计C、C++代码的覆盖率

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

一、Gcov的介绍GCOV是一个GNU的本地覆盖测试工具,伴随GCC发布,配合GCC共同实现对C或者C++文件的语句覆盖和分支覆盖测试。是一个命令行方式的控制台程序。需要工具链的支持。当构建一个程序时,gcov会监视一个程序的执行,并且会标识出执行了哪一行源码,哪一行没有执行。更进一步,gcov可以标识出某一行源执行的次数,这对于执行配置很有用(程序在哪里花费了大多数的时间)。LCOV是GCOV图形化的前端工具,是LinuxTestProject维护的开放源代码工具,最初被设计用来支持Linux内核覆盖率的度量基于Html输出,并生成一棵完整的HTML树输出包括概述、覆盖率百分比、图表,能快速浏览覆盖率数据支持大项目,提供三个级别的视图:目录视图、文件视图、源码视图。二、Gcov原理和使用基本概念1、基本快基本快可以认为是一组顺序执行的指令组成的程序块,基本的特点就是当这个基本快的第一条命令执行了,那么该快中其他的语句也要执行,始终会保持一个基本快中所有的指令执行的次数是相同的。一般情况下,一个基本快是由一个跳转指令结束。如果一段指令中出现了多个跳转指令,也就是分支语句,那么就会被认为是不同的基本快。2.跳转跳转就是从一个基本快运行到另外一个基本快的一行指令。从一个基本快到另外一个基本快的动作就不叫做一个跳转,实际上跳转和基本快构成了统计代码覆盖的基本结构。要想知道程序中的每个语句和分支的执行次数,就必须知道每个基本快和跳转的执行次数。3.程序流图如果把基本块作为一个节点,这样一个函数中的所有基本块就构成了一个有向图。,要想知道程序中的每个语句和分支的执行次数,就必须知道每个基本块和跳转的执行次数。根据图论可以知道有向图中基本块的入度和出度是相同的,所以只要知道了部分的基本块或者跳转大小,就可以推断所有的大小。这里选择由跳转的执行次数来推断基本快的执行次数。以下是针对某个函数的程序流图:2.2.1原理简介GCOV是一个纯软件的覆盖测试工具,被测程序的预处理,插桩和编译成目标文件三个步骤由GCC一次完成。GCOV本身只负责数据处理和结果显示,下图是GCOV的工作原理。gcov工作原理从左图可以看出,GCOV统计覆盖率主要包括三个阶段:编译阶段:如下一段C语言代码(test.c):#includeintmain(void){inti,total;total=0;for(i=0;i5;i++){if(i%2==0){printf(Thenumberis%disnotodd,i);}else{printf(Thenumberis%disodd,i);}total+=i;}if(total!=45)printf(Failure\n);elseprintf(Success\n);return0;}加入编译选项执行:gcc–otest–fprofile-arcs–ftest-coveragetest.c编译后首先会生成.gcno文件。该文件是由-ftest-coverage产生的,它包含了重建基本块图和相应的块的源码的行号的信息。编译完成后,运行该程序:./test执行后生成.gcda文件。.gcda是由加了-fprofile-arcs编译参数的编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息。Gcov就是利用上面生成的两个文件.gcda和.gcno进行代码覆盖率的统计。这时候可以通过执行gcovhello.c统计总体的代码覆盖率生成gcda文件之后执行命令gcovtest.c就会在屏幕上打印出测试的总体覆盖率。$gcovtest.cFile‘test.c’已执行的行数:90.91%(共11行)test.c:正在创建‘test.c.gcov’并同时生成文件“test.c.gcov”,然后用vi打开就可以看见哪行被覆盖掉了。$vitest.c.gcov-:0:Source:test.c-:0:Graph:test.gcno-:0:Data:test.gcda-:0:Runs:1-:0:Programs:1-:1:#include-:2:1:3:intmain(void)-:4:{-:5:inti,total;1:6:total=0;6:7:for(i=0;i5;i++){5:8:if(i%2==0){3:9:printf(Thenumberis%disnotodd,i);-:10:}-:11:else{2:12:printf(Thenumberis%disodd,i);-:13:}5:14:total+=i;-:15:}-:16:1:17:if(total!=45)1:18:printf(Failure\n);-:19:else#####:20:printf(Success\n);1:21:return0;-:22:}~看一下内容,第一列出显示出每一行代码的覆盖执行次数。比如第7行代码执行了6次,for语句执行了6次,前5次进入循环内部。第6次因为判断为假,退出了循环。因此也退出了第8行的if语句只运行了5次。其中有写语句标识了”-“,表示不进入统计,这些只是并不会影响代码的简单C源码元素。我们也可以使用-b选项来查看程序的分支数据。这个选项会输出程序中每一个分支的频度与相应的摘要。例如,我们使用-b选项来执行gcov命令:执行gcov–btest.c会重新生成test.c.gcov。打开生成的文件可以清晰的看出哪些分支被执行了,执行的次数,已经执行覆盖的百分比统计。$vitest.c.gcov-:0:Source:test.c-:0:Graph:test.gcno-:0:Data:test.gcda-:0:Runs:1-:0:Programs:1-:1:#include-:2:functionmaincalled1returned100%blocksexecuted90%1:3:intmain(void)-:4:{-:5:inti,total;1:6:total=0;6:7:for(i=0;i5;i++){branch0被执行83%branch1被执行17%(fallthrough)5:8:if(i%2==0){branch0被执行60%(fallthrough)branch1被执行40%3:9:printf(Thenumberis%disnotodd,i);call0返回了100%-:10:}-:11:else{2:12:printf(Thenumberis%disodd,i);call0返回了100%-:13:}5:14:total+=i;-:15:}-:16:1:17:if(total!=45)branch0被执行100%(fallthrough)branch1被执行0%1:18:printf(Failure\n);call0返回了100%-:19:else#####:20:printf(Success\n);call0从未被执行1:21:return0;-:22:}三、使用lcov生成统计报告Lcov则是上的gcov结果展现的一个前端,可以将覆盖率信息转换成html展现Makefile在编译和link环节都加入-fprofile-arcs-ftest-coverage选项,收集覆盖率数据生成app.info文件。执行lcov--directory.--capture--output-file./test.info生成test.info文件使用gcovhtml将生成的代码统计信息转换成html格式genhtml-o./result./test.info生成的result目录就包含了html格式的报告。将该报告在浏览器中打开就形成了可视化的代码覆盖率的信息。可以点开目录,展示具体的代码覆盖情况

1 / 6
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功