forked from OSchip/llvm-project
[asan] Provide bug descriptions for all reports (not just ErrorGeneric)
Differential Revision: https://reviews.llvm.org/D27012 llvm-svn: 288065
This commit is contained in:
parent
b3d93889f5
commit
48090f5b82
|
@ -26,8 +26,8 @@ void ErrorStackOverflow::Print() {
|
||||||
Decorator d;
|
Decorator d;
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
Report(
|
Report(
|
||||||
"ERROR: AddressSanitizer: stack-overflow on address %p"
|
"ERROR: AddressSanitizer: %s on address %p"
|
||||||
" (pc %p bp %p sp %p T%d)\n",
|
" (pc %p bp %p sp %p T%d)\n", scariness.GetDescription(),
|
||||||
(void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
|
(void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
scariness.Print();
|
scariness.Print();
|
||||||
|
@ -35,7 +35,7 @@ void ErrorStackOverflow::Print() {
|
||||||
GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
|
GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
|
||||||
common_flags()->fast_unwind_on_fatal);
|
common_flags()->fast_unwind_on_fatal);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
ReportErrorSummary("stack-overflow", &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MaybeDumpInstructionBytes(uptr pc) {
|
static void MaybeDumpInstructionBytes(uptr pc) {
|
||||||
|
@ -93,9 +93,9 @@ void ErrorDoubleFree::Print() {
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
char tname[128];
|
char tname[128];
|
||||||
Report(
|
Report(
|
||||||
"ERROR: AddressSanitizer: attempting double-free on %p in "
|
"ERROR: AddressSanitizer: attempting %s on %p in "
|
||||||
"thread T%d%s:\n",
|
"thread T%d%s:\n",
|
||||||
addr_description.addr, tid,
|
scariness.GetDescription(), addr_description.addr, tid,
|
||||||
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
scariness.Print();
|
scariness.Print();
|
||||||
|
@ -103,7 +103,7 @@ void ErrorDoubleFree::Print() {
|
||||||
second_free_stack->top_frame_bp);
|
second_free_stack->top_frame_bp);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("double-free", &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorNewDeleteSizeMismatch::Print() {
|
void ErrorNewDeleteSizeMismatch::Print() {
|
||||||
|
@ -111,9 +111,9 @@ void ErrorNewDeleteSizeMismatch::Print() {
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
char tname[128];
|
char tname[128];
|
||||||
Report(
|
Report(
|
||||||
"ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
|
"ERROR: AddressSanitizer: %s on %p in thread "
|
||||||
"T%d%s:\n",
|
"T%d%s:\n",
|
||||||
addr_description.addr, tid,
|
scariness.GetDescription(), addr_description.addr, tid,
|
||||||
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
||||||
Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
|
Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
|
||||||
Printf(
|
Printf(
|
||||||
|
@ -125,7 +125,7 @@ void ErrorNewDeleteSizeMismatch::Print() {
|
||||||
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
|
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("new-delete-type-mismatch", &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
Report(
|
Report(
|
||||||
"HINT: if you don't care about these errors you may set "
|
"HINT: if you don't care about these errors you may set "
|
||||||
"ASAN_OPTIONS=new_delete_type_mismatch=0\n");
|
"ASAN_OPTIONS=new_delete_type_mismatch=0\n");
|
||||||
|
@ -146,7 +146,7 @@ void ErrorFreeNotMalloced::Print() {
|
||||||
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
|
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("bad-free", &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorAllocTypeMismatch::Print() {
|
void ErrorAllocTypeMismatch::Print() {
|
||||||
|
@ -157,7 +157,8 @@ void ErrorAllocTypeMismatch::Print() {
|
||||||
CHECK_NE(alloc_type, dealloc_type);
|
CHECK_NE(alloc_type, dealloc_type);
|
||||||
Decorator d;
|
Decorator d;
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n",
|
Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
|
||||||
|
scariness.GetDescription(),
|
||||||
alloc_names[alloc_type], dealloc_names[dealloc_type],
|
alloc_names[alloc_type], dealloc_names[dealloc_type],
|
||||||
addr_description.addr);
|
addr_description.addr);
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
|
@ -166,7 +167,7 @@ void ErrorAllocTypeMismatch::Print() {
|
||||||
GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
|
GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("alloc-dealloc-mismatch", &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
Report(
|
Report(
|
||||||
"HINT: if you don't care about these errors you may set "
|
"HINT: if you don't care about these errors you may set "
|
||||||
"ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
|
"ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
|
||||||
|
@ -182,7 +183,7 @@ void ErrorMallocUsableSizeNotOwned::Print() {
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
stack->Print();
|
stack->Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("bad-malloc_usable_size", stack);
|
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
|
void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
|
||||||
|
@ -195,7 +196,7 @@ void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
stack->Print();
|
stack->Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack);
|
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorStringFunctionMemoryRangesOverlap::Print() {
|
void ErrorStringFunctionMemoryRangesOverlap::Print() {
|
||||||
|
@ -220,13 +221,13 @@ void ErrorStringFunctionMemoryRangesOverlap::Print() {
|
||||||
void ErrorStringFunctionSizeOverflow::Print() {
|
void ErrorStringFunctionSizeOverflow::Print() {
|
||||||
Decorator d;
|
Decorator d;
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
const char *bug_type = "negative-size-param";
|
Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
|
||||||
Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
|
scariness.GetDescription(), size);
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
scariness.Print();
|
scariness.Print();
|
||||||
stack->Print();
|
stack->Print();
|
||||||
addr_description.Print();
|
addr_description.Print();
|
||||||
ReportErrorSummary(bug_type, stack);
|
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorBadParamsToAnnotateContiguousContainer::Print() {
|
void ErrorBadParamsToAnnotateContiguousContainer::Print() {
|
||||||
|
@ -242,13 +243,14 @@ void ErrorBadParamsToAnnotateContiguousContainer::Print() {
|
||||||
if (!IsAligned(beg, granularity))
|
if (!IsAligned(beg, granularity))
|
||||||
Report("ERROR: beg is not aligned by %d\n", granularity);
|
Report("ERROR: beg is not aligned by %d\n", granularity);
|
||||||
stack->Print();
|
stack->Print();
|
||||||
ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
|
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorODRViolation::Print() {
|
void ErrorODRViolation::Print() {
|
||||||
Decorator d;
|
Decorator d;
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
Report("ERROR: AddressSanitizer: odr-violation (%p):\n", global1.beg);
|
Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
|
||||||
|
global1.beg);
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
InternalScopedString g1_loc(256), g2_loc(256);
|
InternalScopedString g1_loc(256), g2_loc(256);
|
||||||
PrintGlobalLocation(&g1_loc, global1);
|
PrintGlobalLocation(&g1_loc, global1);
|
||||||
|
@ -268,23 +270,22 @@ void ErrorODRViolation::Print() {
|
||||||
"HINT: if you don't care about these errors you may set "
|
"HINT: if you don't care about these errors you may set "
|
||||||
"ASAN_OPTIONS=detect_odr_violation=0\n");
|
"ASAN_OPTIONS=detect_odr_violation=0\n");
|
||||||
InternalScopedString error_msg(256);
|
InternalScopedString error_msg(256);
|
||||||
error_msg.append("odr-violation: global '%s' at %s",
|
error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
|
||||||
MaybeDemangleGlobalName(global1.name), g1_loc.data());
|
MaybeDemangleGlobalName(global1.name), g1_loc.data());
|
||||||
ReportErrorSummary(error_msg.data());
|
ReportErrorSummary(error_msg.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorInvalidPointerPair::Print() {
|
void ErrorInvalidPointerPair::Print() {
|
||||||
const char *bug_type = "invalid-pointer-pair";
|
|
||||||
Decorator d;
|
Decorator d;
|
||||||
Printf("%s", d.Warning());
|
Printf("%s", d.Warning());
|
||||||
Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n",
|
Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
|
||||||
addr1_description.Address(), addr2_description.Address());
|
addr1_description.Address(), addr2_description.Address());
|
||||||
Printf("%s", d.EndWarning());
|
Printf("%s", d.EndWarning());
|
||||||
GET_STACK_TRACE_FATAL(pc, bp);
|
GET_STACK_TRACE_FATAL(pc, bp);
|
||||||
stack.Print();
|
stack.Print();
|
||||||
addr1_description.Print();
|
addr1_description.Print();
|
||||||
addr2_description.Print();
|
addr2_description.Print();
|
||||||
ReportErrorSummary(bug_type, &stack);
|
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
|
static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
|
||||||
|
|
|
@ -172,6 +172,7 @@ struct ErrorMallocUsableSizeNotOwned : ErrorBase {
|
||||||
stack(stack_),
|
stack(stack_),
|
||||||
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
||||||
scariness.Clear();
|
scariness.Clear();
|
||||||
|
scariness.Scare(10, "bad-malloc_usable_size");
|
||||||
}
|
}
|
||||||
void Print();
|
void Print();
|
||||||
};
|
};
|
||||||
|
@ -189,6 +190,7 @@ struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
|
||||||
stack(stack_),
|
stack(stack_),
|
||||||
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
||||||
scariness.Clear();
|
scariness.Clear();
|
||||||
|
scariness.Scare(10, "bad-__sanitizer_get_allocated_size");
|
||||||
}
|
}
|
||||||
void Print();
|
void Print();
|
||||||
};
|
};
|
||||||
|
@ -258,7 +260,10 @@ struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
|
||||||
beg(beg_),
|
beg(beg_),
|
||||||
end(end_),
|
end(end_),
|
||||||
old_mid(old_mid_),
|
old_mid(old_mid_),
|
||||||
new_mid(new_mid_) {}
|
new_mid(new_mid_) {
|
||||||
|
scariness.Clear();
|
||||||
|
scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container");
|
||||||
|
}
|
||||||
void Print();
|
void Print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,7 +279,10 @@ struct ErrorODRViolation : ErrorBase {
|
||||||
global1(*g1),
|
global1(*g1),
|
||||||
global2(*g2),
|
global2(*g2),
|
||||||
stack_id1(stack_id1_),
|
stack_id1(stack_id1_),
|
||||||
stack_id2(stack_id2_) {}
|
stack_id2(stack_id2_) {
|
||||||
|
scariness.Clear();
|
||||||
|
scariness.Scare(10, "odr-violation");
|
||||||
|
}
|
||||||
void Print();
|
void Print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -292,7 +300,10 @@ struct ErrorInvalidPointerPair : ErrorBase {
|
||||||
bp(bp_),
|
bp(bp_),
|
||||||
sp(sp_),
|
sp(sp_),
|
||||||
addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
|
addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
|
||||||
addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
|
addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {
|
||||||
|
scariness.Clear();
|
||||||
|
scariness.Scare(10, "invalid-pointer-pair");
|
||||||
|
}
|
||||||
void Print();
|
void Print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -350,6 +361,7 @@ struct ErrorDescription {
|
||||||
// We can add a wrapper around it to make it "more c++-like", but that would
|
// We can add a wrapper around it to make it "more c++-like", but that would
|
||||||
// add a lot of code and the benefit wouldn't be that big.
|
// add a lot of code and the benefit wouldn't be that big.
|
||||||
union {
|
union {
|
||||||
|
ErrorBase Base;
|
||||||
ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
|
ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,7 @@ void __asan_describe_address(uptr addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int __asan_report_present() {
|
int __asan_report_present() {
|
||||||
return ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric;
|
return ScopedInErrorReport::CurrentError().kind != kErrorKindInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr __asan_get_report_pc() {
|
uptr __asan_get_report_pc() {
|
||||||
|
@ -449,9 +449,11 @@ uptr __asan_get_report_sp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr __asan_get_report_address() {
|
uptr __asan_get_report_address() {
|
||||||
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
|
ErrorDescription &err = ScopedInErrorReport::CurrentError();
|
||||||
return ScopedInErrorReport::CurrentError()
|
if (err.kind == kErrorKindGeneric)
|
||||||
.Generic.addr_description.Address();
|
return err.Generic.addr_description.Address();
|
||||||
|
else if (err.kind == kErrorKindDoubleFree)
|
||||||
|
return err.DoubleFree.addr_description.addr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +472,7 @@ uptr __asan_get_report_access_size() {
|
||||||
const char *__asan_get_report_description() {
|
const char *__asan_get_report_description() {
|
||||||
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
|
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
|
||||||
return ScopedInErrorReport::CurrentError().Generic.bug_descr;
|
return ScopedInErrorReport::CurrentError().Generic.bug_descr;
|
||||||
return nullptr;
|
return ScopedInErrorReport::CurrentError().Base.scariness.GetDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
#include <sanitizer/asan_interface.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char *heap_ptr;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
heap_ptr = (char *)malloc(10);
|
||||||
|
fprintf(stderr, "heap_ptr: %p\n", heap_ptr);
|
||||||
|
// CHECK: heap_ptr: 0x[[ADDR:[0-9a-f]+]]
|
||||||
|
|
||||||
|
free(heap_ptr);
|
||||||
|
free(heap_ptr); // BOOM
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __asan_on_error() {
|
||||||
|
int present = __asan_report_present();
|
||||||
|
void *addr = __asan_get_report_address();
|
||||||
|
const char *description = __asan_get_report_description();
|
||||||
|
|
||||||
|
fprintf(stderr, "%s\n", (present == 1) ? "report present" : "");
|
||||||
|
// CHECK: report present
|
||||||
|
fprintf(stderr, "addr: %p\n", addr);
|
||||||
|
// CHECK: addr: {{0x0*}}[[ADDR]]
|
||||||
|
fprintf(stderr, "description: %s\n", description);
|
||||||
|
// CHECK: description: double-free
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: AddressSanitizer: attempting double-free on {{0x0*}}[[ADDR]] in thread T0
|
Loading…
Reference in New Issue