msan_report.cc revision 6f3460595f10fb4740ccd0beaa888a0e47ed48cd
17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//===-- msan_report.cc ----------------------------------------------------===//
27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//                     The LLVM Compiler Infrastructure
47faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This file is distributed under the University of Illinois Open Source
67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// License. See LICENSE.TXT for details.
77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//===----------------------------------------------------------------------===//
97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This file is a part of MemorySanitizer.
117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//
127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Error reporting.
137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez//===----------------------------------------------------------------------===//
147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "msan.h"
167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_allocator_internal.h"
177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_common.h"
187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_flags.h"
197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_mutex.h"
207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_report_decorator.h"
217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_stackdepot.h"
227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#include "sanitizer_common/sanitizer_symbolizer.h"
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezusing namespace __sanitizer;
257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace __msan {
277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezclass Decorator: private __sanitizer::AnsiColorDecorator {
297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public:
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char *Warning()    { return Red(); }
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char *Origin()     { return Magenta(); }
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char *Name()   { return Green(); }
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  const char *End()    { return Default(); }
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic void PrintStack(const uptr *trace, uptr size) {
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  SymbolizerScope sym_scope;
397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  StackTrace::PrintStack(trace, size, true,
407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                         common_flags()->strip_path_prefix, 0);
417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezstatic void DescribeOrigin(u32 origin) {
447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Decorator d;
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  if (flags()->verbosity)
467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Printf("  raw origin id: %d\n", origin);
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  uptr pc;
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (const char *so = GetOriginDescrIfStack(origin, &pc)) {
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    char* s = internal_strdup(so);
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    char* sep = internal_strchr(s, '@');
517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    CHECK(sep);
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    *sep = '\0';
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Printf("%s", d.Origin());
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Printf("  %sUninitialized value was created by an allocation of '%s%s%s'"
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           " in the stack frame of function '%s%s%s'%s\n",
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           d.Origin(), d.Name(), s, d.Origin(), d.Name(),
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           getSymbolizer()->Demangle(sep + 1), d.Origin(), d.End());
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    InternalFree(s);
597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if (pc) {
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // For some reason function address in LLVM IR is 1 less then the address
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // of the first instruction.
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      pc += 1;
647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      PrintStack(&pc, 1);
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  } else {
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    uptr size = 0;
687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const uptr *trace = StackDepotGet(origin, &size);
697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Printf("  %sUninitialized value was created by a heap allocation%s\n",
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           d.Origin(), d.End());
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    PrintStack(trace, size);
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic void ReportSummary(const char *error_type, StackTrace *stack) {
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  if (!stack->size || !getSymbolizer()->IsAvailable()) return;
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  AddressInfo ai;
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SymbolizerScope sym_scope;
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    getSymbolizer()->SymbolizeCode(pc, &ai, 1);
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  }
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ReportErrorSummary(error_type,
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                     StripPathPrefix(ai.file,
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                     common_flags()->strip_path_prefix),
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                     ai.line, ai.function);
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid ReportUMR(StackTrace *stack, u32 origin) {
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (!__msan::flags()->report_umrs) return;
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  SpinMutexLock l(&CommonSanitizerReportMutex);
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Decorator d;
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Printf("%s", d.Warning());
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n");
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Printf("%s", d.End());
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  PrintStack(stack->trace, stack->size);
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (origin) {
1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    DescribeOrigin(origin);
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ReportSummary("use-of-uninitialized-value", stack);
1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid ReportExpectedUMRNotFound(StackTrace *stack) {
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  SpinMutexLock l(&CommonSanitizerReportMutex);
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Printf(" WARNING: Expected use of uninitialized value not found\n");
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  PrintStack(stack->trace, stack->size);
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid ReportAtExitStatistics() {
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  SpinMutexLock l(&CommonSanitizerReportMutex);
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Decorator d;
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Printf("%s", d.Warning());
1177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
1187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Printf("%s", d.End());
1197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}  // namespace __msan
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath