[llvm-dev] Missing coverage instrumentation with trace-pc-guard option
Dmitriy Nikiforov via llvm-dev
llvm-dev at lists.llvm.org
Wed Mar 15 12:21:33 PDT 2017
Hi,
I was trying to get a coverage for sanitizers for my library and then I have encountered a problem that some calls to __sanitizer_coverage_trace_pc_guards are missing in several basic blocks. I made a
reduced reprocase for this (reduced.c in attachments) and built it with '-gline-tables-only -O0 -fsanitize=address -fsanitize-coverage=trace-pc-guard' flags:
clang -gline-tables-only -O0 -fsanitize=address -fsanitize-coverage=trace-pc-guard -S reduced.c
extern void clobber1(int *state_ptr);
extern void clobber2(int *state_ptr);
extern void clobber3(int *state_ptr);
int foo(char c, int state, int threshold) {
while (state < threshold) {
switch (state) {
case 1:
clobber1(&state);
if (c == '*') {
state++;
} else if (c == '/') {
state--; <============== missing __sanitizer_cov_trace_pc_guard call
} else {
clobber1(&state);
goto out;
}
clobber2(&state);
break;
case 2:
clobber3(&state);
break;
}
}
out:
return state;
}
int main(int argc, char **argv) {
return foo(argv[1][2], argc + 4, 255) > 100;
}
After examination of dumped LLVM IR (-print-after-all) I have found that there are no calls of __sanitizer_coverage_trace_pc_guard in 'if.then6' basic block that corresponds to "else if (c == '/')"
fall through case:
sw.bb: ; preds = %while.body
call void @clobber1(i32* %state.addr), !dbg !15
%3 = load i8, i8* %c.addr, align 1, !dbg !16
%conv = sext i8 %3 to i32, !dbg !16
%cmp1 = icmp eq i32 %conv, 42, !dbg !17
br i1 %cmp1, label %if.then, label %if.else, !dbg !16
if.then: ; preds = %sw.bb
call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 8) to i32*)), !dbg !18
call void asm sideeffect "", ""(), !dbg !18
%4 = load i32, i32* %state.addr, align 4, !dbg !18
%inc = add nsw i32 %4, 1, !dbg !18
store i32 %inc, i32* %state.addr, align 4, !dbg !18
br label %if.end8, !dbg !19
if.else: ; preds = %sw.bb
%5 = load i8, i8* %c.addr, align 1, !dbg !20
%conv3 = sext i8 %5 to i32, !dbg !20
%cmp4 = icmp eq i32 %conv3, 47, !dbg !21
br i1 %cmp4, label %if.then6, label %if.else7, !dbg !20
if.then6: ; preds = %if.else <======= no __sanitizer_cov_trace_pc_guard
%6 = load i32, i32* %state.addr, align 4, !dbg !22
%dec = add nsw i32 %6, -1, !dbg !22
store i32 %dec, i32* %state.addr, align 4, !dbg !22
br label %if.end, !dbg !23
if.else7: ; preds = %if.else
call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 12) to i32*)), !dbg !24
call void asm sideeffect "", ""(), !dbg !24
call void @clobber1(i32* %state.addr), !dbg !24
br label %out, !dbg !25
if.end: ; preds = %if.then6
br label %if.end8
if.end8: ; preds = %if.end, %if.then
call void @clobber2(i32* %state.addr), !dbg !26
br label %sw.epilog, !dbg !27
But, if I remove the 'goto out' instruction, then '__sanitizer_cov_trace_pc_guard' call appears in all if clauses as expected.
Is this an intended behavior or some kind of a bug? And if it's intended, how can I deduce a real coverage from these instrumented points?
Thanks,
Dmitriy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reduced.c
Type: text/x-csrc
Size: 623 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170315/65f7417d/attachment.c>
More information about the llvm-dev
mailing list