| Kostya Serebryany | 4a42cf6 | 2012-12-27 14:09:19 +0000 | [diff] [blame] | 1 | //===-- msan_report.cc ----------------------------------------------------===// | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 2 | // | 
|  | 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" | 
| Alexey Samsonov | c30e2d6 | 2013-05-29 09:15:39 +0000 | [diff] [blame] | 16 | #include "sanitizer_common/sanitizer_allocator_internal.h" | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 17 | #include "sanitizer_common/sanitizer_common.h" | 
| Sergey Matveev | 6eff11e | 2013-05-06 13:15:14 +0000 | [diff] [blame] | 18 | #include "sanitizer_common/sanitizer_flags.h" | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 19 | #include "sanitizer_common/sanitizer_mutex.h" | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 20 | #include "sanitizer_common/sanitizer_report_decorator.h" | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 21 | #include "sanitizer_common/sanitizer_stackdepot.h" | 
| Kostya Serebryany | 7b0b9b3 | 2013-02-07 08:04:56 +0000 | [diff] [blame] | 22 | #include "sanitizer_common/sanitizer_symbolizer.h" | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 23 |  | 
|  | 24 | using namespace __sanitizer; | 
|  | 25 |  | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 26 | namespace __msan { | 
|  | 27 |  | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 28 | class Decorator: private __sanitizer::AnsiColorDecorator { | 
|  | 29 | public: | 
|  | 30 | Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { } | 
|  | 31 | const char *Warning()    { return Red(); } | 
|  | 32 | const char *Origin()     { return Magenta(); } | 
|  | 33 | const char *Name()   { return Green(); } | 
|  | 34 | const char *End()    { return Default(); } | 
|  | 35 | }; | 
|  | 36 |  | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 37 | static void PrintStack(const uptr *trace, uptr size) { | 
|  | 38 | SymbolizerScope sym_scope; | 
| Alexey Samsonov | f2b811a | 2013-10-04 08:55:03 +0000 | [diff] [blame] | 39 | StackTrace::PrintStack(trace, size, true, 0); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 40 | } | 
|  | 41 |  | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 42 | static void DescribeOrigin(u32 origin) { | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 43 | Decorator d; | 
| Evgeniy Stepanov | ced9fed | 2013-10-25 11:17:54 +0000 | [diff] [blame] | 44 | Printf("\n"); | 
| Dmitry Vyukov | 52ca74e | 2013-10-15 13:28:51 +0000 | [diff] [blame] | 45 | if (common_flags()->verbosity) | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 46 | Printf("  raw origin id: %d\n", origin); | 
| Evgeniy Stepanov | ac5ac34 | 2013-09-13 12:49:13 +0000 | [diff] [blame] | 47 | uptr pc; | 
|  | 48 | if (const char *so = GetOriginDescrIfStack(origin, &pc)) { | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 49 | char* s = internal_strdup(so); | 
|  | 50 | char* sep = internal_strchr(s, '@'); | 
|  | 51 | CHECK(sep); | 
|  | 52 | *sep = '\0'; | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 53 | Printf("%s", d.Origin()); | 
| Evgeniy Stepanov | 257274e | 2013-02-11 11:34:26 +0000 | [diff] [blame] | 54 | Printf("  %sUninitialized value was created by an allocation of '%s%s%s'" | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 55 | " in the stack frame of function '%s%s%s'%s\n", | 
| Alexey Samsonov | 7a36e61 | 2013-09-10 14:36:16 +0000 | [diff] [blame] | 56 | d.Origin(), d.Name(), s, d.Origin(), d.Name(), | 
| Peter Collingbourne | 791e65d | 2013-10-25 23:03:29 +0000 | [diff] [blame^] | 57 | Symbolizer::Get()->Demangle(sep + 1), d.Origin(), d.End()); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 58 | InternalFree(s); | 
| Evgeniy Stepanov | ac5ac34 | 2013-09-13 12:49:13 +0000 | [diff] [blame] | 59 |  | 
|  | 60 | if (pc) { | 
|  | 61 | // For some reason function address in LLVM IR is 1 less then the address | 
|  | 62 | // of the first instruction. | 
|  | 63 | pc += 1; | 
|  | 64 | PrintStack(&pc, 1); | 
|  | 65 | } | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 66 | } else { | 
|  | 67 | uptr size = 0; | 
|  | 68 | const uptr *trace = StackDepotGet(origin, &size); | 
| Evgeniy Stepanov | 257274e | 2013-02-11 11:34:26 +0000 | [diff] [blame] | 69 | Printf("  %sUninitialized value was created by a heap allocation%s\n", | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 70 | d.Origin(), d.End()); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 71 | PrintStack(trace, size); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 72 | } | 
|  | 73 | } | 
|  | 74 |  | 
| Kostya Serebryany | 7b0b9b3 | 2013-02-07 08:04:56 +0000 | [diff] [blame] | 75 | static void ReportSummary(const char *error_type, StackTrace *stack) { | 
| Peter Collingbourne | 791e65d | 2013-10-25 23:03:29 +0000 | [diff] [blame^] | 76 | if (!stack->size || !Symbolizer::Get()->IsAvailable()) return; | 
| Kostya Serebryany | 7b0b9b3 | 2013-02-07 08:04:56 +0000 | [diff] [blame] | 77 | AddressInfo ai; | 
| Alexey Samsonov | 93686fc | 2013-02-12 10:46:39 +0000 | [diff] [blame] | 78 | uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 79 | { | 
|  | 80 | SymbolizerScope sym_scope; | 
| Peter Collingbourne | 791e65d | 2013-10-25 23:03:29 +0000 | [diff] [blame^] | 81 | Symbolizer::Get()->SymbolizeCode(pc, &ai, 1); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 82 | } | 
| Alexey Samsonov | f2b811a | 2013-10-04 08:55:03 +0000 | [diff] [blame] | 83 | ReportErrorSummary(error_type, ai.file, ai.line, ai.function); | 
| Kostya Serebryany | 7b0b9b3 | 2013-02-07 08:04:56 +0000 | [diff] [blame] | 84 | } | 
|  | 85 |  | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 86 | void ReportUMR(StackTrace *stack, u32 origin) { | 
|  | 87 | if (!__msan::flags()->report_umrs) return; | 
|  | 88 |  | 
| Alexey Samsonov | 734aab4 | 2013-04-05 07:30:29 +0000 | [diff] [blame] | 89 | SpinMutexLock l(&CommonSanitizerReportMutex); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 90 |  | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 91 | Decorator d; | 
|  | 92 | Printf("%s", d.Warning()); | 
| Evgeniy Stepanov | dd0780f | 2013-05-28 14:27:30 +0000 | [diff] [blame] | 93 | Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n"); | 
| Evgeniy Stepanov | fee82c6 | 2012-12-26 10:16:45 +0000 | [diff] [blame] | 94 | Printf("%s", d.End()); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 95 | PrintStack(stack->trace, stack->size); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 96 | if (origin) { | 
|  | 97 | DescribeOrigin(origin); | 
|  | 98 | } | 
| Kostya Serebryany | 7b0b9b3 | 2013-02-07 08:04:56 +0000 | [diff] [blame] | 99 | ReportSummary("use-of-uninitialized-value", stack); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 100 | } | 
|  | 101 |  | 
|  | 102 | void ReportExpectedUMRNotFound(StackTrace *stack) { | 
| Alexey Samsonov | 734aab4 | 2013-04-05 07:30:29 +0000 | [diff] [blame] | 103 | SpinMutexLock l(&CommonSanitizerReportMutex); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 104 |  | 
|  | 105 | Printf(" WARNING: Expected use of uninitialized value not found\n"); | 
| Kostya Serebryany | ec87e78 | 2013-02-13 07:19:47 +0000 | [diff] [blame] | 106 | PrintStack(stack->trace, stack->size); | 
| Evgeniy Stepanov | 367dc64 | 2012-12-26 09:32:05 +0000 | [diff] [blame] | 107 | } | 
|  | 108 |  | 
| Evgeniy Stepanov | 9b52ce9 | 2013-01-10 11:17:55 +0000 | [diff] [blame] | 109 | void ReportAtExitStatistics() { | 
| Alexey Samsonov | 734aab4 | 2013-04-05 07:30:29 +0000 | [diff] [blame] | 110 | SpinMutexLock l(&CommonSanitizerReportMutex); | 
|  | 111 |  | 
| Evgeniy Stepanov | 9b52ce9 | 2013-01-10 11:17:55 +0000 | [diff] [blame] | 112 | Decorator d; | 
|  | 113 | Printf("%s", d.Warning()); | 
|  | 114 | Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count); | 
|  | 115 | Printf("%s", d.End()); | 
|  | 116 | } | 
|  | 117 |  | 
| Alexey Samsonov | 49a32c1 | 2013-01-30 07:45:58 +0000 | [diff] [blame] | 118 | }  // namespace __msan |