blob: 16b13f6c0a408b6b018e544d71f1a7cc29ca0fef [file] [log] [blame]
Kostya Serebryany4a42cf62012-12-27 14:09:19 +00001//===-- msan_report.cc ----------------------------------------------------===//
Evgeniy Stepanov367dc642012-12-26 09:32:05 +00002//
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"
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000018#include "sanitizer_common/sanitizer_report_decorator.h"
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000019#include "sanitizer_common/sanitizer_stackdepot.h"
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000020#include "sanitizer_common/sanitizer_symbolizer.h"
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000021
22using namespace __sanitizer;
23
24static StaticSpinMutex report_mu;
25
26namespace __msan {
27
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000028static 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
38class Decorator: private __sanitizer::AnsiColorDecorator {
39 public:
40 Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
41 const char *Warning() { return Red(); }
42 const char *Origin() { return Magenta(); }
43 const char *Name() { return Green(); }
44 const char *End() { return Default(); }
45};
46
Kostya Serebryanyec87e782013-02-13 07:19:47 +000047struct SymbolizerScope {
48 SymbolizerScope() { EnterSymbolizer(); }
49 ~SymbolizerScope() { ExitSymbolizer(); }
50};
51
52static void PrintStack(const uptr *trace, uptr size) {
53 SymbolizerScope sym_scope;
54 StackTrace::PrintStack(trace, size, true, flags()->strip_path_prefix, 0);
55}
56
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000057static void DescribeOrigin(u32 origin) {
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000058 Decorator d;
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000059 if (flags()->verbosity)
60 Printf(" raw origin id: %d\n", origin);
61 if (const char *so = __msan_get_origin_descr_if_stack(origin)) {
62 char* s = internal_strdup(so);
63 char* sep = internal_strchr(s, '@');
64 CHECK(sep);
65 *sep = '\0';
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000066 Printf("%s", d.Origin());
Evgeniy Stepanov257274e2013-02-11 11:34:26 +000067 Printf(" %sUninitialized value was created by an allocation of '%s%s%s'"
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000068 " in the stack frame of function '%s%s%s'%s\n",
69 d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1,
70 d.Origin(), d.End());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000071 InternalFree(s);
72 } else {
73 uptr size = 0;
74 const uptr *trace = StackDepotGet(origin, &size);
Evgeniy Stepanov257274e2013-02-11 11:34:26 +000075 Printf(" %sUninitialized value was created by a heap allocation%s\n",
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000076 d.Origin(), d.End());
Kostya Serebryanyec87e782013-02-13 07:19:47 +000077 PrintStack(trace, size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000078 }
79}
80
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000081static void ReportSummary(const char *error_type, StackTrace *stack) {
82 if (!stack->size || !IsSymbolizerAvailable()) return;
83 AddressInfo ai;
Alexey Samsonov93686fc2013-02-12 10:46:39 +000084 uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
Kostya Serebryanyec87e782013-02-13 07:19:47 +000085 {
86 SymbolizerScope sym_scope;
87 SymbolizeCode(pc, &ai, 1);
88 }
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000089 ReportErrorSummary(error_type,
90 StripPathPrefix(ai.file, flags()->strip_path_prefix),
91 ai.line, ai.function);
92}
93
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000094void ReportUMR(StackTrace *stack, u32 origin) {
95 if (!__msan::flags()->report_umrs) return;
96
97 GenericScopedLock<StaticSpinMutex> lock(&report_mu);
98
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000099 Decorator d;
100 Printf("%s", d.Warning());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000101 Report(" WARNING: Use of uninitialized value\n");
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +0000102 Printf("%s", d.End());
Kostya Serebryanyec87e782013-02-13 07:19:47 +0000103 PrintStack(stack->trace, stack->size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000104 if (origin) {
105 DescribeOrigin(origin);
106 }
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +0000107 ReportSummary("use-of-uninitialized-value", stack);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000108}
109
110void ReportExpectedUMRNotFound(StackTrace *stack) {
111 GenericScopedLock<StaticSpinMutex> lock(&report_mu);
112
113 Printf(" WARNING: Expected use of uninitialized value not found\n");
Kostya Serebryanyec87e782013-02-13 07:19:47 +0000114 PrintStack(stack->trace, stack->size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000115}
116
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000117void ReportAtExitStatistics() {
118 Decorator d;
119 Printf("%s", d.Warning());
120 Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
121 Printf("%s", d.End());
122}
123
124
Alexey Samsonov49a32c12013-01-30 07:45:58 +0000125} // namespace __msan