Gcov 详解 + 内核函数覆盖率测试方法详述及产生错误解决办法

2023-11-18

1. gcov是什么?

  • Gcov is GCC Coverage
  • 是一个测试代码覆盖率的工具
  • 是一个命令行方式的控制台程序
  • 伴随GCC发布配合GCC共同实现对C/C++文件的语句覆盖和分支覆盖测试
  • 与程序概要分析工具(profiling tool,例如gprof)一起工作,可以估计程序中哪一段代码最耗时;

注:程序概要分析工具是分析代码性能的工具。

2. gcov能做什么?

gcov可以统计

  • 每一行代码的执行频率
  • 实际上哪些代码确实被执行了
  • 每一段代码(section code)的耗时(执行时间)

因此,gcov可以帮你优化代码,当然这个优化动作还是应该有开发者完成。

 


3. Gcov的实现原理简介

Gcc中指定-ftest-coverage 等覆盖率测试选项后,gcc会:在输出目标文件中留出一段存储区保存统计数据

在源代码中每行可执行语句生成的代码之后附加一段更新覆盖率统计结果的代码

在最终可执行文件中进入用户代码 main函数之前调用 gcov_init内部函数初始化统计数据区,并将gcov_exit内部函数注册为 exit handlers

用户代码调用exit 正常结束时,gcov_exit函数得到调用,其继续调用 __gcov_flush函数输出统计数据到 *.gcda 文件中


4. 如何使用gcov

4.1 - 准备工作
==============
配置内核(Configure the kernel with):
        CONFIG_DEBUG_FS=y
        CONFIG_GCOV_KERNEL=y

选择gcov的格式(select the gcc's gcov format, default is autodetect based on gcc version):

        CONFIG_GCOV_FORMAT_AUTODETECT=y

获取内核数据覆盖率(and to get coverage data for the entire kernel):

        CONFIG_GCOV_PROFILE_ALL=y


Note that kernels compiled with profiling flags will be significantly
larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
on all architectures.


挂载debugfs(Profiling data will only become accessible once debugfs has been mounted):

        mount -t debugfs none /sys/kernel/debug

到此Gcov的准备工作已经完成,下面要做的就是编译内核

(参考:http://blog.csdn.net/wangyezi19930928/article/details/41985795)


4.2  - 相关文件介绍:

========
The gcov kernel support creates the following files in debugfs:
        /sys/kernel/debug/gcov
                Parent directory for all gcov-related files.


        /sys/kernel/debug/gcov/reset
                Global reset file: resets all coverage data to zero when written to.


Invoking gcov        /sys/kernel/debug/gcov/path/to/compile/dir/file.gcda
                The actual gcov data file as understood by the gcov tool. Resets file coverage data to zero when written to.

        /sys/kernel/debug/gcov/path/to/compile/dir/file.gcno
                Symbolic link to a static data file required by the gcov tool. This file is generated by gcc when compiling with
                option -ftest-coverage.

4.3 - 
Invoking gcov


gcov [options] files
wangye@selfimpro:~$ gcov
Usage: gcov [OPTION]... SOURCE|OBJ...

Print code coverage information.

  -h, --help                      Print this help, then exit
  -v, --version                   Print version number, then exit
  -a, --all-blocks                Show information for every basic block
  -b, --branch-probabilities      Include branch probabilities in output
  -c, --branch-counts             Given counts of branches taken
                                    rather than percentages
  -n, --no-output                 Do not create an output file
  -l, --long-file-names           Use long output file names for included
                                    source files
  -f, --function-summaries        Output summaries for each function
  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE
  -s, --source-prefix DIR         Source prefix to elide
  -r, --relative-only             Only show data for relative sources
  -p, --preserve-paths            Preserve all pathname components
  -u, --unconditional-branches    Show unconditional branch counts too
  -d, --display-progress          Display progress information

下面我们就来具体的介绍一下如何使用gcov!

上述例子是Gcov的官方暗网站给出来的,这里我们就直接使用!

#include <stdio.h>
int main (void)
{
    int i, total;
    total = 0;
    for (i = 0; i < 10; i++)
        total += i;
    if (total != 45)
        printf ("Failure\n");
    else
        printf ("Success\n");
    return 0;
}

此时该目录中只有一个源文件:

wangye@selfimpro:~/Gcov_study$ ls
tmp.c

1)编译:

wangye@selfimpro:~/Gcov_study$ gcc -fprofile-arcs -ftest-coverage tmp.c
wangye@selfimpro:~/Gcov_study$ ls
a.out  tmp.c  tmp.gcno

-fprofile-arcs  -ftest-coverage告诉编译器生成gcov需要的额外信息,并在目标文件中插入gcov需要的extra profiling information。因此,该命令在生成可执行文件的同时生成gcov note文件(tmp.gcno)


2)收集信息:

