代码覆盖率测试gcov和lcov

简介:

gcov是什么?

  • 测试代码覆盖率的工具
  • 命令行方式控制台程序
  • GCC自带,伴随GCC一起发布
  • 可以和gprof一起工作估算代码执行时间

gcov能做什么?

  • 每一行代码的执行效率
  • 哪些代码确实被执行了
  • 每一段代码的耗时

如何使用?

1.编译生成.gcno与.gcda

大部分博客和老的官方manual会告诉你在编译的时候加两个参数 (包括man)-ftest-coverage -fprofile-arcs

但是在g++中会出现(gcc也会出现这种问题)

```
undefined reference to `__gcov_init'

```

因为作者在新版本中更改了编译选项,只需要从

```
 gcc xxx.o -o xxx --coverage
 gcc xxx.o -o xxx -lgcov
 gcc xxx.o -o xxx -fprofile-arcs
```

选一个就行,我选择的是--coverage, 记得要在编译以及链接的时候加,仅在链接的时候加不会生成相关的文件。编译后会生成.gcno文件,运行后会生成.gcda文件,这些是生成分析文件的源文件

.gcno包含了重建基本块图和相应的块的源码的行号的信息。
.gcda由编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息。

2. 生成报告

基本命令

gcov xxx.cc
生成 .cov文件,使用vim打开即可查看

选项

-b 分支覆盖
-a 所有block覆盖
-f 函数覆盖
        -:    0:Source:test.c
        -:    0:Graph:test.gcno
        -:    0:Data:test.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include
        -:    2:
        -:    3:int main (void)
        1:    4:{
        -:    5:    int i, total;
        -:    6:
        1:    7:    total = 0;
        -:    8:
       11:    9:    for (i = 0; i < 10; i++)
        1:    9-block  0
       10:    9-block  1
       11:    9-block  2
       10:   10:        total += i;
        -:   11:
        1:   12:    if (total != 45)
        1:   12-block  0
    #####:   13:        printf ("Failure/n");

代码来源于官方manual
-代表不必执行
数字n代表执行的次数

代表没有被执行过

3.可能的问题

生成文件失败

profiling:Cannot create directory
profiling:Selection.pb.gcda:Skip

Running the program will cause profile output to be generated. For each source file compiled with -fprofile-arcs, an accompanying .gcda file will be placed in the object file directory. That implicitly requires running the program on the same system as it was built or having the same absolute directory structure on the target system. The program will try to create the needed directory structure, if it is not already present.

在运行环境中没有相应的目录,所以不能生成.gcda文件,只要设一下GCOV_PREFIX和GCOV_PREFIX_STRIP环境变量。

GCOV_PREFIX:就是制定生成数据文件的前缀

GCOV_PREFIX_STRIP:就是需要在原来的路径上去掉多少层目录

假设执行路径“/home/a/b/c/d/”,

现在的运行路径是“/home/e/f/g/h/p/l”,那么执行如下命令即可
export GCOV_PREFIX=”/home/e/f/g/h/p/l”
export GCOV_PREFIX_STRIP=4
执行完这两行命令,就可以开始运行被测程序,然后正常退出,就会看到.gcda文件生成出来了。

.gcda文件生成了就可以用lcov直接处理它们,但是在处理的过程中遇到以下错误:

文件时间戳不一致

“stamp mismatch with graph file”
Processing Ads_Request.gcda
xxx.gcda:stamp mismatch with graph file
geninfo: WARNING: gcov did not create any files for xxx.gcda!

导致出现这个错误的原因是.gcda和.gcno文件并不是同一次build出来的,它们2个文件的时间戳就不一样,更新所有的.gcno文件即可。

Using gcov with GCC Optimization

https://gcc.gnu.org/onlinedocs/gcc/Gcov-and-Optimization.html#Gcov-and-Optimization

4.缺陷

gcov的每个源码的分析分散在对应的 .cov 文件中,
如果有N个源文件,基本上就很难快速分析处理了,最关键的是文本,也没有图表什么的

lcov

lcov是什么

  • 是GCOV图形化的前端工具
  • 是Linux Test Project维护的开放源代码工具,最初被设计用来支持Linux内核覆盖率的度量
  • 基于Html输出,并生成一棵完整的HTML树
  • 输出包括概述、覆盖率百分比、图表,能快速浏览覆盖率数据
  • 支持大项目,提供三个级别的视图:目录视图、文件视图、源码视图

安装

    sudo yun install lcov

使用lcov

lcov -t "xxx" -o xxx.info -c -d filepath
-t sets a test name
-o to specify the output file
-c to capture the coverage data
-d to specify the directory where the data files needs to be searched

生成前端显示
genhtml -o res xxx.info

res :生成的文件名
xxx.info : 上一步生成的信息文件

之后打开res下的index.html就可以浏览了

Reference

gcov—a Test Coverage Program

USING GCOV AND LCOV TO GENERATE BEAUTIFUL C++ CODE COVERAGE STATISTICS

目录
相关文章
|
easyexcel Java Maven
使用EasyExcel实现CSV文件读写功能,
使用EasyExcel实现CSV文件读写功能,顺手使用Idea创建SpringBoot工程集成swagger3
2721 0
使用EasyExcel实现CSV文件读写功能,
|
测试技术 Python
分支覆盖 (Branch Coverage)
分支覆盖 (Branch Coverage) 是一种软件测试覆盖率评估方法,能够测量代码中每个分支的执行情况,即代码中每个条件语句 (if-else 语句) 的所有可能分支是否都被执行过。
5020 1
|
存储 运维 Kubernetes
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
飞轮科技推出了 Doris 的 Kubernetes Operator 开源项目(简称:Doris Operator),并捐赠给 Apache 基金会。该工具集成了原生 Kubernetes 资源的复杂管理能力,并融合了 Doris 组件间的分布式协同、用户集群形态的按需定制等经验,为用户提供了一个更简洁、高效、易用的容器化部署方案。
1147 16
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
|
网络协议 算法 网络性能优化
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
计算机网络常见面试题(一):TCP/IP五层模型、应用层常见的协议、TCP与UDP的区别,TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议、ARP协议
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
977 6
|
JSON 数据格式
关于nlohmann::json的简单使用
关于nlohmann::json的简单使用
872 0
关于nlohmann::json的简单使用
|
消息中间件 监控 NoSQL
面试官:Redis主从集群切换数据丢失问题如何应对?
一、数据丢失的情况 异步复制同步丢失 集群产生脑裂数据丢失
|
测试技术 Linux C++
gtest单元测试框架介绍及简单使用
gtest单元测试框架介绍及简单使用