[compiler-rt] r204152 - [msan] Origin tracking with history, compiler-rt part.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Mar 18 06:45:20 PDT 2014


Author: eugenis
Date: Tue Mar 18 08:45:19 2014
New Revision: 204152

URL: http://llvm.org/viewvc/llvm-project?rev=204152&view=rev
Log:
[msan] Origin tracking with history, compiler-rt part.

Compiler-rt part of MSan implementation of advanced origin tracking,
when we record not only creation point, but all locations where
an uninitialized value was stored to memory, too.

Added:
    compiler-rt/trunk/test/msan/chained_origin.cc   (with props)
    compiler-rt/trunk/test/msan/chained_origin_memcpy.cc   (with props)
Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/msan/msan_interface_internal.h
    compiler-rt/trunk/lib/msan/msan_report.cc

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=204152&r1=204151&r2=204152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Tue Mar 18 08:45:19 2014
@@ -20,6 +20,7 @@
 #include "sanitizer_common/sanitizer_procmaps.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
 
 
 // ACHTUNG! No system header includes in this file.
@@ -234,6 +235,13 @@ const char *GetOriginDescrIfStack(u32 id
   return StackOriginDescr[id];
 }
 
+u32 ChainOrigin(u32 id, StackTrace *stack) {
+  uptr idx = Min(stack->size, kStackTraceMax - 1);
+  stack->trace[idx] = TRACE_MAKE_CHAINED(id);
+  u32 new_id = StackDepotPut(stack->trace, idx + 1);
+  return new_id;
+}
+
 }  // namespace __msan
 
 // Interface.
@@ -472,6 +480,11 @@ void __msan_set_alloca_origin4(void *a,
   __msan_set_origin(a, size, id);
 }
 
+u32 __msan_chain_origin(u32 id) {
+  GET_STORE_STACK_TRACE;
+  return ChainOrigin(id, &stack);
+}
+
 const char *__msan_get_origin_descr_if_stack(u32 id) {
   return GetOriginDescrIfStack(id, 0);
 }

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=204152&r1=204151&r2=204152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Tue Mar 18 08:45:19 2014
@@ -32,6 +32,12 @@
 #define MEM_IS_SHADOW(mem) \
   ((uptr)mem >= 0x200000000000ULL && (uptr)mem <= 0x400000000000ULL)
 
+// Chained stack trace format.
+#define TRACE_MAGIC_MASK 0xFFFFFFFF00000000LLU
+#define TRACE_MAKE_CHAINED(id) ((uptr)id | TRACE_MAGIC_MASK)
+#define TRACE_TO_CHAINED_ID(u) ((uptr)u & (~TRACE_MAGIC_MASK))
+#define TRACE_IS_CHAINED(u) ((((uptr)u) & TRACE_MAGIC_MASK) == TRACE_MAGIC_MASK)
+
 const int kMsanParamTlsSizeInWords = 100;
 const int kMsanRetvalTlsSizeInWords = 100;
 
@@ -82,6 +88,14 @@ void ReportAtExitStatistics();
 void UnpoisonParam(uptr n);
 void UnpoisonThreadLocalState();
 
+void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack);
+void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack);
+void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack);
+
+// Returns a "chained" origin id, pointing to the given stack trace followed by
+// the previous origin id.
+u32 ChainOrigin(u32 id, StackTrace *stack);
+
 #define GET_MALLOC_STACK_TRACE                                     \
   StackTrace stack;                                                \
   stack.size = 0;                                                  \
@@ -89,6 +103,14 @@ void UnpoisonThreadLocalState();
     GetStackTrace(&stack, common_flags()->malloc_context_size,     \
         StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),           \
         common_flags()->fast_unwind_on_malloc)
