gCov 1.5版本数据文件格式分析

本文详细介绍了GCC自带的gCov覆盖率工具如何生成代码覆盖率报告。通过对gCov产生的三种关键文件(.da、.bb、.bbg)的格式进行深入分析,帮助读者理解代码覆盖率报告的生成过程。

作者:蓝白云


说明:本文参考的源代码版本为gcc-2.95.3版本

 

gCov 1.5版本依赖2类文件才能生成代码覆盖率报告,第一类:源代码文件,其次就是:源文件描述文件、程序基本块流程图文件和覆盖率数据文件,本文是针对后者进行分析和说明(当然,源代码文件没有分析的意义)。

我们可以在gcc源代码中的gcov.c源文件的bbg_fileda_filebb_file三个文件指针为线索来找到它们仨的文件数据格式。

三个文件之间的关系

三种文件都是以二进制格式存在。它们的关系是,根据bb文件中的代码行信息找到bbg文件中对应的基本块(based block),然后根据基本块找到对应的覆盖率数据。最后结合源文件一并输出代码覆盖率报告。

x.c源文件为例来阐述gCov覆盖率统计产生的数据文件格式,以下是x.c的覆盖率报告。其中 Branch data中 + 表示分支是否被覆盖, # 表示未被覆盖;Line data 中的数字表示代码行被执行的次数。

Branch dataLine dataSource code

1:: #include "stdio.h"

2:: /* file: x.c */

3:: void foo(int i)

