侧边栏壁纸
Linux入门自学网博主等级

每日学一条Linux命令,终成Linux大神

  • 累计撰写 725 篇文章
  • 累计创建 143 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Linux gcov命令教程:如何分析程序源代码的覆盖率(附实例详解和注意事项)

Linux gcov命令介绍

gcov命令是GNU Code Coverage,它是一个用来分析程序源代码的覆盖率的工具,可以帮助开发者找出程序中未被测试到的代码,提高代码的质量和可靠性。gcov命令可以显示每个源文件的总体覆盖率,以及每个函数和每行代码的覆盖率,还可以生成注释的源代码文件,显示每行代码被执行的次数。

Linux gcov命令适用的Linux版本

gcov命令是GNU编译器集合(GCC)的一部分,因此,只要安装了GCC,就可以使用gcov命令。GCC是Linux系统中最常用的编译器,大多数Linux发行版都自带了GCC,或者可以通过包管理器来安装GCC。例如,在CentOS 7中,可以使用以下命令来安装GCC:

[linux@bashcommandnotfound.cn ~]$ sudo yum install gcc

在CentOS 8中,可以使用以下命令来安装GCC:

[linux@bashcommandnotfound.cn ~]$ sudo dnf install gcc

Linux gcov命令的基本语法

gcov命令的基本语法格式如下:

gcov [选项] 源文件

其中,源文件是要分析的程序的源代码文件,必须是C、C++或Objective-C语言编写的。如果源文件没有指定扩展名,gcov命令会自动添加.c、.cc、.C、.cpp、.cp或.m扩展名。如果源文件有多个扩展名,gcov命令会按照上述顺序查找。

Linux gcov命令的常用选项或参数说明

gcov命令有很多选项或参数,可以用来控制分析的方式和输出的格式。以下是一些常用的选项或参数:

选项或参数说明
-a显示所有函数的覆盖率信息,而不仅仅是主程序中调用的函数
-b显示分支覆盖率信息,即每个条件语句的真假分支是否被执行
-c显示调用图覆盖率信息,即每个函数被调用的次数和调用者
-f显示每个函数的覆盖率信息,包括函数名、行号、执行次数和覆盖百分比
-l显示每行代码的覆盖率信息,包括行号、执行次数和源代码
-n不生成注释的源代码文件,只显示覆盖率信息
-o <目录>指定目标文件(即编译后的可执行文件)的目录,如果不指定,gcov命令会在当前目录或源文件所在的目录中查找
-p在输出的文件名中保留源文件的路径信息,而不是只显示文件名
-r删除辅助文件,即.gcda和.gcno文件,这些文件是编译时和运行时生成的,用来存储覆盖率数据
-s <目录>指定源文件的目录,如果不指定,gcov命令会在当前目录或目标文件所在的目录中查找
-u不显示未执行的函数和行的覆盖率信息

Linux gcov命令的实例

以下是一些使用gcov命令的实例,假设有一个名为hello.c的源文件,内容如下:

#include <stdio.h>

int foo(int x) {
  if (x > 0) {
    return x + 1;
  } else {
    return x - 1;
  }
}

int main() {
  printf("Hello, world!\n");
  printf("foo(10) = %d\n", foo(10));
  printf("foo(-10) = %d\n", foo(-10));
  return 0;
}

实例1:编译源文件并运行程序

为了使用gcov命令,需要在编译源文件时加上-g和-fprofile-arcs -ftest-coverage选项,这样可以生成目标文件、可执行文件和辅助文件。然后运行程序,这样可以收集覆盖率数据。例如:

[linux@bashcommandnotfound.cn ~]$ gcc -g -fprofile-arcs -ftest-coverage hello.c -o hello
[linux@bashcommandnotfound.cn ~]$ ./hello
Hello, world!
foo(10) = 11
foo(-10) = -11

实例2:显示总体覆盖率信息

使用gcov命令不带任何选项,可以显示源文件的总体覆盖率信息,包括文件名、行数、执行次数和覆盖百分比。例如:

[linux@bashcommandnotfound.cn ~]$ gcov hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'

这里可以看到,源文件的总体覆盖率是100%,即所有的代码行都被执行了。同时,gcov命令还生成了一个名为hello.c.gcov的文件,这是一个注释的源代码文件,可以用文本编辑器打开查看。

实例3:显示每个函数的覆盖率信息

使用gcov命令带上-f选项,可以显示每个函数的覆盖率信息,包括函数名、行号、执行次数和覆盖百分比。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -f hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'

Function 'foo'
Lines executed:100.00% of 5
Called 2 times

Function 'main'
Lines executed:100.00% of 4
Called 1 times

这里可以看到,源文件中有两个函数,foo和main,它们的覆盖率都是100%,即所有的函数体内的代码行都被执行了。同时,还可以看到,foo函数被调用了两次,main函数被调用了一次。

实例4:显示分支覆盖率信息

使用gcov命令带上-b选项,可以显示分支覆盖率信息,即每个条件语句的真假分支是否被执行。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -b hello.c
File 'hello.c'
Lines executed:100.00% of 9
Branches executed:100.00% of 4
Taken at least once:100.00% of 4
Calls executed:100.00% of 4
Creating 'hello.c.gcov'

这里可以看到,源文件中有四个分支,它们的覆盖率都是100%,即每个分支都被执行了至少一次。同时,还可以看到,源文件中有四个函数调用,它们的覆盖率也都是100%,即每个函数调用都被执行了。

