简介 在这章里,我们将会探讨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
|