| 简介 在这章里,我们将会探讨gcov实用程序,并且了解一下如何使用gcov来帮助测试与支持软件配置与优化。我们将会了解如何使用gcov来构建软件,并且理解他所提供的各种数据类型。最后,我们将探讨当执行保险测试时要避免的事情。
 gcov是什么?
 我们从gcov可以为我们做什么开始。gcov是一个保险测试工具。当构建一个程序时,gcov会监视一个程序的执行,并且会标识出执行了哪一行源码,哪一行没有执行。更进一步,gcov可以标识出某一行源执行的次数,这对于执行配置很有用(程序在哪里花费了大多数的时间)。因为gcov可以分辨出哪一行没有执行,这对于保险测试工具是很有用的。
 我们将会讨论3.2.2版本的GNU编译器工具链的gcov的用法。
 准备镜像
 让我们来看一下如何为gcov的使用准备镜像。我们将会在接下来的部分提供更为详细的gcov的选项,所以这里只是作为一个介绍。我们将将会使用下面的所列的bubblesort的源码:
 1: #include
 2:
 3: void bubbleSort( int list[], int size )
 4: {
 5: int i, j, temp, swap = 1;
 6:
 7: while (swap) {
 8:
 9: swap = 0;
 10:
 11: for ( i = (size-1) ; i >= 0 ; i— ) {
 12:
 13: for ( j = 1 ; j list[j] ) {
 16:
 17: temp = list[j-1];
 18: list[j-1] = list[j];
 19: list[j] = temp;
 20: swap = 1;
 21:
 22: }
 23:
 24: }
 25:
 26: }
 27:
 28: }
 29:
 30: }
 31:
 32: int main()
 33: {
 34: int theList[10]={10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
 35: int i;
 36:
 37: /* Invoke the bubble sort algorithm */
 38: bubbleSort( theList, 10 );
 39:
 40: /* Print out the final list */
 41: for (i = 0 ; i 使用gcov程序
 现在我们准备好了我们的程序镜像了,让我们继续我们其余的部分。运行我们的程序就会生成我们在前面所讨论的数据集文件。然后我们使用我们希望进行检测的源码运行gcov程序。如下面所示:
 $ ./bubblesort
 ...
 $ gcov bubblesort.c
 100.00% of 17 source lines executed in file bubblesort.c
 Creating bubblesort.c.gcov.
 这告诉我们在我们的例子程序中所有的源码行至少都执行了一次。我们可以通过查看所生成的bubblesort.c.gcov文件来了解每一源码行所实际运行的次数。如下面所示:
 -: 0:Source:bubblesort.c
 -: 0:Graph:bubblesort.gcno
 -: 0:Data:bubblesort.gcda
 -: 0:Runs:1
 -: 0:Programs:1
 -: 1:#include
 -: 2:void bubbleSort(int list[],int size)
 1: 3:{
 1: 4: int i,j,temp,swap=1;
 4: 5: while(swap)
 -: 6: {
 2: 7: swap=0;
 22: 8: for(i=(size-1);i>=0;i--)
 -: 9: {
 110: 10: for(j=1;jlist[j])
 -: 13: {
 45: 14: temp=list[j-1];
 45: 15: list[j-1]=list[j];
 45: 16: list[j]=temp;
 45: 17: swap=1;
 -: 18: }
 -: 19: }
 -: 20: }
 -: 21: }
 1: 22:}
 -: 23:int main()
 1: 24:{
 1: 25: int theList[10]={10,9,8,7,6,5,4,3,2,1};
 -: 26: int i;
 -: 27: /*Invoke the buble sort algorithm*/
 1: 28: bubbleSort(theList,10);
 -: 29:
 -: 30: /*print out the final list*/
 11: 31: for(i=0;i查看分支概率
 我们也可以使用-b选项来查看程序的分支数据。这个选项会输出程序中每一个分支的频度与相应的摘要。例如,我们使用-b选项来执行gcov命令:
 $ gcov -b bubblesort.c
 100.00% of 17 source lines executed in file bubblesort.c
 100.00% of 12 branches executed in file bubblesort.c
 100.00% of 12 branches taken at least once in file bubblesort.c
 100.00% of 2 calls executed in file bubblesort.c
 Creating bubblesort.c.gcov.
 所生成的bubblesort.c.gcov文件如下所示。
 -: 0:Source:bubblesort.c
 -: 0:Graph:bubblesort.gcno
 -: 0:Data:bubblesort.gcda
 -: 0:Runs:1
 -: 0:Programs:1
 -: 1:#include
 -: 2:void bubbleSort(int list[],int size)
 function bubbleSort called 1 returned 100% blocks executed 100%
 1: 3:{
 1: 4: int i,j,temp,swap=1;
 4: 5: while(swap)
 branch 0 taken 67%
 branch 1 taken 33% (fallthrough)
 -: 6: {
 2: 7: swap=0;
 22: 8: for(i=(size-1);i>=0;i--)
 branch 0 taken 91%
 branch 1 taken 9% (fallthrough)
 -: 9: {
 110: 10: for(j=1;jlist[j])
 branch 0 taken 50% (fallthrough)
 branch 1 taken 50%
 -: 13: {
 45: 14: temp=list[j-1];
 45: 15: list[j-1]=list[j];
 45: 16: list[j]=temp;
 45: 17: swap=1;
 -: 18: }
 -: 19: }
 -: 20: }
 -: 21: }
 1: 22:}
 -: 23:int main()
 function main called 1 returned 100% blocks executed 100%
 1: 24:{
 1: 25: int theList[10]={10,9,8,7,6,5,4,3,2,1};
 -: 26: int i;
 -: 27: /*Invoke the buble sort algorithm*/
 1: 28: bubbleSort(theList,10);
 call 0 returned 100%
 -: 29:
 -: 30: /*print out the final list*/
 11: 31: for(i=0;i
 2:
 3: int main()
 4: 1 {
 5: 1 int a=1, b=2;
 6:
 7: 1 if (a == 1) {
 8: 1 printf("a = 1\n");
 9: } else {
 10: ###### printf("a != 1\n");
 11: }
 12:
 13: 1 if (b == 1) {
 14: ###### printf("b = 1\n");
 15: } else {
 16: 1 printf("b != 1\n");
 17: }
 18:
 19: 1 return 0;
 20: }
 当这个程序运行时,gcov实用程序也会向标准输出输出相应的信息。他会显示可能执行的源码行的行数以及实际运行的百分比。
 $ gcov incomptest.c
 77.78% of 9 source lines executed in file incomptest.c
 Creating incomptest.c.gcov.
 $
 如果我们的例子程序有多个函数,我们可以通过使用-f选项来查看每一个函数的执行情况。如下面的我们以bubbleSort程序所进行的演示:
 $ gcov -f bubblesort.c
 100.00% of 11 source lines executed in function bubbleSort
 100.00% of 6 source lines executed in function main
 100.00% of 17 source lines executed in file bubblesort.c
 Creating bubblesort.c.gcov.
 $
 gcov可用的选项
 gcov程序调用的格式为:
 gcov [options] sourcefile
 其可用的选项如下:
 选项 目的
 -v,-version 打印版本信息
 -h,-help 打印帮助信息
 -b,-branch-probabilities向输出文件输出分支频度
 -c,-branch-counts 打印分支计数而不是分支频度
 -n,-no-output 不创建gcov输出文件
 -l,-long-file-names 创建长文件名
 -f,-function-summaries 打印每一个函数的概要
 -o,-object-directory .bb,.bbg,.da文件存放的目录
 从上面这个表中,我们可以看到一个单个字符选项,以及一个长选项。当从命令行中使用gcov命令时短选项是比较有用的,但是当gcov是Makefile的一个部分时,应使用长选项,因为这更易于理解。
 当了解gcov程序的版本信息时,可以使用-v选项。因为gcov是与一个指定的编译器工具链联系在一起的(实际上是由gcc工具链而构建的),gcc版本与gcov的版本是相同的。
 gcov程序的简介以及选项帮助可以用-h选项来进行显示。
 
 undefined reference to _gcov_init问题
 On the link line you have to either
 a) add -fprofile-arcs
 b) add -lgcov
 
 |