实例5:显示每行代码的覆盖率信息

使用gcov命令带上-l选项,可以显示每行代码的覆盖率信息,包括行号、执行次数和源代码。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -l hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'

        -:    0:Source:hello.c
        -:    0:Graph:hello.gcno
        -:    0:Data:hello.gcda
        -:    0:Runs:
好的,我继续给你显示每行代码的覆盖率信息,包括行号、执行次数和源代码。例如:

```bash
[linux@bashcommandnotfound.cn ~]$ gcov -l hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'

        -:    0:Source:hello.c
        -:    0:Graph:hello.gcno
        -:    0:Data:hello.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <stdio.h>
        -:    2:
        -:    3:int foo(int x) {
        1:    4:  if (x > 0) {
        1:    5:    return x + 1;
        -:    6:  } else {
        1:    7:    return x - 1;
        -:    8:  }
        -:    9:}
        -:   10:
        1:   11:int main() {
        1:   12:  printf("Hello, world!\n");
        1:   13:  printf("foo(10) = %d\n", foo(10));
        1:   14:  printf("foo(-10) = %d\n", foo(-10));
        1:   15:  return 0;
        -:   16:}

这里可以看到,每行代码前面有一个数字,表示该行代码被执行的次数。如果该行代码没有被执行,或者不是有效的代码行,例如空行或注释行,那么数字就是-。这样可以很清楚地看到程序的执行流程和覆盖情况。

实例6:不生成注释的源代码文件

使用gcov命令带上-n选项,可以不生成注释的源代码文件,只显示覆盖率信息。这样可以节省磁盘空间,或者避免覆盖原有的源代码文件。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -n hello.c
File 'hello.c'
Lines executed:100.00% of 9

这里可以看到,gcov命令没有生成hello.c.gcov文件,只显示了总体覆盖率信息。

实例7:指定目标文件和源文件的目录

使用gcov命令带上-o和-s选项,可以指定目标文件和源文件的目录,如果它们不在当前目录或默认的目录中。例如,假设目标文件在~/obj目录中,源文件在~/src目录中,可以使用以下命令来分析覆盖率:

[linux@bashcommandnotfound.cn ~]$ gcov -o ~/obj -s ~/src hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating '~/src/hello.c.gcov'

这里可以看到,gcov命令在~/src目录中生成了注释的源代码文件。

实例8:在输出的文件名中保留源文件的路径信息

使用gcov命令带上-p选项,可以在输出的文件名中保留源文件的路径信息,而不是只显示文件名。这样可以避免不同目录中的同名文件产生冲突。例如,假设源文件在~/src/sub目录中,可以使用以下命令来分析覆盖率:

[linux@bashcommandnotfound.cn ~]$ gcov -p hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating '#home#user#src#sub#hello.c.gcov'

这里可以看到,gcov命令在当前目录中生成了一个名为#home#user#src#sub#hello.c.gcov的文件,其中#表示目录分隔符。

实例9:删除辅助文件

使用gcov命令带上-r选项,可以删除辅助文件,即.gcda和.gcno文件,这些文件是编译时和运行时生成的,用来存储覆盖率数据。如果不需要再分析覆盖率,可以使用这个选项来清理磁盘空间。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -r hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'
Removing 'hello.gcda'
Removing 'hello.gcno'

这里可以看到,gcov命令在生成注释的源代码文件后,删除了辅助文件。

实例10:显示调用图覆盖率信息

使用gcov命令带上-c选项,可以显示调用图覆盖率信息,即每个函数被调用的次数和调用者。这样可以更好地理解程序的结构和逻辑。例如:

[linux@bashcommandnotfound.cn ~]$ gcov -c hello.c
File 'hello.c'
Lines executed:100.00% of 9
Creating 'hello.c.gcov'

Function 'foo'
Lines executed:100.00% of 5
Called 2 times
Calls:
    1: foo (called by main)
    1: foo (called by main)

Function 'main'
Lines executed:100.00% of 4
Called 1 times
Calls:
    1: printf (called by main)
    1: printf (called by main)
    1: foo (called by main)
    1: printf (called by main)
    1: foo (called by main)

这里可以看到,每个函数后面有一个Calls:的列表,显示了该函数被哪些函数调用,以及调用的次数。

Linux gcov命令的注意事项

使用gcov命令时,需要注意以下几点:

  • gcov命令只能分析C、C++或Objective-C语言编写的程序,不能分析其他语言的程序。
  • gcov命令需要在编译源文件时加上-g和-fprofile-arcs -ftest-coverage选项,否则无法生成覆盖率数据。
  • gcov命令需要在运行程序后才能分析覆盖率,否则无法收集覆盖率数据。
  • gcov命令的输出文件名和格式可能随着GCC版本的变化而变化,因此,建议使用相同版本的GCC和gcov命令,或者使用-gcov-tool命令来兼容不同版本的覆盖率数据。
  • 如果在执行gcov命令时出现bash: gcov: command not found的错误,说明没有安装GCC或者没有将GCC的路径添加到环境变量中,可以使用以下命令来安装GCC或者查看GCC的路径:
[linux@bashcommandnotfound.cn ~]$ sudo yum install gcc # CentOS 7
[linux@bashcommandnotfound.cn ~]$ sudo dnf install gcc # CentOS 8
[linux@bashcommandnotfound.cn ~]$ which gcc

Linux gcov命令的相关命令

以下是一些和gcov命令相关的命令,可以用来辅助分析覆盖率或者生成更友好的报告:

0

评论区