• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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"
23 
24 using namespace __sanitizer;
25 
26 namespace __msan {
27 
PrintsToTtyCached()28 static bool PrintsToTtyCached() {
29   static int cached = 0;
30   static bool prints_to_tty;
31   if (!cached) {  // Ok wrt threads since we are printing only from one thread.
32     prints_to_tty = PrintsToTty();
33     cached = 1;
34   }
35   return prints_to_tty;
36 }
37 
38 class Decorator: private __sanitizer::AnsiColorDecorator {
39  public:
Decorator()40   Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
Warning()41   const char *Warning()    { return Red(); }
Origin()42   const char *Origin()     { return Magenta(); }
Name()43   const char *Name()   { return Green(); }
End()44   const char *End()    { return Default(); }
45 };
46 
PrintStack(const uptr * trace,uptr size)47 static void PrintStack(const uptr *trace, uptr size) {
48   SymbolizerScope sym_scope;
49   StackTrace::PrintStack(trace, size, true,
50                          common_flags()->strip_path_prefix, 0);
51 }
52 
DescribeOrigin(u32 origin)53 static void DescribeOrigin(u32 origin) {
54   Decorator d;
55   if (flags()->verbosity)
56     Printf("  raw origin id: %d\n", origin);
57   if (const char *so = __msan_get_origin_descr_if_stack(origin)) {
58     char* s = internal_strdup(so);
59     char* sep = internal_strchr(s, '@');
60     CHECK(sep);
61     *sep = '\0';
62     Printf("%s", d.Origin());
63     Printf("  %sUninitialized value was created by an allocation of '%s%s%s'"
64            " in the stack frame of function '%s%s%s'%s\n",
65            d.Origin(), d.Name(), s, d.Origin(), d.Name(), Demangle(sep + 1),
66            d.Origin(), d.End());
67     InternalFree(s);
68   } else {
69     uptr size = 0;
70     const uptr *trace = StackDepotGet(origin, &size);
71     Printf("  %sUninitialized value was created by a heap allocation%s\n",
72            d.Origin(), d.End());
73     PrintStack(trace, size);
74   }
75 }
76 
ReportSummary(const char * error_type,StackTrace * stack)77 static void ReportSummary(const char *error_type, StackTrace *stack) {
78   if (!stack->size || !IsSymbolizerAvailable()) return;
79   AddressInfo ai;
80   uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
81   {
82     SymbolizerScope sym_scope;
83     SymbolizeCode(pc, &ai, 1);
84   }
85   ReportErrorSummary(error_type,
86                      StripPathPrefix(ai.file,
87                                      common_flags()->strip_path_prefix),
88                      ai.line, ai.function);
89 }
90 
ReportUMR(StackTrace * stack,u32 origin)91 void ReportUMR(StackTrace *stack, u32 origin) {
92   if (!__msan::flags()->report_umrs) return;
93 
94   SpinMutexLock l(&CommonSanitizerReportMutex);
95 
96   Decorator d;
97   Printf("%s", d.Warning());
98   Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n");
99   Printf("%s", d.End());
100   PrintStack(stack->trace, stack->size);
101   if (origin) {
102     DescribeOrigin(origin);
103   }
104   ReportSummary("use-of-uninitialized-value", stack);
105 }
106 
ReportExpectedUMRNotFound(StackTrace * stack)107 void ReportExpectedUMRNotFound(StackTrace *stack) {
108   SpinMutexLock l(&CommonSanitizerReportMutex);
109 
110   Printf(" WARNING: Expected use of uninitialized value not found\n");
111   PrintStack(stack->trace, stack->size);
112 }
113 
ReportAtExitStatistics()114 void ReportAtExitStatistics() {
115   SpinMutexLock l(&CommonSanitizerReportMutex);
116 
117   Decorator d;
118   Printf("%s", d.Warning());
119   Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
120   Printf("%s", d.End());
121 }
122 
123 
124 }  // namespace __msan
125