blob: 8721089997333761c690106d0eedfc576ab88406 [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"
20
21using namespace __sanitizer;
22
23static StaticSpinMutex report_mu;
24
25namespace __msan {
26
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000027static 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
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000046static void DescribeOrigin(u32 origin) {
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000047 Decorator d;
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000048 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';
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000055 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());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000060 InternalFree(s);
61 } else {
62 uptr size = 0;
63 const uptr *trace = StackDepotGet(origin, &size);
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000064 Printf(" %sUninitialised value was created by a heap allocation%s\n",
65 d.Origin(), d.End());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000066 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
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000075 Decorator d;
76 Printf("%s", d.Warning());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000077 Report(" WARNING: Use of uninitialized value\n");
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000078 Printf("%s", d.End());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000079 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
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +000092void 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
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000100} // namespace msan