+
+#define GET_STORE_STACK_TRACE                                      \
+  StackTrace stack;                                                \
+  stack.size = 0;                                                  \
+  if (__msan_get_track_origins() > 1 && msan_inited)               \
+    GetStackTrace(&stack, common_flags()->malloc_context_size,     \
+        StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),           \
+        common_flags()->fast_unwind_on_malloc)
 
 class ScopedThreadLocalStateBackup {
  public:

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=204152&r1=204151&r2=204152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Mar 18 08:45:19 2014
@@ -208,60 +208,67 @@ INTERCEPTOR(SIZE_T, strnlen, const char
 
 INTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T n = REAL(strlen)(src);
   char *res = REAL(strcpy)(dest, src);  // NOLINT
-  __msan_copy_poison(dest, src, n + 1);
+  CopyPoison(dest, src, n + 1, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T copy_size = REAL(strnlen)(src, n);
   if (copy_size < n)
     copy_size++;  // trailing \0
   char *res = REAL(strncpy)(dest, src, n);  // NOLINT
-  __msan_copy_poison(dest, src, copy_size);
+  CopyPoison(dest, src, copy_size, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T n = REAL(strlen)(src);
   char *res = REAL(stpcpy)(dest, src);  // NOLINT
-  __msan_copy_poison(dest, src, n + 1);
+  CopyPoison(dest, src, n + 1, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, strdup, char *src) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T n = REAL(strlen)(src);
   char *res = REAL(strdup)(src);
-  __msan_copy_poison(res, src, n + 1);
+  CopyPoison(res, src, n + 1, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, __strdup, char *src) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T n = REAL(strlen)(src);
   char *res = REAL(__strdup)(src);
-  __msan_copy_poison(res, src, n + 1);
+  CopyPoison(res, src, n + 1, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T copy_size = REAL(strnlen)(src, n);
   char *res = REAL(strndup)(src, n);
-  __msan_copy_poison(res, src, copy_size);
+  CopyPoison(res, src, copy_size, &stack);
   __msan_unpoison(res + copy_size, 1); // \0
   return res;
 }
 
 INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T copy_size = REAL(strnlen)(src, n);
   char *res = REAL(__strndup)(src, n);
-  __msan_copy_poison(res, src, copy_size);
+  CopyPoison(res, src, copy_size, &stack);
   __msan_unpoison(res + copy_size, 1); // \0
   return res;
 }
@@ -279,19 +286,21 @@ INTERCEPTOR(char *, gcvt, double number,
 
 INTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T src_size = REAL(strlen)(src);
   SIZE_T dest_size = REAL(strlen)(dest);
   char *res = REAL(strcat)(dest, src);  // NOLINT
-  __msan_copy_poison(dest + dest_size, src, src_size + 1);
+  CopyPoison(dest + dest_size, src, src_size + 1, &stack);
   return res;
 }
 
 INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   SIZE_T dest_size = REAL(strlen)(dest);
   SIZE_T copy_size = REAL(strnlen)(src, n);
   char *res = REAL(strncat)(dest, src, n);  // NOLINT
-  __msan_copy_poison(dest + dest_size, src, copy_size);
+  CopyPoison(dest + dest_size, src, copy_size, &stack);
   __msan_unpoison(dest + dest_size + copy_size, 1); // \0
   return res;
 }
@@ -459,23 +468,26 @@ INTERCEPTOR(wchar_t *, wcschr, void *s,
 // wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
 INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   wchar_t *res = REAL(wcscpy)(dest, src);
-  __msan_copy_poison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1));
+  CopyPoison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1), &stack);
   return res;
 }
 
 // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
 INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   wchar_t *res = REAL(wmemcpy)(dest, src, n);
-  __msan_copy_poison(dest, src, n * sizeof(wchar_t));
+  CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
   return res;
 }
 
 INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   wchar_t *res = REAL(wmempcpy)(dest, src, n);
-  __msan_copy_poison(dest, src, n * sizeof(wchar_t));
+  CopyPoison(dest, src, n * sizeof(wchar_t), &stack);
   return res;
 }
 
@@ -489,8 +501,9 @@ INTERCEPTOR(wchar_t *, wmemset, wchar_t
 
 INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
   wchar_t *res = REAL(wmemmove)(dest, src, n);
-  __msan_move_poison(dest, src, n * sizeof(wchar_t));
+  MovePoison(dest, src, n * sizeof(wchar_t), &stack);
   return res;
 }
 
@@ -1336,16 +1349,44 @@ u32 get_origin_if_poisoned(uptr a, uptr
   return 0;
 }
 
