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;
|
||||
Printf("%s", d.Warning());
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: stack-overflow on address %p"
|
||||
" (pc %p bp %p sp %p T%d)\n",
|
||||
"ERROR: AddressSanitizer: %s on address %p"
|
||||
" (pc %p bp %p sp %p T%d)\n", scariness.GetDescription(),
|
||||
(void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
|
||||
Printf("%s", d.EndWarning());
|
||||
scariness.Print();
|
||||
|
@ -35,7 +35,7 @@ void ErrorStackOverflow::Print() {
|
|||
GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
|
||||
common_flags()->fast_unwind_on_fatal);
|
||||
stack.Print();
|
||||
ReportErrorSummary("stack-overflow", &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
}
|
||||
|
||||
static void MaybeDumpInstructionBytes(uptr pc) {
|
||||
|
@ -93,9 +93,9 @@ void ErrorDoubleFree::Print() {
|
|||
Printf("%s", d.Warning());
|
||||
char tname[128];
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: attempting double-free on %p in "
|
||||
"ERROR: AddressSanitizer: attempting %s on %p in "
|
||||
"thread T%d%s:\n",
|
||||
addr_description.addr, tid,
|
||||
scariness.GetDescription(), addr_description.addr, tid,
|
||||
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
||||
Printf("%s", d.EndWarning());
|
||||
scariness.Print();
|
||||
|
@ -103,7 +103,7 @@ void ErrorDoubleFree::Print() {
|
|||
second_free_stack->top_frame_bp);
|
||||
stack.Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("double-free", &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
}
|
||||
|
||||
void ErrorNewDeleteSizeMismatch::Print() {
|
||||
|
@ -111,9 +111,9 @@ void ErrorNewDeleteSizeMismatch::Print() {
|
|||
Printf("%s", d.Warning());
|
||||
char tname[128];
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
|
||||
"ERROR: AddressSanitizer: %s on %p in thread "
|
||||
"T%d%s:\n",
|
||||
addr_description.addr, tid,
|
||||
scariness.GetDescription(), addr_description.addr, tid,
|
||||
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
|
||||
Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
|
||||
Printf(
|
||||
|
@ -125,7 +125,7 @@ void ErrorNewDeleteSizeMismatch::Print() {
|
|||
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
|
||||
stack.Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("new-delete-type-mismatch", &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
Report(
|
||||
"HINT: if you don't care about these errors you may set "
|
||||
"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);
|
||||
stack.Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("bad-free", &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
}
|
||||
|
||||
void ErrorAllocTypeMismatch::Print() {
|
||||
|
@ -157,7 +157,8 @@ void ErrorAllocTypeMismatch::Print() {
|
|||
CHECK_NE(alloc_type, dealloc_type);
|
||||
Decorator d;
|
||||
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],
|
||||
addr_description.addr);
|
||||
Printf("%s", d.EndWarning());
|
||||
|
@ -166,7 +167,7 @@ void ErrorAllocTypeMismatch::Print() {
|
|||
GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
|
||||
stack.Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("alloc-dealloc-mismatch", &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
Report(
|
||||
"HINT: if you don't care about these errors you may set "
|
||||
"ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
|
||||
|
@ -182,7 +183,7 @@ void ErrorMallocUsableSizeNotOwned::Print() {
|
|||
Printf("%s", d.EndWarning());
|
||||
stack->Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("bad-malloc_usable_size", stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
|
||||
|
@ -195,7 +196,7 @@ void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
|
|||
Printf("%s", d.EndWarning());
|
||||
stack->Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorStringFunctionMemoryRangesOverlap::Print() {
|
||||
|
@ -220,13 +221,13 @@ void ErrorStringFunctionMemoryRangesOverlap::Print() {
|
|||
void ErrorStringFunctionSizeOverflow::Print() {
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
const char *bug_type = "negative-size-param";
|
||||
Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
|
||||
Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
|
||||
scariness.GetDescription(), size);
|
||||
Printf("%s", d.EndWarning());
|
||||
scariness.Print();
|
||||
stack->Print();
|
||||
addr_description.Print();
|
||||
ReportErrorSummary(bug_type, stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorBadParamsToAnnotateContiguousContainer::Print() {
|
||||
|
@ -242,13 +243,14 @@ void ErrorBadParamsToAnnotateContiguousContainer::Print() {
|
|||
if (!IsAligned(beg, granularity))
|
||||
Report("ERROR: beg is not aligned by %d\n", granularity);
|
||||
stack->Print();
|
||||
ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), stack);
|
||||
}
|
||||
|
||||
void ErrorODRViolation::Print() {
|
||||
Decorator d;
|
||||
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());
|
||||
InternalScopedString g1_loc(256), g2_loc(256);
|
||||
PrintGlobalLocation(&g1_loc, global1);
|
||||
|
@ -268,23 +270,22 @@ void ErrorODRViolation::Print() {
|
|||
"HINT: if you don't care about these errors you may set "
|
||||
"ASAN_OPTIONS=detect_odr_violation=0\n");
|
||||
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());
|
||||
ReportErrorSummary(error_msg.data());
|
||||
}
|
||||
|
||||
void ErrorInvalidPointerPair::Print() {
|
||||
const char *bug_type = "invalid-pointer-pair";
|
||||
Decorator d;
|
||||
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());
|
||||
Printf("%s", d.EndWarning());
|
||||
GET_STACK_TRACE_FATAL(pc, bp);
|
||||
stack.Print();
|
||||
addr1_description.Print();
|
||||
addr2_description.Print();
|
||||
ReportErrorSummary(bug_type, &stack);
|
||||
ReportErrorSummary(scariness.GetDescription(), &stack);
|
||||
}
|
||||
|
||||
static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
|
||||
|
|
|
@ -172,6 +172,7 @@ struct ErrorMallocUsableSizeNotOwned : ErrorBase {
|
|||
stack(stack_),
|
||||
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
||||
scariness.Clear();
|
||||
scariness.Scare(10, "bad-malloc_usable_size");
|
||||
}
|
||||
void Print();
|
||||
};
|
||||
|
@ -189,6 +190,7 @@ struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
|
|||
stack(stack_),
|
||||
addr_description(addr, /*shouldLockThreadRegistry=*/false) {
|
||||
scariness.Clear();
|
||||
scariness.Scare(10, "bad-__sanitizer_get_allocated_size");
|
||||
}
|
||||
void Print();
|
||||
};
|
||||
|
@ -258,7 +260,10 @@ struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
|
|||
beg(beg_),
|
||||
end(end_),
|
||||
old_mid(old_mid_),
|
||||
new_mid(new_mid_) {}
|
||||
new_mid(new_mid_) {
|
||||
scariness.Clear();
|
||||
scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container");
|
||||
}
|
||||
void Print();
|
||||
};
|
||||
|
||||
|
@ -274,7 +279,10 @@ struct ErrorODRViolation : ErrorBase {
|
|||
global1(*g1),
|
||||
global2(*g2),
|
||||
stack_id1(stack_id1_),
|
||||
stack_id2(stack_id2_) {}
|
||||
stack_id2(stack_id2_) {
|
||||
scariness.Clear();
|
||||
scariness.Scare(10, "odr-violation");
|
||||
}
|
||||
void Print();
|
||||
};
|
||||
|
||||
|
@ -292,7 +300,10 @@ struct ErrorInvalidPointerPair : ErrorBase {
|
|||
bp(bp_),
|
||||
sp(sp_),
|
||||
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();
|
||||
};
|
||||
|
||||
|
@ -350,6 +361,7 @@ struct ErrorDescription {
|
|||
// 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.
|
||||
union {
|
||||
ErrorBase Base;
|
||||
ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
|
||||
};
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ void __asan_describe_address(uptr addr) {
|
|||
}
|
||||
|
||||
int __asan_report_present() {
|
||||
return ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric;
|
||||
return ScopedInErrorReport::CurrentError().kind != kErrorKindInvalid;
|
||||
}
|
||||
|
||||
uptr __asan_get_report_pc() {
|
||||
|
@ -449,9 +449,11 @@ uptr __asan_get_report_sp() {
|
|||
}
|
||||
|
||||
uptr __asan_get_report_address() {
|
||||
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
|
||||
return ScopedInErrorReport::CurrentError()
|
||||
.Generic.addr_description.Address();
|
||||
ErrorDescription &err = ScopedInErrorReport::CurrentError();
|
||||
if (err.kind == kErrorKindGeneric)
|
||||
return err.Generic.addr_description.Address();
|
||||
else if (err.kind == kErrorKindDoubleFree)
|
||||
return err.DoubleFree.addr_description.addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -470,7 +472,7 @@ uptr __asan_get_report_access_size() {
|
|||
const char *__asan_get_report_description() {
|
||||
if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
|
||||
return ScopedInErrorReport::CurrentError().Generic.bug_descr;
|
||||
return nullptr;
|
||||
return ScopedInErrorReport::CurrentError().Base.scariness.GetDescription();
|
||||
}
|
||||
|
||||
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