blob: 0469f8d868b16d396cbe2407a717c4f348ded01e [file] [log] [blame]
Kostya Serebryany4b48f452012-12-27 14:09:19 +00001//===-- msan_report.cc ----------------------------------------------------===//
Evgeniy Stepanovdb010da2012-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 Stepanovc209ba62012-12-26 10:16:45 +000018#include "sanitizer_common/sanitizer_report_decorator.h"
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000019#include "sanitizer_common/sanitizer_stackdepot.h"
Kostya Serebryany1d333c52013-02-07 08:04:56 +000020#include "sanitizer_common/sanitizer_symbolizer.h"
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000021
22using namespace __sanitizer;
23
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000024namespace __msan {
25
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000026static bool PrintsToTtyCached() {
27 static int cached = 0;
28 static bool prints_to_tty;
29 if (!cached) { // Ok wrt threads since we are printing only from one thread.
30 prints_to_tty = PrintsToTty();
31 cached = 1;
32 }
33 return prints_to_tty;
34}
35
36class Decorator: private __sanitizer::AnsiColorDecorator {
37 public:
38 Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
39 const char *Warning() { return Red(); }
40 const char *Origin() { return Magenta(); }
41 const char *Name() { return Green(); }
42 const char *End() { return Default(); }
43};
44
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +000045static void PrintStack(const uptr *trace, uptr size) {
46 SymbolizerScope sym_scope;
47 StackTrace::PrintStack(trace, size, true, flags()->strip_path_prefix, 0);
48}
49
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000050static void DescribeOrigin(u32 origin) {
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000051 Decorator d;
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000052 if (flags()->verbosity)
53 Printf(" raw origin id: %d\n", origin);
54 if (const char *so = __msan_get_origin_descr_if_stack(origin)) {
55 char* s = internal_strdup(so);
56 char* sep = internal_strchr(s, '@');
57 CHECK(sep);
58 *sep = '\0';
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000059 Printf("%s", d.Origin());
Evgeniy Stepanov9af86762013-02-11 11:34:26 +000060 Printf(" %sUninitialized value was created by an allocation of '%s%s%s'"
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000061 " in the stack frame of function '%s%s%s'%s\n",
62 d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1,
63 d.Origin(), d.End());
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000064 InternalFree(s);
65 } else {
66 uptr size = 0;
67 const uptr *trace = StackDepotGet(origin, &size);
Evgeniy Stepanov9af86762013-02-11 11:34:26 +000068 Printf(" %sUninitialized value was created by a heap allocation%s\n",
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000069 d.Origin(), d.End());
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +000070 PrintStack(trace, size);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000071 }
72}
73
Kostya Serebryany1d333c52013-02-07 08:04:56 +000074static void ReportSummary(const char *error_type, StackTrace *stack) {
75 if (!stack->size || !IsSymbolizerAvailable()) return;
76 AddressInfo ai;
Alexey Samsonov43fb7582013-02-12 10:46:39 +000077 uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +000078 {
79 SymbolizerScope sym_scope;
80 SymbolizeCode(pc, &ai, 1);
81 }
Kostya Serebryany1d333c52013-02-07 08:04:56 +000082 ReportErrorSummary(error_type,
83 StripPathPrefix(ai.file, flags()->strip_path_prefix),
84 ai.line, ai.function);
85}
86
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000087void ReportUMR(StackTrace *stack, u32 origin) {
88 if (!__msan::flags()->report_umrs) return;
89
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +000090 SpinMutexLock l(&CommonSanitizerReportMutex);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000091
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000092 Decorator d;
93 Printf("%s", d.Warning());
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000094 Report(" WARNING: Use of uninitialized value\n");
Evgeniy Stepanovc209ba62012-12-26 10:16:45 +000095 Printf("%s", d.End());
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +000096 PrintStack(stack->trace, stack->size);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +000097 if (origin) {
98 DescribeOrigin(origin);
99 }
Kostya Serebryany1d333c52013-02-07 08:04:56 +0000100 ReportSummary("use-of-uninitialized-value", stack);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000101}
102
103void ReportExpectedUMRNotFound(StackTrace *stack) {
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +0000104 SpinMutexLock l(&CommonSanitizerReportMutex);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000105
106 Printf(" WARNING: Expected use of uninitialized value not found\n");
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +0000107 PrintStack(stack->trace, stack->size);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000108}
109
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000110void ReportAtExitStatistics() {
Alexey Samsonov7ed46ff2013-04-05 07:30:29 +0000111 SpinMutexLock l(&CommonSanitizerReportMutex);
112
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000113 Decorator d;
114 Printf("%s", d.Warning());
115 Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
116 Printf("%s", d.End());
117}
118
119
Alexey Samsonovba5e9962013-01-30 07:45:58 +0000120} // namespace __msan