-void __msan_copy_origin(void *dst, const void *src, uptr size) {
+void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
+  ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
+  void *res = fast_memcpy(dest, src, n);
+  CopyPoison(dest, src, n, &stack);
+  return res;
+}
+
+void *__msan_memset(void *s, int c, SIZE_T n) {
+  ENSURE_MSAN_INITED();
+  void *res = fast_memset(s, c, n);
+  __msan_unpoison(s, n);
+  return res;
+}
+
+void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
+  ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
+  void *res = REAL(memmove)(dest, src, n);
+  MovePoison(dest, src, n, &stack);
+  return res;
+}
+
+namespace __msan {
+
+void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) {
   if (!__msan_get_track_origins()) return;
   if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
+
   uptr d = (uptr)dst;
   uptr beg = d & ~3UL;
   // Copy left unaligned origin if that memory is poisoned.
   if (beg < d) {
     u32 o = get_origin_if_poisoned(beg, d - beg);
-    if (o)
+    if (o) {
+      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
       *(u32 *)MEM_TO_ORIGIN(beg) = o;
+    }
     beg += 4;
   }
 
@@ -1353,56 +1394,56 @@ void __msan_copy_origin(void *dst, const
   // Copy right unaligned origin if that memory is poisoned.
   if (end > d + size) {
     u32 o = get_origin_if_poisoned(d + size, end - d - size);
-    if (o)
+    if (o) {
+      if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
       *(u32 *)MEM_TO_ORIGIN(end - 4) = o;
+    }
     end -= 4;
   }
 
   if (beg < end) {
     // Align src up.
     uptr s = ((uptr)src + 3) & ~3UL;
-    fast_memcpy((void*)MEM_TO_ORIGIN(beg), (void*)MEM_TO_ORIGIN(s), end - beg);
+    // FIXME: factor out to msan_copy_origin_aligned
+    if (__msan_get_track_origins() > 1) {
+      u32 *src = (u32 *)MEM_TO_ORIGIN(s);
+      u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
+      u32 *src_end = src + (end - beg);
+      u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);
+      u32 src_o = 0;
+      u32 dst_o = 0;
+      for (; src < src_end; ++src, ++src_s, ++dst) {
+        if (!*src_s) continue;
+        if (*src != src_o) {
+          src_o = *src;
+          dst_o = ChainOrigin(src_o, stack);
+        }
+        *dst = dst_o;
+      }
+    } else {
+      fast_memcpy((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
+                  end - beg);
+    }
   }
 }
 
-void __msan_copy_poison(void *dst, const void *src, uptr size) {
+void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack) {
   if (!MEM_IS_APP(dst)) return;
   if (!MEM_IS_APP(src)) return;
-  fast_memcpy((void*)MEM_TO_SHADOW((uptr)dst),
-              (void*)MEM_TO_SHADOW((uptr)src), size);
-  __msan_copy_origin(dst, src, size);
+  if (src == dst) return;
+  internal_memmove((void *)MEM_TO_SHADOW((uptr)dst),
+                   (void *)MEM_TO_SHADOW((uptr)src), size);
+  CopyOrigin(dst, src, size, stack);
 }
 
-void __msan_move_poison(void *dst, const void *src, uptr size) {
+void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack) {
   if (!MEM_IS_APP(dst)) return;
   if (!MEM_IS_APP(src)) return;
-  internal_memmove((void*)MEM_TO_SHADOW((uptr)dst),
-         (void*)MEM_TO_SHADOW((uptr)src), size);
-  __msan_copy_origin(dst, src, size);
-}
-
-void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
-  ENSURE_MSAN_INITED();
-  void *res = fast_memcpy(dest, src, n);
-  __msan_copy_poison(dest, src, n);
-  return res;
+  fast_memcpy((void *)MEM_TO_SHADOW((uptr)dst),
+              (void *)MEM_TO_SHADOW((uptr)src), size);
+  CopyOrigin(dst, src, size, stack);
 }
 