wangye@selfimpro:~/Gcov_study$ ./a.out 
Success
wangye@selfimpro:~/Gcov_study$ ls
a.out  tmp.c  tmp.gcda  tmp.gcno

执行该程序,生成gcov data文件(tmp.gcda)


3)生成数据报告

wangye@selfimpro:~/Gcov_study$ gcov tmp.c
File 'tmp.c'
Lines executed:87.50% of 8
Creating 'tmp.c.gcov'

wangye@selfimpro:~/Gcov_study$ ls
a.out  tmp.c  tmp.c.gcov  tmp.gcda  tmp.gcno

wangye@selfimpro:~/Gcov_study$ cat tmp.c.gcov
        -:    0:Source:tmp.c
        -:    0:Graph:tmp.gcno
        -:    0:Data:tmp.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <stdio.h>
        1:    2:int main (void)
        -:    3:{
        -:    4:	int i, total;
        1:    5:	total = 0;
       11:    6:	for (i = 0; i < 10; i++)
       10:    7:		total += i;
        1:    8:	if (total != 45)
    #####:    9:		printf ("Failure\n");
        -:   10:	else
        1:   11:		printf ("Success\n");
        1:   12:	return 0;
        -:   13:}

总结:

1)

如何使用gcov

用GCC编译的时候加上-fprofile-arcs -ftest-coverage选项,链接的时候也加上。
fprofile-arcs参数使gcc创建一个程序的流图,之后找到适合图的生成树。

只有不在生成树中的弧被操纵(instrumented):gcc添加了代码来清点这些弧执行的次数。当这段弧是一个块的唯一出口或入口时,操纵工具代码(instrumentation code)将会添加到块中,否则创建一个基础块来包含操纵工具代码。

gcov主要使用.gcno和.gcda两个文件
.gcno是由-ftest-coverage产生的,它包含了重建基本块图和相应的块的源码的行号的信息。
.gcda是由加了-fprofile-arcs编译参数的编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息(而gcda只能在程序运行完毕后才能产生的)。
Gcov执行函数覆盖、语句覆盖和分支覆盖。

2. 使用主要有三个步骤:

  1)编译阶段:加入编译选项gcc  –fprofile-arcs –ftest-coverage tmp.c,生成记录程序流程图等信息

  2)数据收集与提取阶段:./a.out,生成具体的运行信息

这一阶段生成的数据信息自动保存到.o所在的目录,也就是说如果存在/usr/build/hello.o,则生成/usr/build/hello.gcda,但是如果前边目录不存在就会出错。

  3)生成数据报告: gcov  tmp.c


此时该目录中有两个源文件:

程序代码由main.c和tmp.c两个文件组成,编译、链接、运行程序
1) 编译:gcc -fprofile-arcs -ftest-coverage -o myapp main.c tmp.c
2) 运行:./myapp
3)然后 输入命令: gcov main.c,gcov tmp.c

