编译链接实战(22)C/C++代码覆盖率统计报告生成

news2024/9/20 0:53:49

Gcov 查看代码覆盖率

文章目录

    • GCOV 工具简介
    • gcov 使用
    • lcov
    • 相关编译选项

GCOV 工具简介

gcov是一个测试代码覆盖率的工具,它是 gcc 自带的查看代码覆盖率的工具。

与GCC结合使用,可以分析您的程序以帮助创建更高效、运行更快的代码,并发现程序中未经测试的部分。您可以将gcov作为性能分析工具使用,以帮助发现优化工作对代码产生最佳效果的位置。您还可以将gcov与另一种性能分析工具gprof一起使用,以评估代码的哪些部分使用了最多的计算时间。

性能分析工具可以帮助您分析代码的性能。使用像gcov或gprof这样的分析器,您可以找出一些基本的性能统计数据,例如:

  • 每行代码执行了多少次
  • 实际执行了哪些代码行
  • 每个代码段使用了多少计算时间

一旦您了解了编译后的代码如何工作,就可以查看每个模块,看看哪些模块应该进行优化。gcov可以帮助您确定在哪里进行优化工作。

软件开发人员还结合测试套件使用覆盖率测试,以确保软件实际上足够好,可以发布。测试套件可以验证程序按预期工作;覆盖率程序测试测试套件执行了程序的多少部分。然后,开发人员可以确定需要向测试套件中添加哪些类型的测试用例,以创建更好的测试和更好的最终产品。

如果您计划使用gcov,应该在不优化的情况下编译代码,因为通过将一些代码行组合成一个函数的优化,可能无法为您提供寻找“热点”所需的信息,即代码使用大量计算时间的地方。同样,因为gcov按行(最低分辨率)累积统计数据,它最适合一种编程风格,即每行只放置一个语句。如果您使用复杂的宏,这些宏展开为循环或其他控制结构,统计数据就不那么有用——它们只报告宏调用出现的行。如果您的复杂宏表现得像函数,您可以用内联函数替换它们来解决这个问题。

gcov创建一个名为sourcefile.gcov的日志文件,指示源文件sourcefile.c的每一行执行了多少次。您可以将这些日志文件与gprof一起使用,以帮助微调程序的性能。gprof提供您可以与从gcov获得的信息一起使用的计时信息。

gcov仅适用于用GCC编译的代码。它与任何其他性能分析或测试覆盖机制不兼容。

使用效果如下图所示:

img

程序运行完成后,可以查看每个文件的代码覆盖率情况,上面报告中展示了每个文件的行覆盖率,函数覆盖率和分支覆盖率。

打开一个文件的覆盖率报告,页面对开始有文件的基本信息描述,以 FreeRTOS 的 task.c 为例,它的有效代码行数为 921 行,共 24 个函数(几千行的文件其实也没多少嘛~)

img

img

在覆盖率的正文,有该文件的完整代码,并用不同颜色进行高亮标注了:

  • 蓝色表示运行被覆盖的代码,前面的数字表示代码执行次数。
  • 红色表示未执行代码。
  • 白色表示无效代码,包括注释,空行和未编译代码。

gcov 使用

使用 gcov 的流程非常简单,只需要三步即可。 下面以 hello world 为例,展示生成覆盖率报告。

代码如下:

//main.c

#include <stdio.h>

int main(int argc, char **argv) {
    printf("hello world\n");
    return 0;
}

第一步: 添加编译参数 -fprofile-arcs -ftest-coverage

在所需要的生产覆盖率的文件中,添加编译参数,编译代码生成目标文件,同时会生成 *.gcno 文件,其中包含文件的行号等信息。
GCC C/C++代码覆盖率统计生成

gcc main.c -c -fprofile-arcs -ftest-coverage -o main.o
ls # 输出文件列表:
# main.c  main.gcno  main.o
gcc main.o -lgcov -o main

第二步: 添加链接参数 -lgcov ,运行程序