-void *__msan_memset(void *s, int c, SIZE_T n) {
-  ENSURE_MSAN_INITED();
-  void *res = fast_memset(s, c, n);
-  __msan_unpoison(s, n);
-  return res;
-}
-
-void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
-  ENSURE_MSAN_INITED();
-  void *res = REAL(memmove)(dest, src, n);
-  __msan_move_poison(dest, src, n);
-  return res;
-}
-
-namespace __msan {
 void InitializeInterceptors() {
   static int inited = 0;
   CHECK_EQ(inited, 0);

Modified: compiler-rt/trunk/lib/msan/msan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interface_internal.h?rev=204152&r1=204151&r2=204152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/msan/msan_interface_internal.h Tue Mar 18 08:45:19 2014
@@ -48,12 +48,6 @@ void* __msan_memset(void *s, int c, uptr
 SANITIZER_INTERFACE_ATTRIBUTE
 void* __msan_memmove(void* dest, const void* src, uptr n);
 SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_copy_poison(void *dst, const void *src, uptr size);
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_copy_origin(void *dst, const void *src, uptr size);
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_move_poison(void *dst, const void *src, uptr size);
-SANITIZER_INTERFACE_ATTRIBUTE
 void __msan_poison(const void *a, uptr size);
 SANITIZER_INTERFACE_ATTRIBUTE
 void __msan_poison_stack(void *a, uptr size);
@@ -75,6 +69,8 @@ void __msan_set_alloca_origin(void *a, u
 SANITIZER_INTERFACE_ATTRIBUTE
 void __msan_set_alloca_origin4(void *a, uptr size, const char *descr, uptr pc);
 SANITIZER_INTERFACE_ATTRIBUTE
+u32 __msan_chain_origin(u32 id);
+SANITIZER_INTERFACE_ATTRIBUTE
 u32 __msan_get_origin(const void *a);
 
 SANITIZER_INTERFACE_ATTRIBUTE

Modified: compiler-rt/trunk/lib/msan/msan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_report.cc?rev=204152&r1=204151&r2=204152&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_report.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_report.cc Tue Mar 18 08:45:19 2014
@@ -34,34 +34,53 @@ class Decorator: private __sanitizer::An
   const char *End()    { return Default(); }
 };
 
-static void DescribeOrigin(u32 origin) {
+static void DescribeStackOrigin(const char *so, uptr pc) {
   Decorator d;
+  char *s = internal_strdup(so);
+  char *sep = internal_strchr(s, '@');
+  CHECK(sep);
+  *sep = '\0';
+  Printf("%s", d.Origin());
+  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());
+  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);
+  }
+}
+
+static void DescribeOrigin(u32 origin) {
   VPrintf(1, "  raw origin id: %d\n", origin);
   uptr pc;
-  if (const char *so = GetOriginDescrIfStack(origin, &pc)) {
-    char* s = internal_strdup(so);
-    char* sep = internal_strchr(s, '@');
-    CHECK(sep);
-    *sep = '\0';
-    Printf("%s", d.Origin());
-    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());
-    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);
+  while (true) {
+    if (const char *so = GetOriginDescrIfStack(origin, &pc)) {
+      DescribeStackOrigin(so, pc);
+      break;
     }
-  } else {
+    Decorator d;
     uptr size = 0;
     const uptr *trace = StackDepotGet(origin, &size);
-    Printf("  %sUninitialized value was created by a heap allocation%s\n",
-           d.Origin(), d.End());
-    StackTrace::PrintStack(trace, 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;
+    }
   }
 }
 
@@ -91,10 +110,18 @@ void ReportExpectedUMRNotFound(StackTrac
 void ReportAtExitStatistics() {
   SpinMutexLock l(&CommonSanitizerReportMutex);
 
-  Decorator d;
-  Printf("%s", d.Warning());
-  Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
-  Printf("%s", d.End());
+  if (msan_report_count > 0) {
+    Decorator d;
+    Printf("%s", d.Warning());
+    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);
 }
 
 }  // namespace __msan

