Index: lib/asan/asan_errors.h =================================================================== --- lib/asan/asan_errors.h +++ lib/asan/asan_errors.h @@ -141,12 +141,35 @@ void Print(); }; +struct ErrorAllocTypeMismatch : ErrorBase { + u32 tid; + HeapAddressDescription addr_description; + // ErrorAllocTypeMismatch doesn't own the stack trace. + BufferedStackTrace *dealloc_stack; + AllocType alloc_type, dealloc_type; + // VS2013 doesn't implement unrestricted unions, so we need a trivial default + // constructor + ErrorAllocTypeMismatch() = default; + ErrorAllocTypeMismatch(uptr addr, u32 tid_, BufferedStackTrace *stack, + AllocType alloc_type_, AllocType dealloc_type_) + : tid(tid_), + dealloc_stack(stack), + alloc_type(alloc_type_), + dealloc_type(dealloc_type_) { + GetHeapAddressInformation(addr, 1, &addr_description); + scariness.Clear(); + scariness.Scare(10, "alloc-dealloc-mismatch"); + }; + void Print(); +}; + #define FOR_EACH_ERROR_KIND_MEMBER_NAME_PAIR(macro) \ macro(StackOverflow, stack_overflow) \ macro(DeadlySignal, deadly_signal) \ macro(DoubleFree, double_free) \ macro(NewDeleteSizeMismatch, new_delete_size_mismatch) \ - macro(FreeNotMalloced, free_not_malloced) + macro(FreeNotMalloced, free_not_malloced) \ + macro(AllocTypeMismatch, alloc_type_mismatch) enum ErrorKind { kErrorKindInvalid = 0, Index: lib/asan/asan_errors.cc =================================================================== --- lib/asan/asan_errors.cc +++ lib/asan/asan_errors.cc @@ -141,4 +141,27 @@ ReportErrorSummary("bad-free", &stack); } +void ErrorAllocTypeMismatch::Print() { + static const char *alloc_names[] = {"INVALID", "malloc", "operator new", + "operator new []"}; + static const char *dealloc_names[] = {"INVALID", "free", "operator delete", + "operator delete []"}; + CHECK_NE(alloc_type, dealloc_type); + Decorator d; + Printf("%s", d.Warning()); + Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", + alloc_names[alloc_type], dealloc_names[dealloc_type], + addr_description.addr); + Printf("%s", d.EndWarning()); + CHECK_GT(dealloc_stack->size, 0); + scariness.Print(); + GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp); + stack.Print(); + addr_description.Print(); + ReportErrorSummary("alloc-dealloc-mismatch", &stack); + Report( + "HINT: if you don't care about these errors you may set " + "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); +} + } // namespace __asan Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -357,25 +357,10 @@ void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack, AllocType alloc_type, AllocType dealloc_type) { - static const char *alloc_names[] = - {"INVALID", "malloc", "operator new", "operator new []"}; - static const char *dealloc_names[] = - {"INVALID", "free", "operator delete", "operator delete []"}; - CHECK_NE(alloc_type, dealloc_type); ScopedInErrorReport in_report; - Decorator d; - Printf("%s", d.Warning()); - Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", - alloc_names[alloc_type], dealloc_names[dealloc_type], addr); - Printf("%s", d.EndWarning()); - CHECK_GT(free_stack->size, 0); - ScarinessScore::PrintSimple(10, "alloc-dealloc-mismatch"); - GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); - stack.Print(); - DescribeAddressIfHeap(addr); - ReportErrorSummary("alloc-dealloc-mismatch", &stack); - Report("HINT: if you don't care about these errors you may set " - "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); + ErrorAllocTypeMismatch error(addr, GetCurrentTidOrInvalid(), free_stack, + alloc_type, dealloc_type); + in_report.ReportError(error); } void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack) {