运行程序后,会生成一个 *.gcda 文件,里面包含代码执行次数等数据。

gcc main.o -lgcov -o main
# 运行程序
./main
# hello world
ls # 输出文件列表:
#main  main.c  main.gcda  main.gcno  main.o

第三步: 输出覆盖率报告 使用下面命令输出覆盖率报告

# 第一次使用前安装工具
sudo apt install lcov

# 生成覆盖率文本报告
lcov -c -d . -o test.info --rc lcov_branch_coverage=1 
# 生成覆盖率网页报告
genhtml --branch-coverage -o result test.info 

输入上面两/三条命令后在,执行命令的文件路径可以看到一个 result 文件夹,在里面就是对应的网页覆盖率报告。

img

用浏览器打开 index.html 就可以看到最开始展示的覆盖率信息了。

lcov

lcov 是 GCC 覆盖率测试工具 gcov 的图形化前端,用于收集多个源文件的行、函数和分支覆盖率数据,并创建包含覆盖信息的 HTML 页面。它还添加了概览页面,以便在文件结构中进行方便的导航。

使用 lcov 收集覆盖率数据,并使用 genhtml 创建 HTML 页面。覆盖率数据可以从当前正在运行的 Linux 内核或用户空间应用程序中收集。要做到这一点,您需要完成以下准备步骤:

  1. 收集覆盖率数据:首先,使用 lcov 工具来收集代码的覆盖率数据。您可以通过在编译时添加 -ftest-coverage-fprofile-arcs 选项来生成覆盖率数据的中间文件。然后,通过运行应用程序或测试套件来执行代码路径,以便生成覆盖率数据。
  2. 生成 HTML 页面:接下来,使用 genhtml 工具将收集到的覆盖率数据转换为 HTML 页面。genhtml 将分析覆盖率数据,并生成带有覆盖信息注释的源代码的 HTML 页面,以及用于导航文件结构的概览页面。

这些工具的结合使用使得开发人员能够更直观地查看代码的覆盖情况,从而更好地理解测试覆盖范围和质量。通过分析生成的 HTML 页面,开发人员可以识别哪些部分的代码需要更多的测试覆盖,以及哪些部分已经得到了良好的覆盖。

总的来说,lcov 和 genhtml 工具的组合为开发人员提供了一种强大的方式来收集和可视化代码覆盖率数据,从而帮助他们更好地进行测试和代码质量管理。如果您需要进一步解释或有其他问题,请随时告诉我,我很乐意为您提供帮助。

关键选项:

   -r tracefile pattern
   --remove tracefile pattern
          Remove data from tracefile.

          Use this switch if you want to remove coverage data for a particular set of files from a tracefile. Additional command line parameters will be interpreted as  shell  wildcard  patterns  (note
          that they may need to be escaped accordingly to prevent the shell from expanding them first).  Every file entry in tracefile which matches at least one of those patterns will be removed.

          Note: The pattern must be specified to match the absolute path of each source file.

          The result of the remove operation will be written to stdout or the tracefile specified with -o.

          Only one of  -z, -c, -a, -e, -r, -l, --diff or --summary may be specified at a time.

   --exclude pattern
          Exclude source files matching pattern.

          Use this switch if you want to exclude coverage data for a particular set of source files matching any of the given patterns. Multiple patterns can be specified by  using  multiple  --exclude
          command line switches. The patterns will be interpreted as shell wildcard patterns (note that they may need to be escaped accordingly to prevent the shell from expanding them first).

          Note: The pattern must be specified to match the absolute path of each source file.

          Can be combined with the --include command line switch. If a given file matches both the include pattern and the exclude pattern, the exclude pattern will take precedence.
 --include pattern
              Include source files matching pattern.

              Use this switch if you want to include coverage data for only a particular set of source files matching any of the given patterns. Multiple patterns can be specified by using  multiple  --in‐
              clude command line switches. The patterns will be interpreted as shell wildcard patterns (note that they may need to be escaped accordingly to prevent the shell from expanding them first).

              Note: The pattern must be specified to match the absolute path of each source file.
       --rc keyword=value
              Override a configuration directive.

              Use  this option to specify a keyword=value statement which overrides the corresponding configuration statement in the lcovrc configuration file. You can specify this option more than once to
              override multiple configuration statements.  See lcovrc(5) for a list of available keywords and their meaning.