Added: compiler-rt/trunk/test/msan/chained_origin.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/chained_origin.cc?rev=204152&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/chained_origin.cc (added)
+++ compiler-rt/trunk/test/msan/chained_origin.cc Tue Mar 18 08:45:19 2014
@@ -0,0 +1,56 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -mllvm -msan-track-origins=2 -m64 -O3 %s -o %t && \
+// RUN:     not %t >%t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-STACK < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -mllvm -msan-track-origins=2 -DHEAP=1 -m64 -O3 %s -o %t && \
+// RUN:     not %t >%t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-HEAP < %t.out
+
+#include <stdio.h>
+
+volatile int x, y;
+
+__attribute__((noinline))
+void fn_g(int a) {
+  x = a;
+}
+
+__attribute__((noinline))
+void fn_f(int a) {
+  fn_g(a);
+}
+
+__attribute__((noinline))
+void fn_h() {
+  y = x;
+}
+
+int main(int argc, char *argv[]) {
+#ifdef HEAP
+  int * volatile zz = new int;
+  int z = *zz;
+#else
+  int volatile z;
+#endif
+  fn_f(z);
+  fn_h();
+  return y;
+}
+
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK: {{#0 .* in main.*chained_origin.cc:37}}
+
+// CHECK: Uninitialized value was stored to memory at
+// CHECK: {{#.* in fn_h.*chained_origin.cc:26}}
+// CHECK: {{#.* in main.*chained_origin.cc:36}}
+
+// CHECK: Uninitialized value was stored to memory at
+// CHECK: {{#.* in fn_g.*chained_origin.cc:16}}
+// CHECK: {{#.* in fn_f.*chained_origin.cc:20}}
+// CHECK: {{#.* in main.*chained_origin.cc:35}}
+
+// CHECK-STACK: Uninitialized value was created by an allocation of 'z' in the stack frame of function 'main'
+// CHECK-STACK: {{#0 .* in main.*chained_origin.cc:28}}
+
+// CHECK-HEAP: Uninitialized value was created by a heap allocation
+// CHECK-HEAP: {{#1 .* in main.*chained_origin.cc:30}}

Propchange: compiler-rt/trunk/test/msan/chained_origin.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: compiler-rt/trunk/test/msan/chained_origin_memcpy.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/chained_origin_memcpy.cc?rev=204152&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/chained_origin_memcpy.cc (added)
+++ compiler-rt/trunk/test/msan/chained_origin_memcpy.cc Tue Mar 18 08:45:19 2014
@@ -0,0 +1,51 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -mllvm -msan-track-origins=2 -m64 -DOFFSET=0 -O3 %s -o %t && \
+// RUN:     not %t >%t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z1 < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -mllvm -msan-track-origins=2 -DOFFSET=10 -m64 -O3 %s -o %t && \
+// RUN:     not %t >%t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z2 < %t.out
+
+#include <stdio.h>
+#include <string.h>
+
+int xx[10000];
+int yy[10000];
+volatile int idx = 30;
+
+__attribute__((noinline))
+void fn_g(int a, int b) {
+  xx[idx] = a; xx[idx + 10] = b;
+}
+
+__attribute__((noinline))
+void fn_f(int a, int b) {
+  fn_g(a, b);
+}
+
+__attribute__((noinline))
+void fn_h() {
+  memcpy(&yy, &xx, sizeof(xx));
+}
+
+int main(int argc, char *argv[]) {
+  int volatile z1;
+  int volatile z2;
+  fn_f(z1, z2);
+  fn_h();
+  return yy[idx + OFFSET];
+}
+
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK: {{#0 .* in main .*chained_origin_memcpy.cc:36}}
+
+// CHECK: Uninitialized value was stored to memory at
+// CHECK: {{#.* in fn_h.*chained_origin_memcpy.cc:28}}
+
+// CHECK: Uninitialized value was stored to memory at
+// CHECK: {{#.* in fn_g.*chained_origin_memcpy.cc:.*}}
+// CHECK: {{#.* in fn_f.*chained_origin_memcpy.cc:23}}
+
+// CHECK-Z1: Uninitialized value was created by an allocation of 'z1' in the stack frame of function 'main'
+// CHECK-Z2: Uninitialized value was created by an allocation of 'z2' in the stack frame of function 'main'
+// CHECK: {{#0 .* in main.*chained_origin_memcpy.cc:31}}

Propchange: compiler-rt/trunk/test/msan/chained_origin_memcpy.cc
------------------------------------------------------------------------------
    svn:eol-style = LF





More information about the llvm-commits mailing list