JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:Discover 和 Uncover 用户指南     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  简介

2.  内存错误搜索工具 (Discover)

3.  代码覆盖工具 (Uncover)

Uncover 的使用要求

使用 Uncover

检测二进制文件

运行检测过的二进制文件

生成并查看覆盖报告

示例

了解性能分析器中的覆盖报告

`Functions`(函数)选项卡

`Uncoverage`(未覆盖)计数器

`Function Count`(函数计数)计数器

`Instr Exec`(指令执行)计数器

`Block Covered %`(块覆盖率)计数器

`Instr Covered %`(指令覆盖率)计数器

`Source`(源)选项卡

`Disassembly`(反汇编)选项卡

`Inst-Freq`(指令频率)选项卡

了解 ASCII 覆盖报告

了解 HTML 覆盖报告

使用 Uncover 时的限制

只能检测有注释的代码

计算机指令可能不同于源代码

示例 1

示例 2

示例 3

索引

使用 Uncover 时的限制

只能检测有注释的代码

Uncover 只能检测按照Uncover 的使用要求中的说明准备的代码。无注释代码可能来自链接到二进制文件中的汇编语言代码,或者来自使用早于该部分中所列版本的编译器或操作系统编译的模块。

在准备时,特别要排除包含 asm 语句或 .il 模板的汇编语言模块和函数。

计算机指令可能不同于源代码

Uncover 处理计算机代码。它会查找计算机指令的覆盖,然后将此覆盖与源代码相关联。某些源代码语句没有关联的计算机指令,因此,看上去好像是 Uncover 没有报告这些语句的覆盖。

示例 1

考虑以下代码片段:

#define A 100
#define B 200
...
   if (A>B) {
        ...
   }

根据您的预期,Uncover 应该对 if 语句报告非零执行计数,但编译器很可能会删除此代码,使得 Uncover 在检测期间看不到它。因此,不会针对这些指令报告覆盖数据。

示例 2

以下为死代码的示例:

1  void foo() 
2  {
3     A();
4     return;
5     B();
6     C();
7     D();
8     return;
9   }                                                                

对应的汇编显示删除了 B,C,D 的调用,因为该代码从不执行。

foo:
                        .L900000109:
/* 000000          2 */         save    %sp,-96,%sp
/* 0x0004          3 */         call    A       ! params =      ! Result = 
/* 0x0008            */         nop
/* 0x000c          8 */         ret     ! Result = 
/* 0x0010            */         restore %g0,%g0,%g0

因此,不会针对第 5 行到第 6 行报告覆盖。

   Excl.       Excl.     Excl.  Excl.      Excl.
   Uncoverage  Function  Instr  Block      Instr
               Count     Exec   Covered %  Covered %
                                                             1.  void foo() 
## 0           1         1      100        100               2.   {
                                                                <Function: foo
## 0           0         2        0          0               3.      A();
                                                             4.      return;
                                                             5.      B();
                                                             6.      C();
                                                             7.      D();
                                                             8.     return;
## 0           0         2        0          0               9.    }
  

示例 3

以下为冗余代码的示例:

      1  int g;
      2  int foo() {
      3    int x;
      4    x = g;
      5    for (int i=0; i<100; i++)
      6        x++;
      7    return x;
      8  }

在低优化级别时,编译器可能为所有行生成代码:

foo:
                         .L900000107:
 /* 000000          3 */         save    %sp,-112,%sp
 /* 0x0004          5 */         sethi   %hi(g),%l1
 /* 0x0008            */         ld      [%l1+%lo(g)],%l3 ! volatile
 /* 0x000c            */         add     %l1,%lo(g),%l2
 /* 0x0010          6 */         st      %g0,[%fp-12]
 /* 0x0014          5 */         st      %l3,[%fp-8]
 /* 0x0018          6 */         ld      [%fp-12],%l4
 /* 0x001c            */         cmp     %l4,100
 /* 0x0020            */         bge,a,pn        %icc,.L900000105
 /* 0x0024          8 */         ld      [%fp-8],%l1
                        .L17:
 /* 0x0028          7 */         ld      [%fp-8],%l1
                         .L900000104:
 /* 0x002c          6 */         ld      [%fp-12],%l3
 /* 0x0030          7 */         add     %l1,1,%l2
 /* 0x0034            */         st      %l2,[%fp-8]
 /* 0x0038          6 */         add     %l3,1,%l4
 /* 0x003c            */         st      %l4,[%fp-12]
 /* 0x0040            */         ld      [%fp-12],%l5
 /* 0x0044            */         cmp     %l5,100
 /* 0x0048            */         bl,a,pn %icc,.L900000104
 /* 0x004c          7 */         ld      [%fp-8],%l1
 /* 0x0050          8 */         ld      [%fp-8],%l1
                         .L900000105:
 /* 0x0054          8 */         st      %l1,[%fp-4]
 /* 0x0058            */         ld      [%fp-4],%i0
 /* 0x005c            */         ret     ! Result =  %i0
 /* 0x0060            */         restore %g0,%g0,%g0

在高优化级别时,大多数可执行的源代码行不具有任何对应的指令:

foo:
 /* 000000          5 */         sethi   %hi(g),%o5
 /* 0x0004            */         ld      [%o5+%lo(g)],%o4
 /* 0x0008          8 */         retl    ! Result =  %o0
 /* 0x000c          5 */         add     %o4,100,%o0

因此,不会针对某些行报告覆盖。

     Excl.       Excl.     Excl.  Excl.      Excl.
    Uncoverage  Function  Instr  Block      Instr
                Count     Exec   Covered %  Covered %
                                                              1. int g;
    0           0         0        0          0               2. int foo() {
                                                              <Function foo>
                                                              3.   int x;
                                                              4.   x = g;
                                                                            
                                                            Source loop below has tag L1
                                                            Induction variable substitution performed on L1
                                                            L1 deleted as dead code
 ## 0           1         3      100        100               5.   for (int i=0; i<100; i++)
                                                              6.       x++;
                                                              7.   return x;
    0           0         1        0          0               8. }