diff --git a/compiler-rt/lib/msan/CMakeLists.txt b/compiler-rt/lib/msan/CMakeLists.txt index 44b00695a1e1..bb020c915f08 100644 --- a/compiler-rt/lib/msan/CMakeLists.txt +++ b/compiler-rt/lib/msan/CMakeLists.txt @@ -8,6 +8,7 @@ set(MSAN_RTL_SOURCES msan_linux.cc msan_new_delete.cc msan_platform_limits_posix.cc + msan_report.cc ) set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS} diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index e0bff8203120..0805f751daaa 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -17,9 +17,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_libc.h" -#include "sanitizer_common/sanitizer_mutex.h" #include "sanitizer_common/sanitizer_procmaps.h" -#include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" @@ -60,8 +58,6 @@ static THREADLOCAL struct { uptr stack_top, stack_bottom; } __msan_stack_bounds; -static StaticSpinMutex report_mu; - extern const int __msan_track_origins; int __msan_get_track_origins() { return __msan_track_origins; @@ -151,18 +147,15 @@ void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { stack->FastUnwindStack(pc, bp, stack_top, stack_bottom); } -static void PrintCurrentStackTrace(uptr pc, uptr bp) { - StackTrace stack; - GetStackTrace(&stack, kStackTraceMax, pc, bp); - StackTrace::PrintStack(stack.trace, stack.size, true, "", 0); -} - void PrintWarning(uptr pc, uptr bp) { PrintWarningWithOrigin(pc, bp, __msan_origin_tls); } +bool OriginIsValid(u32 origin) { + return origin != 0 && origin != (u32)-1; +} + void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { - if (!__msan::flags()->report_umrs) return; if (msan_expect_umr) { // Printf("Expected UMR\n"); __msan_origin_tls = origin; @@ -170,27 +163,21 @@ void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { return; } - GenericScopedLock lock(&report_mu); + StackTrace stack; + GetStackTrace(&stack, kStackTraceMax, pc, bp); - Report(" WARNING: MemorySanitizer: UMR (uninitialized-memory-read)\n"); - PrintCurrentStackTrace(pc, bp); - if (__msan_track_origins) { - Printf(" raw origin id: %d\n", origin); - if (origin == 0 || origin == (u32)-1) { - Printf(" ORIGIN: invalid (%x). Might be a bug in MemorySanitizer, " - "please report to MemorySanitizer developers.\n", - origin); - } else if (const char *so = __msan_get_origin_descr_if_stack(origin)) { - Printf(" ORIGIN: stack allocation: %s\n", so); - } else if (origin != 0) { - uptr size = 0; - const uptr *trace = StackDepotGet(origin, &size); - Printf(" ORIGIN: heap allocation:\n"); - StackTrace::PrintStack(trace, size, true, "", 0); - } + u32 report_origin = + (__msan_track_origins && OriginIsValid(origin)) ? origin : 0; + ReportUMR(&stack, report_origin); + + if (__msan_track_origins && !OriginIsValid(origin)) { + Printf(" ORIGIN: invalid (%x). Might be a bug in MemorySanitizer, " + "please report to MemorySanitizer developers.\n", + origin); } } + } // namespace __msan // Interface. @@ -215,8 +202,6 @@ void __msan_init() { if (msan_inited) return; msan_init_is_running = 1; - report_mu.Init(); - SetDieCallback(MsanDie); InitializeInterceptors(); @@ -272,10 +257,11 @@ void __msan_set_expect_umr(int expect_umr) { if (expect_umr) { msan_expected_umr_found = 0; } else if (!msan_expected_umr_found) { - Printf("Expected UMR not found\n"); GET_CALLER_PC_BP_SP; (void)sp; - PrintCurrentStackTrace(pc, bp); + StackTrace stack; + GetStackTrace(&stack, kStackTraceMax, pc, bp); + ReportExpectedUMRNotFound(&stack); Die(); } msan_expect_umr = expect_umr; diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index c43daf5383c4..6c481995abab 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -50,6 +50,9 @@ void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin); void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp); +void ReportUMR(StackTrace *stack, u32 origin); +void ReportExpectedUMRNotFound(StackTrace *stack); + #define GET_MALLOC_STACK_TRACE \ StackTrace stack; \ stack.size = 0; \ diff --git a/compiler-rt/lib/msan/msan_report.cc b/compiler-rt/lib/msan/msan_report.cc new file mode 100644 index 000000000000..a1a1bee632e0 --- /dev/null +++ b/compiler-rt/lib/msan/msan_report.cc @@ -0,0 +1,64 @@ +//===-- msan_report.cc -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of MemorySanitizer. +// +// Error reporting. +//===----------------------------------------------------------------------===// + +#include "msan.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_mutex.h" +#include "sanitizer_common/sanitizer_stackdepot.h" + +using namespace __sanitizer; + +static StaticSpinMutex report_mu; + +namespace __msan { + +static void DescribeOrigin(u32 origin) { + if (flags()->verbosity) + Printf(" raw origin id: %d\n", origin); + if (const char *so = __msan_get_origin_descr_if_stack(origin)) { + char* s = internal_strdup(so); + char* sep = internal_strchr(s, '@'); + CHECK(sep); + *sep = '\0'; + Printf(" Uninitialised value was created by an allocation of '%s'" + " in the stack frame of function '%s'\n", s, sep + 1); + InternalFree(s); + } else { + uptr size = 0; + const uptr *trace = StackDepotGet(origin, &size); + Printf(" Uninitialised value was created by a heap allocation\n"); + StackTrace::PrintStack(trace, size, true, "", 0); + } +} + +void ReportUMR(StackTrace *stack, u32 origin) { + if (!__msan::flags()->report_umrs) return; + + GenericScopedLock lock(&report_mu); + + Report(" WARNING: Use of uninitialized value\n"); + StackTrace::PrintStack(stack->trace, stack->size, true, "", 0); + if (origin) { + DescribeOrigin(origin); + } +} + +void ReportExpectedUMRNotFound(StackTrace *stack) { + GenericScopedLock lock(&report_mu); + + Printf(" WARNING: Expected use of uninitialized value not found\n"); + StackTrace::PrintStack(stack->trace, stack->size, true, "", 0); +} + +} // namespace msan