1 //===-- msan_report.cc ----------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of MemorySanitizer.
13 //===----------------------------------------------------------------------===//
16 #include "sanitizer_common/sanitizer_allocator_internal.h"
17 #include "sanitizer_common/sanitizer_common.h"
18 #include "sanitizer_common/sanitizer_flags.h"
19 #include "sanitizer_common/sanitizer_mutex.h"
20 #include "sanitizer_common/sanitizer_report_decorator.h"
21 #include "sanitizer_common/sanitizer_stackdepot.h"
22 #include "sanitizer_common/sanitizer_symbolizer.h"
24 using namespace __sanitizer
;
28 class Decorator
: private __sanitizer::AnsiColorDecorator
{
30 Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
31 const char *Warning() { return Red(); }
32 const char *Origin() { return Magenta(); }
33 const char *Name() { return Green(); }
34 const char *End() { return Default(); }
37 static void PrintStack(const uptr
*trace
, uptr size
) {
38 SymbolizerScope sym_scope
;
39 StackTrace::PrintStack(trace
, size
, true, 0);
42 static void DescribeOrigin(u32 origin
) {
44 if (common_flags()->verbosity
)
45 Printf(" raw origin id: %d\n", origin
);
47 if (const char *so
= GetOriginDescrIfStack(origin
, &pc
)) {
48 char* s
= internal_strdup(so
);
49 char* sep
= internal_strchr(s
, '@');
52 Printf("%s", d
.Origin());
53 Printf(" %sUninitialized value was created by an allocation of '%s%s%s'"
54 " in the stack frame of function '%s%s%s'%s\n",
55 d
.Origin(), d
.Name(), s
, d
.Origin(), d
.Name(),
56 getSymbolizer()->Demangle(sep
+ 1), d
.Origin(), d
.End());
60 // For some reason function address in LLVM IR is 1 less then the address
61 // of the first instruction.
67 const uptr
*trace
= StackDepotGet(origin
, &size
);
68 Printf(" %sUninitialized value was created by a heap allocation%s\n",
70 PrintStack(trace
, size
);
74 static void ReportSummary(const char *error_type
, StackTrace
*stack
) {
75 if (!stack
->size
|| !getSymbolizer()->IsAvailable()) return;
77 uptr pc
= StackTrace::GetPreviousInstructionPc(stack
->trace
[0]);
79 SymbolizerScope sym_scope
;
80 getSymbolizer()->SymbolizeCode(pc
, &ai
, 1);
82 ReportErrorSummary(error_type
, ai
.file
, ai
.line
, ai
.function
);
85 void ReportUMR(StackTrace
*stack
, u32 origin
) {
86 if (!__msan::flags()->report_umrs
) return;
88 SpinMutexLock
l(&CommonSanitizerReportMutex
);
91 Printf("%s", d
.Warning());
92 Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n");
93 Printf("%s", d
.End());
94 PrintStack(stack
->trace
, stack
->size
);
96 DescribeOrigin(origin
);
98 ReportSummary("use-of-uninitialized-value", stack
);
101 void ReportExpectedUMRNotFound(StackTrace
*stack
) {
102 SpinMutexLock
l(&CommonSanitizerReportMutex
);
104 Printf(" WARNING: Expected use of uninitialized value not found\n");
105 PrintStack(stack
->trace
, stack
->size
);
108 void ReportAtExitStatistics() {
109 SpinMutexLock
l(&CommonSanitizerReportMutex
);
112 Printf("%s", d
.Warning());
113 Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count
);
114 Printf("%s", d
.End());
117 } // namespace __msan