Welcome 微信登录

首页 / 操作系统 / Linux / Linux平台代码覆盖率测试-基本块图、插桩位置及桩代码执行分析

0. 序 1. 基本块概念 2. 基本块图及插桩点分析 2.1 基本块图 2.2 有效基本块图 2.3 带桩点信息的有效基本块图 2.4 插桩位置及桩代码执行情况分析 3. 小结 Appendix: 源代码中对 Basic Block 的解释   0. 序  由前面几篇文章,例如:Linux 平台代码覆盖率测试 -gcov-dump 原理分析 http://www.linuxidc.com/Linux/2011-05/36536.htmLinux 平台代码覆盖率测试 -.gcda/.gcno 文件及其格式分析 http://www.linuxidc.com/Linux/2011-05/36540.htmLinux 平台代码覆盖率测试 -GCC 插桩基本概念及原理分析 http://www.linuxidc.com/Linux/2011-05/36572.htmLinux 平台代码覆盖率测试 -GCC 插桩前后汇编代码对比分析 http://www.linuxidc.com/Linux/2011-05/36541.htm 我们已经知道了代码覆盖率测试的一些相关概念,例如 Basic Block , Arcs 等。本文重点叙述这些基本概念,并仍以前面的 test.c 为例说明基本块图 (Basic Block Graph) 及插桩点。  本文所用 gcc 版本为 gcc-4.1.2 。 test.c 代码如下。
00001: #include 00002:00003: int main ( void ) 00004: { 00005:    int i , total ; 00006:00007:    total = 0 ; 00008:00009:    for ( i = 0 ; i < 10 ; i ++ ) 00010:    total += i ; 00011:00012:    if ( total != 45 ) 00013:        printf ( "Failure " ); 00014:    else 00015:        printf ( "Success " ); 00016:    return 0 ; 00017: } 00018:
1. 基本块概念  通过基本块的划分,可以把程序分为一组代码段,每一段代码中的第一条语句被执行,则整段代码都被执行一次。 那么,什么是基本块 (Basic Block) ?  基本块
  • 程序中一个顺序执行的语句序列
  • 只有一个出口语句和一个入口语句
  • 执行时只能从入口语句入,从出口语句退出
  • 基本块中的所有语句的执行次数一定是相同的
  • 一般由多个顺序执行语句后跟一个跳转语句组成
 因此,基本块的最后一条语句一定是一个跳转语句,且跳转的目的地一定是另一个基本块的第一条语句。如果跳转语句是有条件的,就产生了一个分支 (arc) ,该基本块就有两个基本块作为目的地。如果把每个基本块当作一个节点,那么一个函数中的所有基本块就构成了一个有向图,称之为基本块图 (Basic Block Graph) 。且只要知道图中部分 BB 或 arc 的执行次数就可以推算出所有的 BB 和所有的 arc 的执行次数。  本文附录介绍了 GCC 源代码中对 Basic Block 的解释。下面以 test.c 为例,说明这些问题。  2. 基本块图及插桩点分析  2.1 基本块图  根据 " Linux 平台代码覆盖率测试 -.gcda/.gcno 文件及其格式分析 " 一文 1.1 节和 2.1 节的输出信息,我们可以画出如下的基本块图 (Basic Block Graph) 。
 图 1 基本块图  其中, BB0 和 BB8 分别对应着开始和结束的虚拟基本块,表明程序从 BB0 开始,从 BB8 退出。因此, BB0 没有入边,只有出边,而 BB8 只有入边,没有出边。 8 个 ARCS 记录对应图中的 8 个有出度的节点, 12 条有向边实际上就是所有的 arcs 总数。  2.2 有效基本块图  从 输出结果 可以看出, BB0,BB8,BB3 没有对应的代码行,可以当作虚拟的基本块。有效的基本块只有 BB1, BB2, BB4, BB5, BB6, BB7 。  如果在图 1 中,我们删除虚拟基本块 BB0 和 BB8 ,并加入 " Linux 平台代码覆盖率测试 -.gcda/.gcno 文件及其格式分析 " 一文 2.1 节的输出的 LINES 信息 (BB 的行号信息 ) ,那么程序的逻辑会更清楚。如图 2 所示。   图 2 有效基本块 ( 带行号信息 ) 图  其中,每个节点旁边的 lineno( 行号 ) 表示构成该 BB 的代码行,这些代码也显示在旁边。