[asan] Reify ErrorNewDeleteSizeMismatch
authorFilipe Cabecinhas <me@filcab.net>
Wed, 7 Sep 2016 14:20:54 +0000 (14:20 +0000)
committerFilipe Cabecinhas <me@filcab.net>
Wed, 7 Sep 2016 14:20:54 +0000 (14:20 +0000)
Summary: Keep reifying other errors.

Reviewers: kcc, samsonov

Subscribers: llvm-commits, kubabrecka

Differential Revision: https://reviews.llvm.org/D23874

llvm-svn: 280812

compiler-rt/lib/asan/asan_allocator.cc
compiler-rt/lib/asan/asan_errors.cc
compiler-rt/lib/asan/asan_errors.h
compiler-rt/lib/asan/asan_report.cc
compiler-rt/lib/asan/asan_report.h

index 9f673a2..aa08969 100644 (file)
@@ -530,7 +530,7 @@ struct Allocator {
 
     if (delete_size && flags()->new_delete_type_mismatch &&
         delete_size != m->UsedSize()) {
-      ReportNewDeleteSizeMismatch(p, m->UsedSize(), delete_size, stack);
+      ReportNewDeleteSizeMismatch(p, delete_size, stack);
     }
 
     QuarantineChunk(m, ptr, stack, alloc_type);
index 3969f83..c260311 100644 (file)
@@ -52,4 +52,29 @@ void ErrorDoubleFree::Print() {
   ReportErrorSummary("double-free", &stack);
 }
 
+void ErrorNewDeleteSizeMismatch::Print() {
+  Decorator d;
+  Printf("%s", d.Warning());
+  char tname[128];
+  Report(
+      "ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
+      "T%d%s:\n",
+      addr_description.addr, tid,
+      ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
+  Printf("%s  object passed to delete has wrong type:\n", d.EndWarning());
+  Printf(
+      "  size of the allocated type:   %zd bytes;\n"
+      "  size of the deallocated type: %zd bytes.\n",
+      addr_description.chunk_access.chunk_size, delete_size);
+  CHECK_GT(free_stack->size, 0);
+  scariness.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);
+  Report(
+      "HINT: if you don't care about these errors you may set "
+      "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
+}
+
 }  // namespace __asan
index c8fa4c1..5fdd79e 100644 (file)
@@ -62,10 +62,30 @@ struct ErrorDoubleFree : ErrorBase {
   void Print();
 };
 
+struct ErrorNewDeleteSizeMismatch : ErrorBase {
+  u32 tid;
+  HeapAddressDescription addr_description;
+  uptr delete_size;
+  // ErrorNewDeleteSizeMismatch doesn't own the stack trace.
+  BufferedStackTrace *free_stack;
+  // VS2013 doesn't implement unrestricted unions, so we need a trivial default
+  // constructor
+  ErrorNewDeleteSizeMismatch() = default;
+  ErrorNewDeleteSizeMismatch(uptr addr, u32 tid_, uptr delete_size_,
+                             BufferedStackTrace *stack)
+      : tid(tid_), delete_size(delete_size_), free_stack(stack) {
+    GetHeapAddressInformation(addr, 1, &addr_description);
+    scariness.Clear();
+    scariness.Scare(10, "new-delete-type-mismatch");
+  }
+  void Print();
+};
+
 enum ErrorKind {
   kErrorKindInvalid = 0,
   kErrorKindStackOverflow,
   kErrorKindDoubleFree,
+  kErrorKindNewDeleteSizeMismatch,
 };
 
 struct ErrorDescription {
@@ -78,6 +98,7 @@ struct ErrorDescription {
   union {
     ErrorStackOverflow stack_overflow;
     ErrorDoubleFree double_free;
+    ErrorNewDeleteSizeMismatch new_delete_size_mismatch;
   };
   ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
   ErrorDescription(const ErrorStackOverflow &e)  // NOLINT
@@ -86,6 +107,9 @@ struct ErrorDescription {
   ErrorDescription(const ErrorDoubleFree &e)  // NOLINT
       : kind(kErrorKindDoubleFree),
         double_free(e) {}
+  ErrorDescription(const ErrorNewDeleteSizeMismatch &e)  // NOLINT
+      : kind(kErrorKindNewDeleteSizeMismatch),
+        new_delete_size_mismatch(e) {}
 
   bool IsValid() { return kind != kErrorKindInvalid; }
   void Print() {
@@ -96,6 +120,9 @@ struct ErrorDescription {
       case kErrorKindDoubleFree:
         double_free.Print();
         return;
+      case kErrorKindNewDeleteSizeMismatch:
+        new_delete_size_mismatch.Print();
+        return;
       case kErrorKindInvalid:
         CHECK(0);
     }
index d4dfdc9..a629f3f 100644 (file)
@@ -392,29 +392,12 @@ void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
   in_report.ReportError(error);
 }
 
-void ReportNewDeleteSizeMismatch(uptr addr, uptr alloc_size, uptr delete_size,
+void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
                                  BufferedStackTrace *free_stack) {
   ScopedInErrorReport in_report;
-  Decorator d;
-  Printf("%s", d.Warning());
-  char tname[128];
-  u32 curr_tid = GetCurrentTidOrInvalid();
-  Report("ERROR: AddressSanitizer: new-delete-type-mismatch on %p in "
-         "thread T%d%s:\n",
-         addr, curr_tid,
-         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
-  Printf("%s  object passed to delete has wrong type:\n", d.EndWarning());
-  Printf("  size of the allocated type:   %zd bytes;\n"
-         "  size of the deallocated type: %zd bytes.\n",
-         alloc_size, delete_size);
-  CHECK_GT(free_stack->size, 0);
-  ScarinessScore::PrintSimple(10, "new-delete-type-mismatch");
-  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
-  stack.Print();
-  DescribeAddressIfHeap(addr);
-  ReportErrorSummary("new-delete-type-mismatch", &stack);
-  Report("HINT: if you don't care about these errors you may set "
-         "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
+  ErrorNewDeleteSizeMismatch error(addr, GetCurrentTidOrInvalid(), delete_size,
+                                   free_stack);
+  in_report.ReportError(error);
 }
 
 void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) {
index 871bf64..adf18f3 100644 (file)
@@ -52,7 +52,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
                         uptr access_size, u32 exp, bool fatal);
 void ReportStackOverflow(const SignalContext &sig);
 void ReportDeadlySignal(const char *description, const SignalContext &sig);
-void ReportNewDeleteSizeMismatch(uptr addr, uptr alloc_size, uptr delete_size,
+void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
                                  BufferedStackTrace *free_stack);
 void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
 void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);