相关编译选项

  • -fprofile-arcs

该选项用于在程序执行时对程序流程弧进行插装,记录每个分支和调用被执行的次数以及它们被取或返回的次数。对于支持具有优先级支持的构造函数的目标,剖析能够正确处理构造函数、析构函数以及用作全局变量类型的类的C++构造函数(和析构函数)。

当编译后的程序退出时,会将这些数据保存到名为 auxname.gcda 的文件中,每个源文件都会生成一个相应的 .gcda 文件。这些数据可以用于基于profile-directed 的优化(例如 -fbranch-probabilities),或者用于测试覆盖率分析(例如 -ftest-coverage)。每个目标文件的 auxname 是从输出文件的名称生成的,如果显式指定了输出文件并且它不是最终可执行文件,则 auxname 会采用源文件的基本名称。在这两种情况下,任何后缀都会被移除(例如对于输入文件 dir/foo.cauxnamefoo.gcda;对于指定为 -o dir/foo.o 的输出文件,auxnamedir/foo.gcda)。

简而言之,通过使用 -fprofile-arcs 编译选项,您可以收集程序在执行过程中的代码覆盖率和执行路径信息,从而可以进行优化或测试覆盖率分析。

  • –coverage

这个选项是 -fprofile-arcs -ftest-coverage(编译时)和 -lgcov(链接时)的同义词。主要做了以下工作:

  1. 使用 -fprofile-arcs 和优化、代码生成选项来编译源文件。对于测试覆盖率分析,还需额外加上 -ftest-coverage 选项。并不需要对程序中的每个源文件都进行剖析。
  2. 另外使用 -fprofile-abs-path 选项来编译源文件,以在 .gcno 文件中创建绝对路径名。这样可以让 gcov 在项目中的编译发生在不同工作目录的情况下正确找到源文件。
  3. 使用 -lgcov-fprofile-arcs(后者暗含了前者)来链接您的目标文件。
  4. 运行程序以生成弧剖析信息。可以多次重复这个过程。您可以同时运行多个程序实例,只要文件系统支持锁定,数据文件就会被正确地更新。除非启用了严格的 ISO C 方言选项,否则 “fork” 调用会被检测并正确处理,而不会重复计数。
  5. 对于基于profile-directed的优化,需要使用相同的优化和代码生成选项再次编译源文件,并加上 -fbranch-probabilities
  6. 对于测试覆盖率分析,使用 gcov 从 .gcno.gcda 文件中生成人类可读的信息。请参考 gcov 文档以获取更多信息。
    特殊环境使用注意点:

在正常使用 gcov 是非常简单的,但是在特殊项目中使用 gcov 需要注意一些坑,否则就会跟我一样掉进去出不来。。。

  • 链接时,会在 .init_array 段插入 __gcov_init() 函数,该函数在 main 运行之前初始化 gcov 运行环境。
  • 如果修改过链接脚本,注意 .init_array 的全局构造函数是否执行成功。
  • 和上面一样,链接时,会在全局析构函数中插入 __gcov_exit() 函数,在 main 执行结束后,输出 *.gcda 文件。
  • 如果程序为异常退出,则不会生成 *.gcda 文件,此时需要在代码适当位置插入 __gcov_flush() 函数,将文件进行保存。
  • 默认状态 *.gcda 文件和 *.gcno 文件所在文件夹相同,如果需要修改输出文件夹,可通过添加环境变量:GCOV_PREFIX 和 GCOV_PREFIX_STRIP
  • GCOV_PREFIX_STRIP=16 , 为将原有路径裁剪16个文件夹。 GCOV_PREFIX=/home/tester/build , 为将裁剪后的路径添加前缀 例如:上文中默认 main.gcda 所在的文件 /home/tester/main.gcda,裁剪后添加前缀后变为/home/tester/build/main.gcda

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1482445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 之压缩与解压相关命令的基础用法