这个时候当前目录下有了新的文档main.c.gcov,和tmp.c.gcov
若想保存覆盖率文件,上述命令修改为:
命令:gcov main.c >>yourfilename,gcov tmp.c >>yourfilename


5. 对内核函数使用Gcov:

1)、进入到内核源码树目录(包含源文件、目标文件、.gcno文件):

/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel   //内核源码树目录

wangye@selfimpro:~$ cd kernel_sources/kernel_test/linux-3.14.8/kernel/
root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# ls
acct.c		     groups.c		    relay.gcno
relay.o              acct.gcno	            groups.gcno	
...... 

2)、为分析数据文件(.gcda)创建软连接

因为*.gcda文件是内核运行时动态生成的,所以不包含在内核源码数目录下。但是要执行gcov必须要有此文件,因此需要为内核源码树目录

下的源文件对应的.gcda文件创建软连接,目的是在执行  “gcov sourcefile ” 时能找到源文件对应的分析数据。

gcov信息目录(包含要分析的数据)下的

/sys/kernel/debug/gcov/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel

因为kernel中包含很多文件所以需要为很多文件创建软连接,方便期间使用如下命令可以一次性为所有文件创建软连接,需要注意的是/sys/kernel/debug 文件夹是一个临时文件夹,不存在于磁盘当中,是在内存当中存在的,其中的文件也是系统运行是动态产生的,所以当你重新启动机器时会发现之前创建的软连接会全部断开,所以在每次开机重启之后所有的软连接需要重新创建:

root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# 
for i in `ls /sys/kernel/debug/gcov/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel/*gcda`;
 do ln -s $i ${i##*\/};done 

软连接创建成功:

root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# ls
acct.c		     groups.c		    relay.gcno
acct.gcda	     groups.gcda	    relay.o
acct.gcno	     groups.gcno	    res_counter.c
acct.o		     groups.o		    res_counter.gcda
arch_hweight.h.gcov  hrtimer.c		    res_counter.gcno
......

3)执行gcov 命令:

<pre name="code" class="plain">root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# cd..
root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8# gcov kernel/signal.c
File 'kernel/signal.c'
Lines executed:45.95% of 1073
Creating 'signal.c.gcov'

File 'include/linux/signal.h'
Lines executed:86.67% of 15
Creating 'signal.h.gcov'

File 'include/linux/tracehook.h'
Lines executed:75.00% of 4
Creating 'tracehook.h.gcov'

File 'include/linux/signalfd.h'
Lines executed:100.00% of 4
Creating 'signalfd.h.gcov'

File 'include/linux/wait.h'
Lines executed:100.00% of 1
Creating 'wait.h.gcov'
......
 

这时会在当前目录下产生相应的.gcov文件,该文件包含我们需要的信息:

<span style="font-size:14px;color:#000000;">root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8# cat signal.c.gcov
     ......
     -: 3296:SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, nset,
    #####: 3297:		old_sigset_t __user *, oset)
        -: 3298:{
        -: 3299:	old_sigset_t old_set, new_set;
        -: 3300:	sigset_t new_blocked;
        -: 3301:
    #####: 3302:	old_set = current->blocked.sig[0];
        ......</span>


4. Error Record:

1)

root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# gcov range.c
File 'kernel/range.c'
Lines executed:51.35% of 74
Creating 'range.c.gcov'
Cannot open source file kernel/range.c

解决办法:

root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8/kernel# cd ..
root@selfimpro:/home/wangye/kernel_sources/kernel_test/linux-3.14.8# gcov /kernel/range.c
产生该错误的主要原因是路径不对,range.c中使用了内核中其他目录下的文件,因为路径问题找不到调用的文件,所以回退到内核根目录下

加上相应的源文件目录即可!


2)

/sys/kernel/debug/gcov/home/wangye/kernel_sources/linux-3.14.8/kernel/cgroup.gcda:cannot open data file,
assuming not executed
解决办法:

