参考:《Linux® Debugging and Performance Tuning: Tips and Techniques》 chapter 2
1. 待测代码如下:
/home/a/j/nomad2:cat sample.c #include <stdlib.h> #include <stdio.h> int main(argc, argv) int argc; char **argv; { int x, y; int arraysize; int **array; if (argc != 2) { printf("Usage: %s Enter arraysize value \n",argv[0]); exit(-1); } else { arraysize = atoi (argv[1]); if (arraysize <= 0) { printf("Array size must be larger than 0 \n"); exit(-1); } } array = (int **) malloc (arraysize*sizeof (int *)); printf("Creating an %d by %d array \n", arraysize, arraysize); if (array == NULL) { printf("Malloc failed for array size %d \n", arraysize); exit(-1); } for (x=0; x < arraysize; x++) { array[x] = (int *) malloc (arraysize*sizeof (int)); if (array[x] == NULL) { printf("Failed malloc for array size %d \n", arraysize); exit(-1); } } exit(0); }
2. 编译时使用参数-fprofile-arcs -ftest-coverage
/home/a/j/nomad2:gcc -g -fprofile-arcs -ftest-coverage sample.c /home/a/j/nomad2:ls a.out sample.c sample.gcno
3. 开始测试,使用不同的输入,然后依次用gcov命令查看测试覆盖率
/home/a/j/nomad2:./a.out 1000 Creating an 1000 by 1000 array /home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:57.89% of 19 sample.c:creating 'sample.c.gcov' /home/a/j/nomad2:./a.out 0 Array size must be larger than 0 /home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:68.42% of 19 sample.c:creating 'sample.c.gcov' /home/a/j/nomad2:./a.out Usage: ./a.out Enter arraysize value /home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:78.95% of 19 sample.c:creating 'sample.c.gcov' /home/a/j/nomad2:gcov 1 1.gcno:cannot open graph file /home/a/j/nomad2:./a.out 1 Creating an 1 by 1 array /home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:78.95% of 19 sample.c:creating 'sample.c.gcov' /home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:78.95% of 19 sample.c:creating 'sample.c.gcov'
查看产生的sample.c.gcov文件,发现还有一些代码没有覆盖。
1: 31: if (array == NULL) { #####: 32: printf("Malloc failed for array size %d \n", arraysize); #####: 33: exit(-1); -: 34: } 1001: 35: for (x=0; x < arraysize; x++) { 1000: 36: array[x] = (int *) malloc (arraysize*sizeof (int)); 1000: 37: if (array[x] == NULL) { #####: 38: printf("Failed malloc for array size %d \n", arraysize); #####: 39: exit(-1); -: 40: } -: 41: }
下面使用gdb帮助产生第31行的case,
/home/a/j/nomad2:gdb a.out GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu"... (gdb) list 4 5 6 int main(argc, argv) 7 int argc; 8 char **argv; 9 { 10 int x, y; 11 int arraysize; 12 int **array; 13 if (argc != 2) { (gdb) 14 printf("Usage: %s Enter arraysize value \n",argv[0]); 15 exit(-1); 16 17 } 18 else { 19 arraysize = atoi (argv[1]); 20 if (arraysize <= 0) { 21 printf("Array size must be larger than 0 \n"); 22 exit(-1); 23 } (gdb) 24 } 25 26 array = (int **) malloc (arraysize*sizeof (int *)); 27 28 printf("Creating an %d by %d array \n", arraysize, 29 arraysize); 30 31 if (array == NULL) { 32 printf("Malloc failed for array size %d \n", arraysize); 33 exit(-1); (gdb) 34 } 35 for (x=0; x < arraysize; x++) { 36 array[x] = (int *) malloc (arraysize*sizeof (int)); 37 if (array[x] == NULL) { 38 printf("Failed malloc for array size %d \n", 39 arraysize); 40 exit(-1); 41 } 42 } 43 (gdb) break 30 Breakpoint 1 at 0x400e77: file sample.c, line 30. (gdb) run 1 Starting program: /home/a/j/nomad2/linux/ch2/a.out 1 Creating an 1 by 1 array Breakpoint 1, main (argc=2, argv=0x7fffabb4b6d8) at sample.c:31 31 if (array == NULL) { (gdb) print array $1 = (int **) 0x605010 (gdb) set array=0 (gdb) step 32 printf("Malloc failed for array size %d \n", arraysize); (gdb) cont Continuing. Malloc failed for array size 1 Program exited with code 0377. (gdb) quit
查看覆盖率,
/home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:89.47% of 19 sample.c:creating 'sample.c.gcov'
查看文件sample.c.gcov,
/home/a/j/nomad2:cat sample.c.gcov -: 0:Source:sample.c -: 0:Graph:sample.gcno -: 0:Data:sample.gcda -: 0:Runs:5 -: 0:Programs:1 -: 1:#include <stdlib.h> -: 2:#include <stdio.h> -: 3: -: 4: -: 5: -: 6:int main(argc, argv) -: 7: int argc; -: 8: char **argv; 5: 9:{ -: 10: int x, y; -: 11: int arraysize; -: 12: int **array; 5: 13: if (argc != 2) { 1: 14: printf("Usage: %s Enter arraysize value \n",argv[0]); 1: 15: exit(-1); -: 16: -: 17: } -: 18: else { 4: 19: arraysize = atoi (argv[1]); 4: 20: if (arraysize <= 0) { 1: 21: printf("Array size must be larger than 0 \n"); 1: 22: exit(-1); -: 23: } -: 24: } -: 25: 3: 26: array = (int **) malloc (arraysize*sizeof (int *)); -: 27: 3: 28: printf("Creating an %d by %d array \n", arraysize, -: 29: arraysize); -: 30: 3: 31: if (array == NULL) { 1: 32: printf("Malloc failed for array size %d \n", arraysize); 1: 33: exit(-1); -: 34: } 1003: 35: for (x=0; x < arraysize; x++) { 1001: 36: array[x] = (int *) malloc (arraysize*sizeof (int)); 1001: 37: if (array[x] == NULL) { #####: 38: printf("Failed malloc for array size %d \n", -: 39: arraysize); #####: 40: exit(-1); -: 41: } -: 42: } -: 43: -: 44: 2: 45: exit(0); -: 46:}
只剩下最后的38行没有测到了,继续使用gdb辅助测试,
/home/a/j/nomad2:gdb a.out GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu"... (gdb) list 4 5 6 int main(argc, argv) 7 int argc; 8 char **argv; 9 { 10 int x, y; 11 int arraysize; 12 int **array; 13 if (argc != 2) { (gdb) 14 printf("Usage: %s Enter arraysize value \n",argv[0]); 15 exit(-1); 16 17 } 18 else { 19 arraysize = atoi (argv[1]); 20 if (arraysize <= 0) { 21 printf("Array size must be larger than 0 \n"); 22 exit(-1); 23 } (gdb) 24 } 25 26 array = (int **) malloc (arraysize*sizeof (int *)); 27 28 printf("Creating an %d by %d array \n", arraysize, 29 arraysize); 30 31 if (array == NULL) { 32 printf("Malloc failed for array size %d \n", arraysize); 33 exit(-1); (gdb) 34 } 35 for (x=0; x < arraysize; x++) { 36 array[x] = (int *) malloc (arraysize*sizeof (int)); 37 if (array[x] == NULL) { 38 printf("Failed malloc for array size %d \n", 39 arraysize); 40 exit(-1); 41 } 42 } 43 (gdb) 44 45 exit(0); 46 } (gdb) break 37 Breakpoint 1 at 0x400f01: file sample.c, line 37. (gdb) run 1 Starting program: /home/a/j/nomad2/linux/ch2/a.out 1 Creating an 1 by 1 array Breakpoint 1, main (argc=2, argv=0x7fff15222db8) at sample.c:37 37 if (array[x] == NULL) { (gdb) print x $1 = 0 (gdb) print array[0] $2 = (int *) 0x605030 (gdb) set array[0]=0 (gdb) step 38 printf("Failed malloc for array size %d \n", (gdb) cont Continuing. Failed malloc for array size 1 Program exited with code 0377. (gdb) quit
查看覆盖率,
/home/a/j/nomad2:gcov sample.c File 'sample.c' Lines executed:100.00% of 19 sample.c:creating 'sample.c.gcov'
查看文件sample.c.gcov,
/home/a/j/nomad2:cat sample.c.gcov -: 0:Source:sample.c -: 0:Graph:sample.gcno -: 0:Data:sample.gcda -: 0:Runs:6 -: 0:Programs:1 -: 1:#include <stdlib.h> -: 2:#include <stdio.h> -: 3: -: 4: -: 5: -: 6:int main(argc, argv) -: 7: int argc; -: 8: char **argv; 6: 9:{ -: 10: int x, y; -: 11: int arraysize; -: 12: int **array; 6: 13: if (argc != 2) { 1: 14: printf("Usage: %s Enter arraysize value \n",argv[0]); 1: 15: exit(-1); -: 16: -: 17: } -: 18: else { 5: 19: arraysize = atoi (argv[1]); 5: 20: if (arraysize <= 0) { 1: 21: printf("Array size must be larger than 0 \n"); 1: 22: exit(-1); -: 23: } -: 24: } -: 25: 4: 26: array = (int **) malloc (arraysize*sizeof (int *)); -: 27: 4: 28: printf("Creating an %d by %d array \n", arraysize, -: 29: arraysize); -: 30: 4: 31: if (array == NULL) { 1: 32: printf("Malloc failed for array size %d \n", arraysize); 1: 33: exit(-1); -: 34: } 1004: 35: for (x=0; x < arraysize; x++) { 1002: 36: array[x] = (int *) malloc (arraysize*sizeof (int)); 1002: 37: if (array[x] == NULL) { 1: 38: printf("Failed malloc for array size %d \n", -: 39: arraysize); 1: 40: exit(-1); -: 41: } -: 42: } -: 43: -: 44: 2: 45: exit(0); -: 46:}
至此,所有代码已被测试覆盖。
gcov可以参考http://gcc.gnu.org/onlinedocs/gcc/Gcov.html#Gcov