使用gcov提高代码测试覆盖率

参考:《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

你可能感兴趣的:(list,测试,null,Graph,performance,debugging)