使用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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值