覆盖率工具gcov和lcov的使用

1.概述

        此文档用来说明覆盖率工具gcov和lcov的使用方法,使用中遇到的问题以及解决方法。

2.gcov的使用

        gcov 是一个与 GCC配套的命令行工具,用于测量和报告程序的测试覆盖率。它是 GNU 二进制利用工具 binutils 的一部分,专门设计用于分析 C 和 C++ 程序的测试情况

2.1.gcov的安装

        当你安装GCC编译器时,gcov 作为其测试套件的一部分,也会被安装。

2.2.使用示例

        ①添加编译选项:

gcc -fprofile-arcs -ftest-coverage -o example example.c

        ②执行程序:

./example

        ③生成报告:

gcov example.c

2.3.对每一步的详细说明

2.3.1.添加编译选项

        需要添加两个编译选项,分别是 -fprofile-arcs和 -ftest-coverage。

        -fprofile-arcs 选项会生成以 .gcno 结尾的文件,此文件包含了编译器在编译过程中产生的控制流图信息,它是 gcov 工具生成覆盖率报告所需的。在编译之后会为每一个编译包含的 .c 文件都生成一个以 .gcno 结尾的文件。

        -ftest-coverage 选项会生成 .gcda 文件。这个文件记录了程序运行时的覆盖率数据,即哪些代码被执行了。在运行编译之后的可执行程序后会为每个编译包含的 .c 文件生成一个 .gcda结尾的文件。

2.3.2.执行编译后的可执行程序

        执行程序后,如果添加了前面两个编译选项,会为每一个 .c 文件生成相应的 .gcda 文件用来记录每个文件的覆盖率信息。

        如果是在其他主机环境运行,会在运行主机生成对应源文件的.gcda文件,此文件生成的位置为可执行程序编译时所在的目录,需要将其移到编译目录的对应源文件位置,再执行gcov或lcov生成覆盖率报告。

2.3.3.生成覆盖率报告

        使用 `gcov + 程序源文件` 可以生成对应源文件的覆盖率报告,覆盖率报告以 .c.gcov 结尾。

        覆盖率报告示例:

      -:    1:#include <stdio.h>			// ‘-’表示该行未被执行,1表示源文件行号
      -:    2:#include <stdbool.h>
      -:    3:
      1:    4:bool isEven(int number) {return number % 2 == 0;}   // ‘1’表示该行被执行了一次
  #####:    5:bool isPositive(int number) {return number > 0;}	// ‘#####’表示该行未被执行
      1:    6:int main() {
      1:    7:    int number = 43;    //1* 表示这个 if 语句至少在一次执行中被满足,并且至少有一个分支(if 或 else)被执行了一次
     1*:    8:    if (isEven(number) && isPositive(number)) {		
  #####:    9:        printf("The number is a positive even number.\n");
      -:   10:    } else {
      1:   11:        printf("The number is not a positive even number.\n");
      -:   12:    }
      1:   13:    return 0;
      -:   14:}

2.4.gcov的选项

2.4.1.显示每个函数覆盖率

gcov -f example.c

2.4.2.输出分支的执行覆盖率

        此选项会在.c.gcov中包含函数执行的覆盖率等信息。

gcov -b example.c

    3.lcov的使用

            lcov 是一个与 gcov 配套使用的开源工具,用于收集和可视化分析由 gcov 生成的代码覆盖率数据,它提供了比 gcov 更高级的分析和报告功能,包括生成易于阅读的 HTML 格式的覆盖率报告。

    3.1.lcov的安装

    从github下载源码进行安装或者直接执行以下命令。

    git clone https://github.com/linux-test-project/lcov.git

    网址下载:

    https://github.com/linux-test-project/lcov/

    将下载的lcov-2.1.tar.gz 进行解压,直接执行make install进行安装。

    安装依赖库:

    yum install -y perl-Capture-Tiny perl-DateTime perl-Digest-MD5 
    yum install -y perl-TimeDate perl-Devel-Cover perl-Module-Load-Conditional

    3.2.使用示例

            ①添加编译选项:        

    gcc -fprofile-arcs -ftest-coverage -o example example.c

            ②执行程序:

    ./example

            ③生成html报告:

    lcov --capture --directory . --output-file coverage.info
    
    genhtml --show-proportion coverage.info --output-directory out

    3.3.genhtml选项

    3.3.1生成黑色主题的html网页

    genhtml --dark-mode coverage.info --output-directory out

    3.3.2.页面显示函数覆盖率

    genhtml --show-proportion coverage.info --output-directory out

    3.3.3.页面显示颜色图例

    genhtml --legend --show-proportion  coverage.info --output-directory out

    3.3.4.生成自定义标题

    genhtml -t "测试覆盖率示例"  --show-proportion  coverage.info --output-directory out

    3.4.查看html文件

    将genhtml生成的out目录下载下来,在目录中点击index.html使用浏览器打开即可。

    3.4.1.整体的覆盖率

    3.4.2.每个文件的覆盖率

    3.4.3.文件覆盖率详情

    3.4.4.查看函数覆盖率信息

    4.使用时发现的问题

    4.1.死循环程序无法生成报告

            使用了死循环的程序,在生成覆盖率报告时,使用ctrl+c 结束程序后,覆盖率报告并没有生成gcda文件,自然也无法生成gcov覆盖率报告文件。

    4.1.1.解决方法

            使用信号结束程序时,需要对信号进行捕获处理,增加处理函数,这样在结束程序时才能正常生成覆盖率报告。例如以下程序增加对ctrl+c信号的处理:

    static void sigCtrlcHandle(int sig)
    {
        exit(sig);
    }
    
    static int setSigHandle(void)
    {
        struct sigaction act;
    
        sigfillset(&act.sa_mask);
        act.sa_flags = 0;
    
        act.sa_handler = sigCtrlcHandle; 
        sigaction(SIGINT, &act, 0);	//处理ctrl+c的信号
    }

    通过增加上述代码,当执行 Ctrl+C退出程序时,可以生成gcda文件,在执行gcov命令生成覆盖率文件了。

    4.2.头文件中定义的方法覆盖率查看

            如果需要查看头文件中方法的覆盖率,需要使用gcov查看相应的包含此头文件的.c文件的覆盖率,直接查看.h头文件无法查看到代码覆盖率。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值