blob: 734fc96fe69f7602683275d14447237c7b3d4077 [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"
Sergey Matveev6eff11e2013-05-06 13:15:14 +000017#include "sanitizer_common/sanitizer_flags.h"
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000018#include "sanitizer_common/sanitizer_mutex.h"
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000019#include "sanitizer_common/sanitizer_report_decorator.h"
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000020#include "sanitizer_common/sanitizer_stackdepot.h"
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000021#include "sanitizer_common/sanitizer_symbolizer.h"
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000022
23using namespace __sanitizer;
24
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000025namespace __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
Kostya Serebryanyec87e782013-02-13 07:19:47 +000046static void PrintStack(const uptr *trace, uptr size) {
47 SymbolizerScope sym_scope;
Sergey Matveev6eff11e2013-05-06 13:15:14 +000048 StackTrace::PrintStack(trace, size, true,
49 common_flags()->strip_path_prefix, 0);
Kostya Serebryanyec87e782013-02-13 07:19:47 +000050}
51
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000052static void DescribeOrigin(u32 origin) {
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000053 Decorator d;
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000054 if (flags()->verbosity)
55 Printf(" raw origin id: %d\n", origin);
56 if (const char *so = __msan_get_origin_descr_if_stack(origin)) {
57 char* s = internal_strdup(so);
58 char* sep = internal_strchr(s, '@');
59 CHECK(sep);
60 *sep = '\0';
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000061 Printf("%s", d.Origin());
Evgeniy Stepanov257274e2013-02-11 11:34:26 +000062 Printf(" %sUninitialized value was created by an allocation of '%s%s%s'"
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000063 " in the stack frame of function '%s%s%s'%s\n",
Alexey Samsonove4886692013-04-12 07:27:30 +000064 d.Origin(), d.Name(), s, d.Origin(), d.Name(), Demangle(sep + 1),
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000065 d.Origin(), d.End());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000066 InternalFree(s);
67 } else {
68 uptr size = 0;
69 const uptr *trace = StackDepotGet(origin, &size);
Evgeniy Stepanov257274e2013-02-11 11:34:26 +000070 Printf(" %sUninitialized value was created by a heap allocation%s\n",
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000071 d.Origin(), d.End());
Kostya Serebryanyec87e782013-02-13 07:19:47 +000072 PrintStack(trace, size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000073 }
74}
75
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000076static void ReportSummary(const char *error_type, StackTrace *stack) {
77 if (!stack->size || !IsSymbolizerAvailable()) return;
78 AddressInfo ai;
Alexey Samsonov93686fc2013-02-12 10:46:39 +000079 uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
Kostya Serebryanyec87e782013-02-13 07:19:47 +000080 {
81 SymbolizerScope sym_scope;
82 SymbolizeCode(pc, &ai, 1);
83 }
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000084 ReportErrorSummary(error_type,
Sergey Matveev6eff11e2013-05-06 13:15:14 +000085 StripPathPrefix(ai.file,
86 common_flags()->strip_path_prefix),
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +000087 ai.line, ai.function);
88}
89
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000090void ReportUMR(StackTrace *stack, u32 origin) {
91 if (!__msan::flags()->report_umrs) return;
92
Alexey Samsonov734aab42013-04-05 07:30:29 +000093 SpinMutexLock l(&CommonSanitizerReportMutex);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000094
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000095 Decorator d;
96 Printf("%s", d.Warning());
Evgeniy Stepanov367dc642012-12-26 09:32:05 +000097 Report(" WARNING: Use of uninitialized value\n");
Evgeniy Stepanovfee82c62012-12-26 10:16:45 +000098 Printf("%s", d.End());
Kostya Serebryanyec87e782013-02-13 07:19:47 +000099 PrintStack(stack->trace, stack->size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000100 if (origin) {
101 DescribeOrigin(origin);
102 }
Kostya Serebryany7b0b9b32013-02-07 08:04:56 +0000103 ReportSummary("use-of-uninitialized-value", stack);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000104}
105
106void ReportExpectedUMRNotFound(StackTrace *stack) {
Alexey Samsonov734aab42013-04-05 07:30:29 +0000107 SpinMutexLock l(&CommonSanitizerReportMutex);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000108
109 Printf(" WARNING: Expected use of uninitialized value not found\n");
Kostya Serebryanyec87e782013-02-13 07:19:47 +0000110 PrintStack(stack->trace, stack->size);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000111}
112
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000113void ReportAtExitStatistics() {
Alexey Samsonov734aab42013-04-05 07:30:29 +0000114 SpinMutexLock l(&CommonSanitizerReportMutex);
115
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000116 Decorator d;
117 Printf("%s", d.Warning());
118 Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
119 Printf("%s", d.End());
120}
121
122
Alexey Samsonov49a32c12013-01-30 07:45:58 +0000123} // namespace __msan