由于.gcda文件是内核运行时动态产生的,所以在内核源码树下是不存在的,所以需要对其创建软连接到相应源文件目录下,相见上述!


3)

gcov /kernel/key.c
gcno:cannot open graph file
这时到相应目录下才查看文件发现内核运行过程中没有执行key.c这个文件,所以不会有相应的.gcno 和 .o 文件,因此执行gcov操作会产生该错误。


Reference:

https://gcc.gnu.org/onlinedocs/gcc/Gcov.html#Gcov

http://blog.csdn.net/heli007/article/details/8268614

/kernel_sources/Documentation/gcov.txt

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gcov 详解 + 内核函数覆盖率测试方法详述及产生错误解决办法 的相关文章

  • 如何在 Bash 中给定超时后终止子进程?

    我有一个 bash 脚本 它启动一个子进程 该进程时不时地崩溃 实际上是挂起 而且没有明显的原因 闭源 所以我对此无能为力 因此 我希望能够在给定的时间内启动此进程 如果在给定的时间内没有成功返回 则将其终止 有没有simple and r
  • Gtk-ERROR **:检测到 GTK+ 2.x 符号

    我正在使用 gcc 编译我的 c 应用程序 并使用以下标志 gcc evis c pkg config cflags libs gtk 2 0 libs clutter gtk 1 0 libs gthread 2 0 Wall o evi
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • Linux 上的用户空间能否实现本机代码的抢占式多任务处理?

    我想知道是否可以在 Linux 用户空间的单个进程中实现本机代码的抢占式多任务处理 也就是说 从外部暂停一些正在运行的本机代码 保存上下文 交换到不同的上下文 然后恢复执行 所有这些都由用户空间精心安排 但使用可能进入内核的调用 我认为这可
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • 如何在基于 Linux 的系统上的 C 程序中使用 mqueue?

    如何在基于 Linux 的系统上的 C 程序中使用 mqueue 消息队列 我正在寻找一些好的代码示例 可以展示如何以正确且正确的方式完成此操作 也许是一个操作指南 下面是一个服务器的简单示例 该服务器接收来自客户端的消息 直到收到告诉其停
  • 在两次之间每分钟执行一次 Cronjob

    我需要在 crontab 中每分钟运行一个 bash 脚本8 45am and 9 50am每天的 Code 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 8 home pull sh gt ho
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • Windows CE 与嵌入式 Linux [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 现在我确信我们都清楚 Linux 与 Windows 桌面的相对优点 然而 我对嵌入式开发世界的了解却少得多 我主要对行业解决方案感兴
  • 如何查询X11显示分辨率?

    这似乎是一个简单的问题 但我找不到答案 如何查询 通过 X11 存在哪些监视器及其分辨率 查看显示宏 http tronche com gui x xlib display display macros html and 屏幕宏 http
  • PyQt5 - 无法使用 QVideoWidget 播放视频

    from PyQt5 QtWidgets import from PyQt5 QtMultimedia import from PyQt5 QtMultimediaWidgets import from PyQt5 QtCore impor
  • 警告:请求的映像平台 (linux/amd64) 与检测到的主机平台 (linux/arm64/v8) 不匹配

    警告 请求的映像平台 linux amd64 与检测到的主机平台 linux arm64 v8 不匹配 并且未请求特定平台 docker 来自守护程序的错误响应 无法选择具有功能的设备驱动程序 gpu 我在 mac 上尝试运行此命令时遇到此
  • 当用户按下打印时运行脚本,并且在脚本结束之前不开始假脱机(linux,cups)

    我需要做的是结合用户按下打印来执行 python 程序 脚本 并且在该程序退出之前不要让打印作业假脱机 原因是打印驱动程序不是开源的 我需要更改用户设置 在本例中是部门 ID 和密码 通常是每个用户 但因为这是一个信息亭 具有相同帐户的不同
  • Awk - 计算两个文件之间的每个唯一值和匹配值

    我有两个文件 首先 我尝试获取第 4 列中每个唯一字段的计数 然后匹配第二个文件的第二列中的唯一字段值 File1 第 4 列的每个唯一值和 File2 第 2 列包含我需要在两个文件之间匹配的值 所以本质上 我试图 gt 如果 file2
  • Fedora dnf 更新不起作用?

    当我尝试使用 update 命令更新 Fedora 22 时 sudo dnf update 我收到以下错误 错误 无法同步存储库 更新 的缓存 无法准备内部镜像列表 Curl 错误 6 无法解析主机名 无法解析主机 mirrors fed
  • Linux中使用管道进行进程间通信

    我已经编写了在 linux 中写入数字以进行管道传输的代码 如下所示 但显示错误 任何人都可以帮助我解决这个问题 基本上该程序的问题陈述如下 一个程序将打开一个管道 向管道写入一个数字 其他程序将打开同一管道 读取数字并打印它们 关闭两个管
  • 这种 bash 文件名提取技术有何用途?

    我有一部分 bash 脚本正在获取不带扩展名的文件名 但我试图了解这里到底发生了什么 是做什么用的 有人可以详细说明 bash 在幕后做了什么吗 如何在一般基础上使用该技术 bin bash for src in tif do txt sr
  • 码头无故停止

    我需要经验丰富的码头用户的建议 我在负载均衡器 亚马逊云 后面维护着 2 台 Linux 机器 使用 Jetty 9 0 3 有时我的 Jetty 容器会被 Thread 2 无故关闭 同时地 显示以下日志并且容器无故停止 没有错误 没有例
  • 找出 Linux 上的默认语言

    有没有办法从C语言中找出Linux系统的默认语言 有 POSIX API 可以实现这个功能吗 例如 我想要一个人类可读格式的字符串 即德语系统上的 German 或 Deutsch 法语系统上的 French 或 Francais 等 有类
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer

随机推荐

  • BFS(广度优先算法)——判断无向简单图中任意两点是否连通

    include
  • dojo SplitContainer

    SplitContainer author amushen email amushen yahoo com cn qq 38371354 相关的文件 dojo widget LayoutContainer dojo widget HtmlW
  • Pytorch2.0中compiled_model=torch.compile(model) 的正确添加位置

    今天pytorch官网更新了pytorch2 0稳定版 迫不及待的我直接更新了 确实像官方所说 只需加入model torch compile model 一行代码即可加速 加入的位置如下 cpu训练 model UNet deep sup
  • 混杂设备与字符设备的区别----misc_register、 register_chrdev 的区别总结

    杂项设备 misc device 杂项设备也是在嵌入式系统中用得比较多的一种设备驱动 在 Linux 内核的include linux目录下有Miscdevice h文件 要把自己定义的misc device从设备定义在这里 其实是因为这些
  • openstack开发实践(一):devstack搭建all-in-one的openstack开发环境

    Devstack简介 devstack是面向开发者的一个openstack部署工具 用户可以指定不同的版本分支进行安装 devstack借助于Shell脚本实现openstack自动化部署 devstack源码中的stack sh即为安装脚
  • Python基于控制台的学生管理系统

    encoding utf 8 定义一个函数 显示可以使用的功能列表给用户 def showInfo print 30 print 学生管理系统 v1 0 print 1 添加学生的信息 print 2 删除学生的信息 print 3 修改学
  • MIPI信号的分析--结合示波器实际测试波形

    如果排查的思路对你有帮助 请记住 消雨匆匆 码字和排查很累 仅此而已 硬件不是抄电路 拿烙铁 懂点软件 细致分析 找问题和破案搜集线索是一样的 PS 硬件知识也可以性感 部分内容来自于此博客的大神总结 http www elecfans c
  • Java+GeoTools实现WKT数据根据EPSG编码进行坐标系转换

    场景 Java GeoTools 开源的Java GIS工具包 快速入门 实现读取shp文件并显示 Java GeoTools 开源的Java GIS工具包 快速入门 实现读取shp文件并显示 霸道流氓气质的博客 CSDN博客 在上面实现J
  • 数字人+ChatGPT强强联手能擦出什么火花?

    随着元宇宙概念的快速发展 以数字人 ChatGPT为形式的创作方式正在颠覆传统视频创作方式 并在市场上呈现快速增长的态势 根据新榜的报道 目前已经有多位大V使用虚拟数字人来协助完成短视频制作 并且值得一提的是 这些视频并没有因为采用数字人而
  • 定时器编码器AB相电机测速( 补充)

    TIM编码器AB相电机测速 定时器编码器AB相电机测速 1 四倍频 2 算法应用 3 stm32硬件连接 3 stm32环境配置端口配置 3 C语言实现编码器个数读取 3 C语言实现编码器个数转换为速度 定时器编码器AB相电机测速 1 四倍
  • vue3配置eslint 出现问题

    vue3配置eslint 出现问题 标题必须使用导入来加载 ES 模块 ESlint Error Must use import to load ES Module 加上这一行即可
  • Jmeter之ForEach控制器

    场景运用 ForEach控制器一般和用户自定义变量或者正则表达式提取器一起使用 其在用户自定义变量或者从正则表达式提取器的返回结果中读取一系列相关的变量 该控制器下的采样器或者控制器都会被执行一次或多次 每次读取不同的变量值 需求2 有一组
  • 学习java随堂练习-20220609

    学习Java的第八天 第1题 第2题 第3题 第4题 第5题 今天是学习Java的第八天 5道练习题 第1题 题目 1 循环输入近6年某高校的录取分数 求出平均分和最低分 运行结果 代码如下 循环输入近6年某高校的录取分数 求出平均分和最低
  • PHP操作Excel

    头 header Content Type application vnd ms excel header Content Disposition attachment filename sample xls header Pragma n
  • 时序预测

    时序预测 MATLAB实现DNN全连接神经网络时间序列预测 目录 时序预测 MATLAB实现DNN全连接神经网络时间序列预测 基本介绍 模型研究 程序设计 学习总结 参考资料 基本介绍 DNN的结构不固定 一般神经网络包括输入层 隐藏层和输
  • 传指针和传引用的区别以及指针和引用的区别

    一 引用 引用的定义 引用是给另外一个变量其别名 所以引用不会分配内存空间 引用是引入了对象的一个同义词 例如 Point pt1 10 10 Point pt2 pt1 上述的代码 定义了pt2为pt1的引用 通过这样的定义 pt2和pt
  • 让生产活动更高效,物料管理场景的RPA应用

    作为制造业 供应链领域常见环节 物料管理 Material Management 通常是对企业生产经营活动所需各种物料的采购 验收 供应 保管 发放 使用等一系列计划与控制活动的总称 物料管理科学与否 将会影响到组织各职能部门间的协调 生产
  • 文件的上传与下载

    一 文件上传 文件上传程序步骤 1 如何在web页面中添加上传输入项
  • python数据驱动测试设计_Python+unittest+DDT实现的数据驱动测试

    前言 数据驱动测试 避免编写重复代码 数据与测试脚本分离 通过使用数据驱动测试 来验证多组数据测试场景 通常来说 多用于单元测试和接口测试 ddt介绍 Data Driven Tests DDT 即数据驱动测试 可以实现不同数据运行同一个测
  • Gcov 详解 + 内核函数覆盖率测试方法详述及产生错误解决办法

    1 gcov是什么 Gcov is GCC Coverage 是一个测试代码覆盖率的工具 是一个命令行方式的控制台程序 伴随GCC发布 配合GCC共同实现对C C 文件的语句覆盖和分支覆盖测试 与程序概要分析工具 profiling too