]> git.proxmox.com Git - rustc.git/blobdiff - src/compiler-rt/lib/msan/msan_report.cc
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / lib / msan / msan_report.cc
index 12bac2e8c064eb664c50ddb687e7de6bbc764ac2..ddb8070282a980ae940014d7047dacd20815a2ab 100644 (file)
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "msan.h"
+#include "msan_chained_origin_depot.h"
+#include "msan_origin.h"
 #include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_flags.h"
@@ -25,9 +27,9 @@ using namespace __sanitizer;
 
 namespace __msan {
 
-class Decorator: private __sanitizer::AnsiColorDecorator {
+class Decorator: public __sanitizer::SanitizerCommonDecorator {
  public:
-  Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
+  Decorator() : SanitizerCommonDecorator() { }
   const char *Warning()    { return Red(); }
   const char *Origin()     { return Magenta(); }
   const char *Name()   { return Green(); }
@@ -44,43 +46,53 @@ static void DescribeStackOrigin(const char *so, uptr pc) {
   Printf(
       "  %sUninitialized value was created by an allocation of '%s%s%s'"
       " in the stack frame of function '%s%s%s'%s\n",
-      d.Origin(), d.Name(), s, d.Origin(), d.Name(),
-      Symbolizer::Get()->Demangle(sep + 1), d.Origin(), d.End());
+      d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(),
+      d.End());
   InternalFree(s);
 
   if (pc) {
     // For some reason function address in LLVM IR is 1 less then the address
     // of the first instruction.
-    pc += 1;
-    StackTrace::PrintStack(&pc, 1);
+    pc = StackTrace::GetNextInstructionPc(pc);
+    StackTrace(&pc, 1).Print();
   }
 }
 
-static void DescribeOrigin(u32 origin) {
-  VPrintf(1, "  raw origin id: %d\n", origin);
-  uptr pc;
-  while (true) {
-    if (const char *so = GetOriginDescrIfStack(origin, &pc)) {
-      DescribeStackOrigin(so, pc);
-      break;
-    }
-    Decorator d;
-    uptr size = 0;
-    const uptr *trace = StackDepotGet(origin, &size);
-    CHECK_GT(size, 0);
-    if (TRACE_IS_CHAINED(trace[size - 1])) {
-      // Linked origin.
-      // FIXME: copied? modified? passed through? observed?
-      Printf("  %sUninitialized value was stored to memory at%s\n", d.Origin(),
-             d.End());
-      StackTrace::PrintStack(trace, size - 1);
-      origin = TRACE_TO_CHAINED_ID(trace[size - 1]);
-    } else {
-      Printf("  %sUninitialized value was created by a heap allocation%s\n",
-             d.Origin(), d.End());
-      StackTrace::PrintStack(trace, size);
-      break;
+static void DescribeOrigin(u32 id) {
+  VPrintf(1, "  raw origin id: %d\n", id);
+  Decorator d;
+  Origin o = Origin::FromRawId(id);
+  while (o.isChainedOrigin()) {
+    StackTrace stack;
+    o = o.getNextChainedOrigin(&stack);
+    Printf("  %sUninitialized value was stored to memory at%s\n", d.Origin(),
+        d.End());
+    stack.Print();
+  }
+  if (o.isStackOrigin()) {
+    uptr pc;
+    const char *so = GetStackOriginDescr(o.getStackId(), &pc);
+    DescribeStackOrigin(so, pc);
+  } else {
+    StackTrace stack = o.getStackTraceForHeapOrigin();
+    switch (stack.tag) {
+      case StackTrace::TAG_ALLOC:
+        Printf("  %sUninitialized value was created by a heap allocation%s\n",
+               d.Origin(), d.End());
+        break;
+      case StackTrace::TAG_DEALLOC:
+        Printf("  %sUninitialized value was created by a heap deallocation%s\n",
+               d.Origin(), d.End());
+        break;
+      case STACK_TRACE_TAG_POISON:
+        Printf("  %sMemory was marked as uninitialized%s\n", d.Origin(),
+               d.End());
+        break;
+      default:
+        Printf("  %sUninitialized value was created%s\n", d.Origin(), d.End());
+        break;
     }
+    stack.Print();
   }
 }
 
@@ -91,7 +103,7 @@ void ReportUMR(StackTrace *stack, u32 origin) {
 
   Decorator d;
   Printf("%s", d.Warning());
-  Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n");
+  Report("WARNING: MemorySanitizer: use-of-uninitialized-value\n");
   Printf("%s", d.End());
   stack->Print();
   if (origin) {
@@ -103,10 +115,28 @@ void ReportUMR(StackTrace *stack, u32 origin) {
 void ReportExpectedUMRNotFound(StackTrace *stack) {
   SpinMutexLock l(&CommonSanitizerReportMutex);
 
-  Printf(" WARNING: Expected use of uninitialized value not found\n");
+  Printf("WARNING: Expected use of uninitialized value not found\n");
   stack->Print();
 }
 
+void ReportStats() {
+  SpinMutexLock l(&CommonSanitizerReportMutex);
+
+  if (__msan_get_track_origins() > 0) {
+    StackDepotStats *stack_depot_stats = StackDepotGetStats();
+    // FIXME: we want this at normal exit, too!
+    // FIXME: but only with verbosity=1 or something
+    Printf("Unique heap origins: %zu\n", stack_depot_stats->n_uniq_ids);
+    Printf("Stack depot allocated bytes: %zu\n", stack_depot_stats->allocated);
+
+    StackDepotStats *chained_origin_depot_stats = ChainedOriginDepotGetStats();
+    Printf("Unique origin histories: %zu\n",
+           chained_origin_depot_stats->n_uniq_ids);
+    Printf("History depot allocated bytes: %zu\n",
+           chained_origin_depot_stats->allocated);
+  }
+}
+
 void ReportAtExitStatistics() {
   SpinMutexLock l(&CommonSanitizerReportMutex);
 
@@ -116,12 +146,6 @@ void ReportAtExitStatistics() {
     Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
     Printf("%s", d.End());
   }
-
-  StackDepotStats *stack_depot_stats = StackDepotGetStats();
-  // FIXME: we want this at normal exit, too!
-  // FIXME: but only with verbosity=1 or something
-  Printf("Unique heap origins: %zu\n", stack_depot_stats->n_uniq_ids);
-  Printf("Stack depot mapped bytes: %zu\n", stack_depot_stats->mapped);
 }
 
 class OriginSet {
@@ -197,7 +221,11 @@ void DescribeMemoryRange(const void *x, uptr size) {
     } else {
       unsigned char v = *(unsigned char *)s;
       if (v) last_quad_poisoned = true;
-      Printf("%02x", v);
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+      Printf("%x%x", v & 0xf, v >> 4);
+#else
+      Printf("%x%x", v >> 4, v & 0xf);
+#endif
     }
     // Group end.
     if (pos % 4 == 3 && with_origins) {
@@ -235,4 +263,15 @@ void DescribeMemoryRange(const void *x, uptr size) {
   }
 }
 
+void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
+                                 uptr offset) {
+  Decorator d;
+  Printf("%s", d.Warning());
+  Printf("%sUninitialized bytes in %s%s%s at offset %zu inside [%p, %zu)%s\n",
+         d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
+         d.End());
+  if (__sanitizer::Verbosity())
+    DescribeMemoryRange(start, size);
+}
+
 }  // namespace __msan