4:: {

5 [ +++++ :8 :switch(i)

#]

6:: {

7[ + ]:2 :case 1:printf("a\n");/*yes */ break;

8:: case 2:

9:: /* yes */

10:2 :printf("b\n");

11[ + ]:2 :break;

12[ + ]:2 :case 3:printf("c\n");break;

13:2 :default: printf("other\n");

14:: }

15:: }

16::

17:: int test_main()

18:: {

19:2 :int i;

20[ +++ ]:10 :for(i=0;i<4;++i)

21:8 :foo(i);

22[ + ]:2 :return 0;

23:: }

x.da文件格式

8个字节为单位计算,第一个单位为x文件的插桩点总数,第二个单位开始到最后表示每个插桩点的覆盖次数(即运行了多少次);

x.bb文件格式

x.bb文件描述源文件名和函数名,以及函数中的有效行号。函数名和源文件名都是通过字符串表示。字符串都是以’\0’结尾的字符串,且字符序以4字节对齐,不足的末尾以0补充。

-2<函数名>-2 + 函数中有效语句所占用的行号(case不算)[当前行的分支块个数,以4字节的0表示1]

-1<源文件名>-1

x.bbg文件格式

bbg文件是用来表示程序的流程图的,每个函数对应一个图,每个图中以基本块(based block)组成。

函数 = 块总数 + arcs总数{ } + 以-1结尾

其中“图”=每个块的边数[destflag_bits] + …

例如:将x.bbg文件(二进制格式)翻译成如下可读格式,{}表示一个图(也就是一个函数),以[]表示一条边(或叫:弧),其中flag_bits0时(即0246等)表示一个覆盖率桩点(见图中蓝色的边所示),桩点顺序与x.da文件桩点顺序对应

// x.c 的 foo 函数

17 25

{ 1 [ 1, 4], // 0

2 [ 2, 5],[9, 0], // 1

2 [ 3, 5],[5, 1], // 2

2 [ 4, 5],[7, 0], // 3

1 [13, 1], // 4

2 [ 6, 5],[11, 0], // 5

1 [13, 0], // 6

2 [ 8, 5],[16, 3] // 7

1 [15, 0], // 8

2 [10, 5],[16, 3] // 9

1 [15, 0], // 10

2 [12, 5],[16, 3] // 11

1 [15, 0], // 12

2 [14, 5],[16, 3] // 13

1 [15, 4] // 14

1 [16, 3] // 15

1 [ 0, 3], // 16

} -1;


// x.c 的 test_main 函数

10 12

{ 1 [1, 4], // 0

1 [2, 5], // 1

2 [3, 5], [4, 0] // 2

1 [7, 1], // 3

2 [5, 5], [9, 3] // 4

1 [6, 5], // 5

1 [2, 0] // 6

1 [8, 1] // 7

1 [9, 3] // 8

1 [0, 3] // 9

} -1;


<think>好的,我现在要帮用户了解如何使用gcov生成的.gcda文件来获取覆盖率。首先,我需要回忆一下gcov的工作流程。记得gcov是和GCC配套的代码覆盖率工具,它通过插桩程序生成.gcno和.gcda文件。用户已经生成了.gcda文件,说明他们可能已经完成了编译和运行程序这两个步骤。 接下来,用户的问题是如何用这些.gcda文件得到覆盖率。我需要先确认用户是否已经正确生成了这些文件。通常,编译时需要加上-fprofile-arcs -ftest-coverage选项,这样才会生成.gcno文件。运行程序后,生成.gcda文件。如果用户已经做到了,那接下来就是使用gcov工具处理这些文件。 然后,我需要解释gcov的基本命令。比如,运行gcov source.c会生成source.c.gcov文件,里面包含每行代码的执行次数。但用户可能需要更详细的步骤,比如进入正确的目录,或者如何处理多个源文件的情况。 可能还需要提到如何生成可视化的报告,比如使用lcov和genhtml工具。因为单纯看.gcov文件可能不够直观,特别是对于大型项目。这里需要分步骤说明:先用lcov收集数据,生成.info文件,然后用genhtml生成HTML报告。 还要注意一些常见问题,比如.gcda文件的位置是否正确,权限问题,或者多次运行程序后.gcda文件的合并。此外,清理之前的覆盖率数据也是一个有用的提示,避免旧数据影响结果。 用户可能不知道如何解读生成的覆盖率报告,所以需要简要说明行覆盖率、分支覆盖率等指标。不过用户的问题主要集中在获取覆盖率的方法上,这部分可能需要点到为止。 最后,检查是否有遗漏的步骤,比如是否需要特定的GCC版本,或者跨平台的问题(比如在Linux环境下使用)。确保所有命令的语法正确,比如正确的lcov参数和genhtml的使用。 总结下来,步骤应该是:确保正确编译运行生成.gcda,使用gcov生成文本报告,或使用lcov和genhtml生成可视化报告,最后解释如何查看和理解报告。同时,提醒注意事项和常见问题处理。</think>要使用gcov生成的.gcda文件获取代码覆盖率,可以按照以下步骤操作: 1. **准备编译环境** - 编译代码时添加覆盖率检测选项: ```bash gcc -fprofile-arcs -ftest-coverage -g your_source.c -o your_program ``` - `-fprofile-arcs`:生成弧跳转计数 - `-ftest-coverage`:生成.gcno文件(代码插桩信息) 2. **运行生成.gcda文件** ```bash ./your_program ``` 执行程序后会在同一目录生成`.gcda`文件,该文件记录了实际执行路径的覆盖信息 3. **生成覆盖率报告** ```bash gcov your_source.c ``` - 将生成`.gcov`文本文件 - 每行代码前会标记执行次数: - `#####`:未覆盖的代码 - `N`:执行了N次的代码 4. **高级可视化报告(推荐)** - 安装lcov工具: ```bash sudo apt-get install lcov # Ubuntu/Debian ``` - 生成HTML报告: ```bash lcov --capture --directory . --output-file coverage.info genhtml coverage.info --output-directory coverage_report ``` 生成的`coverage_report`目录包含可视化覆盖率报告 **关键文件说明**: - `.gcno`:编译时生成,包含代码结构信息 - `.gcda`:运行时生成,包含实际执行数据 - `.gcov`:文本格式覆盖率报告 - `.info`:lcov中间数据文件 **注意事项**: 1. 确保.gcda文件与.gcno文件在相同目录 2. 程序必须正常退出(调用exit()或return)才能正确生成.gcda 3. 多次运行程序时,覆盖率数据会自动累积(可通过`gcov -r`重置) 4. 使用`lcov --remove`可过滤不需要统计的目录/文件 **查看结果示例**: ```text -: 0:Source:your_source.c -: 0:Programs:1 1: 1:void important_function() { 1: 2: printf("Hello"); #####: 3: // 未执行的代码 1: 4:} ``` 可视化报告会以HTML形式展示不同颜色标记的覆盖情况,支持查看文件/函数/分支级别的覆盖率统计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值