目录 1、zip 与 unzip 2、gzip 命令 3、tar 命令 1、zip 与 unzip 在桌面新建一个文件和文件夹用于测试 在 test 目录下有一个 1.txt 文件 我们使用 zip 命令对其压缩 用法&#xff1a; zip 自定义压缩包名 被压缩文件路径位置 zip myon.zip 1.txt 因为我们这里就是在 …

数据库管理-第157期 Oracle Vector DB AI-08(20240301)

数据库管理157期 2024-03-01 数据库管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09;1 创建示例向量2 查找最近向量3 基于向量簇组的最近向量查询总结 数据库管理-第157期 Oracle Vector DB & AI-08&#xff08;20240301&#xff09; 作者&…

多层感知器(神经网络)与激活函数

单个神经元&#xff08;二分类&#xff09; 多个神经元&#xff08;多分类&#xff09; 多层感知器 多层感知器&#xff0c;他是一种深度学习模型&#xff0c;通过多层神经元的连接和激活来解决非线性问题。 激活函数 激活函数的种类包括relu&#xff0c;sigmoid和tanh等 …

C 嵌入式系统设计模式 15:基本并发概念

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之一…

GEE数据集——GLC_FCS30D - 全球 30 米土地覆被变化数据集(1985-2022 年)

GLC_FCS30D - 全球 30 米土地覆被变化数据集&#xff08;1985-2022 年&#xff09; 注 本数据集是正在提交的论文的一部分&#xff0c;因此没有引用和 DOI 信息。请在使用本数据集时注意这一点。 GLC_FCS30D 数据集是全球土地覆被监测领域的一项开创性进展&#xff0c;它以 30…

青少年CTF2024 #Round1 wp web

web EasyMD5 MD5碰撞&#xff0c;使用工具fastcoll生成内容不同但md5值相同的两个pdf文件上传即可获得flag&#xff1b; ./fastcoll_v1.0.0.5.exe -p 1.pdf -o 2.pdf 3.pdf # -p指定任意源文件&#xff0c;-o指定生成两个内容不同但md5值相同的目标文件 工具下载&#x…

【MySQL】复合查询(重点)-- 详解

一、基本查询练习回顾 1、查询工资高于 500 或岗位为 MANAGER 的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的 J 2、按照部门号升序而雇员的工资降序排序 3、使用年薪进行降序排序 4、显示工资最高的员工的名字和工作岗位 5、显示工资高于平均工资的员工信息 6、显…

【AIGC】微笑的秘密花园:红玫瑰与少女的美好相遇

在这个迷人的画面中&#xff0c;我们目睹了一个迷人的时刻&#xff0c;女子则拥有一头柔顺亮丽的秀发&#xff0c;明亮的眼睛如同星河般璀璨&#xff0c;优雅而灵动&#xff0c;她的微笑如春日暖阳&#xff0c;温暖而又迷人。站在红玫瑰花瓣的惊人洪水中。 在一片湛蓝无云的晴…

100M服务器能同时容纳多少人访问

100M服务器的并发容纳人数会受到多种因素的影响&#xff0c;这些因素包括单个用户的平均访问流量大小、每个用户的平均访问页面数、并发用户比例、服务器和网络的流量利用率以及服务器自身的处理能力。 点击以下任一云产品链接&#xff0c;跳转后登录&#xff0c;自动享有所有…

精品SSM的选修课管理系统选课签到打卡

《[含文档PPT源码等]精品基于SSM的选修课管理系统设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#xff1a;HTM…

leetcode--接雨水(双指针法,动态规划,单调栈)

