本节介绍在使用 uncover 时的已知限制。
uncover 实用程序只能检测使用 uncover 的要求中已介绍的代码。无注释代码可能来自链接到二进制文件的汇编语言代码,或者来自使用早于本节所列版本的编译器或操作系统编译的模块。
uncover 无法检测汇编语言模块或包含 asm 语句或 .il 模板的函数。
uncover 与使用以下任一编译器选项生成的二进制文件不兼容:
–p
–pg
–qp
–xpg
–xlinkopt
uncover 实用程序可处理计算机代码。它会查找计算机指令的覆盖,然后将此覆盖与源代码相关联。某些源代码语句没有关联的计算机指令,因此,uncover 看上去似乎并未报告这些语句的覆盖。
示例 5 简单示例考虑以下代码片段:
#define A 100 #define B 200 ... if (A>B) { ... }
您可能希望使用 uncover 报告 if 语句的非零执行计数。但是,编译器可能会删除此代码。uncover 不会在检测过程中检测到它,因此不会报告这些指令的覆盖信息。
示例 6 死代码示例以下示例显示了死代码:
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 行到第 7 行报告覆盖。
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. }示例 7 冗余代码示例
以下示例显示了冗余代码:
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. }