msan_report.cc revision ba5e99668e3030cc5bab357a04271a1bdbac209c
1//===-- msan_report.cc ----------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of MemorySanitizer. 11// 12// Error reporting. 13//===----------------------------------------------------------------------===// 14 15#include "msan.h" 16#include "sanitizer_common/sanitizer_common.h" 17#include "sanitizer_common/sanitizer_mutex.h" 18#include "sanitizer_common/sanitizer_report_decorator.h" 19#include "sanitizer_common/sanitizer_stackdepot.h" 20 21using namespace __sanitizer; 22 23static StaticSpinMutex report_mu; 24 25namespace __msan { 26 27static bool PrintsToTtyCached() { 28 static int cached = 0; 29 static bool prints_to_tty; 30 if (!cached) { // Ok wrt threads since we are printing only from one thread. 31 prints_to_tty = PrintsToTty(); 32 cached = 1; 33 } 34 return prints_to_tty; 35} 36 37class Decorator: private __sanitizer::AnsiColorDecorator { 38 public: 39 Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { } 40 const char *Warning() { return Red(); } 41 const char *Origin() { return Magenta(); } 42 const char *Name() { return Green(); } 43 const char *End() { return Default(); } 44}; 45 46static void DescribeOrigin(u32 origin) { 47 Decorator d; 48 if (flags()->verbosity) 49 Printf(" raw origin id: %d\n", origin); 50 if (const char *so = __msan_get_origin_descr_if_stack(origin)) { 51 char* s = internal_strdup(so); 52 char* sep = internal_strchr(s, '@'); 53 CHECK(sep); 54 *sep = '\0'; 55 Printf("%s", d.Origin()); 56 Printf(" %sUninitialised value was created by an allocation of '%s%s%s'" 57 " in the stack frame of function '%s%s%s'%s\n", 58 d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, 59 d.Origin(), d.End()); 60 InternalFree(s); 61 } else { 62 uptr size = 0; 63 const uptr *trace = StackDepotGet(origin, &size); 64 Printf(" %sUninitialised value was created by a heap allocation%s\n", 65 d.Origin(), d.End()); 66 StackTrace::PrintStack(trace, size, true, "", 0); 67 } 68} 69 70void ReportUMR(StackTrace *stack, u32 origin) { 71 if (!__msan::flags()->report_umrs) return; 72 73 GenericScopedLock<StaticSpinMutex> lock(&report_mu); 74 75 Decorator d; 76 Printf("%s", d.Warning()); 77 Report(" WARNING: Use of uninitialized value\n"); 78 Printf("%s", d.End()); 79 StackTrace::PrintStack(stack->trace, stack->size, true, "", 0); 80 if (origin) { 81 DescribeOrigin(origin); 82 } 83} 84 85void ReportExpectedUMRNotFound(StackTrace *stack) { 86 GenericScopedLock<StaticSpinMutex> lock(&report_mu); 87 88 Printf(" WARNING: Expected use of uninitialized value not found\n"); 89 StackTrace::PrintStack(stack->trace, stack->size, true, "", 0); 90} 91 92void ReportAtExitStatistics() { 93 Decorator d; 94 Printf("%s", d.Warning()); 95 Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count); 96 Printf("%s", d.End()); 97} 98 99 100} // namespace __msan 101