Oracle® Solaris Studio 12.4: Discover and Uncover User's Guide

Exit Print View

Updated: December 2015
 
 

Limitations When Using uncover

This section describes known limitations when using uncover.

Only Annotated Code Can Be Instrumented

The uncover utility 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.

uncover cannot instrument assembly language modules or functions that contain asm statements or .il templates.

Compiler Options Affect Generated Code

uncover is incompatible with binaries built with any of the following compiler options:

  • –p

  • –pg

  • –qp

  • –xpg

  • –xlinkopt

Machine Instructions Might Differ From Source Code

The uncover utility 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 4  Simple Example

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. However, the compiler is likely to remove this code. uncover will not detect it during instrumentation and no coverage will be reported for these instructions.

Example 5  Dead Code Example

The following example shows 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

Therefore, 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 6  Redundant Code Example

The following example shows 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 can 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

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