JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris Studio 12.3: Discover and Uncover User's Guide     Oracle Solaris Studio 12.3 Information Library
search filter icon
search icon

Document Information

Preface

1.  Introduction

2.  Memory Error Discovery Tool (Discover)

3.  Code Coverage Tool (Uncover)

Requirements for Using Uncover

Using Uncover

Instrumenting the Binary

Running the Instrumented Binary

Generating and Viewing the Coverage Report

Examples

Understanding the Coverage Report in the Performance Analyzer

The Functions Tab

The Uncoverage Counter

The Function Count Counter

The Instr Exec Counter

The Block Covered % Counter

The Instr Covered % Counter

The Source Tab

The Disassembly Tab

The Inst-Freq Tab

Understanding the ASCII Coverage Report

Understanding the HTML Coverage Report

Limitations When Using Uncover

Only Annotated Code Can Be Instrumented

Machine Instructions Might Differ From Source Code

Example 1

Example 2

Example 3

Index

Limitations When Using Uncover

Only Annotated Code Can Be Instrumented

Uncover can instrument only code that has been prepared as described in Requirements for Using Uncover. Non-annotated code might come from assembly language code linked into the binary, or from modules compiled with older compilers or operating systems than those listed in that section.

Specifically excluded from preparation are assembly language modules and functions that contain asm statements or .il templates.

Machine Instructions Might Differ From Source Code

Uncover operates on machine code. It finds coverage of machine instructions and then correlates this coverage with source code. Some source code statements do not have associated machine instructions, so Uncover might appear to not report coverage for such statements.

Example 1

Consider the following code fragment:

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

You might expect Uncover to report a non-zero execution count for the if statement, but the compiler is likely to remove this code, so Uncover will not see it during instrumentation. So no coverage will be reported for these instructions.

Example 2

The following is an example of dead code:

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

Corresponding assembly shows that calls to B,C,D are deleted because this code is never executed.

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

So no coverage will be reported for lines 5 through 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.    }
  

Example 3

The following is an example of redundant code:

      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  }

At low optimization levels, the compiler may generate code for all the lines:

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

At high optimization levels, most of the executable source lines do not have any corresponding instructions :

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

So no coverage will be reported for some lines.

     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. }