目录 方法一&#xff1a;双指针法 方法二&#xff1a;动态规划 方法三&#xff1a;单调栈 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 黑色的是柱子&#xff0c;蓝色的是雨水&#xff0c;我们先来观察一下雨水的分布情况: 雨水落在凹槽之间&#xff0c;在一个凹槽的…

Laravel Octane 和 Swoole 协程的使用分析二

又仔细研究了下 Octane 源码和 Swoole 的文档&#xff0c;关于前几天 Laravel Octane 和 Swoole 协程的使用分析中的猜想&#xff0c;得到进一步验证&#xff1a; Swoole 的 HTTP Server 启动后会创建一个 master 进程和一个 manager 进程&#xff1b;master 进程又会创建多个…

持安科技孙维伯:零信任在攻防演练下的最佳实践|DISCConf 2023

近日&#xff0c;在2023数字身份安全技术大会上&#xff0c;持安科技联合创始人孙维伯应主办方的特别邀请&#xff0c;发表了主题为“零信任在攻防演练下的最佳实践”的演讲。 孙维伯在2023数字身份安全技术大会上发表演讲 以下为本次演讲实录&#xff1a; 我是持安科技的联合…

Leetcode 第 386 场周赛题解

Leetcode 第 386 场周赛题解 Leetcode 第 386 场周赛题解题目1&#xff1a;3046. 分割数组思路代码复杂度分析 题目2&#xff1a;3047. 求交集区域内的最大正方形面积思路代码复杂度分析 题目3&#xff1a;3048. 标记所有下标的最早秒数 I思路代码复杂度分析 题目4&#xff1a;…

网站添加pwa操作和配置manifest.json后,没有效果排查问题

pwa技术官网&#xff1a;https://web.dev/learn/pwa 应用清单manifest.json文件字段说明&#xff1a;https://web.dev/articles/add-manifest?hlzh-cn Web App Manifest&#xff1a;Web App Manifest | MDN 当网站添加了manifest.json文件后&#xff0c;也引入到html中了&a…

决定西弗吉尼亚州地区版图的关键历史事件

决定西弗吉尼亚州地区版图的关键历史事件&#xff1a; 1. 内部分裂与美国内战&#xff1a; - 在1861年美国内战爆发时&#xff0c;弗吉尼亚州作为南方邦联的一员宣布退出美利坚合众国。然而&#xff0c;弗吉尼亚州西部的一些县由于经济结构&#xff08;主要是农业非依赖奴隶制…

小程序事件处理

事件处理 一个应用仅仅只有界面展示是不够的&#xff0c;还需要和用户做交互&#xff0c;例如&#xff1a;响应用户的点击、获取用户输入的值等等&#xff0c;在小程序里边&#xff0c;我们就通过编写 JS 脚本文件来处理用户的操作 1. 事件绑定和事件对象 小程序中绑定事件与…

学习:GPT-4技术报告2023.3

原文链接&#xff1a;GPT-4的 (openai.com) 摘要&#xff1a; 我们创建了 GPT-4&#xff0c;这是 OpenAI 在扩展深度学习方面的最新里程碑。GPT-4 是一个大型多模态模型&#xff08;接受图像和文本输入&#xff0c;发出文本输出&#xff09;&#xff0c;虽然在许多现实世界场…

SpringBoot之Actuator的两种监控模式

SpringBoot之Actuator的两种监控模式 springboot提供了很多的检测端点(Endpoint),但是默认值开启了shutdown的Endpoint&#xff0c;其他默认都是关闭的,可根据需要自行开启 文章目录 SpringBoot之Actuator的两种监控模式1. pom.xml2. 监控模式1. HTTP2. JMX 1. pom.xml <de…

XSS初级漏洞靶场

一、环境的搭建 可以在githb上找靶机包&#xff0c;使用小皮面板搭建在自己本机 与此文章类似&#xff08;放在www目录下&#xff09; 二、XSS漏洞简介 1、什么是xss漏洞 当用户访问被xss注入的网页&#xff0c;xss代码就会被提取出来。用户浏览器就会解析这段xss代码&…