asan_report.cc revision e218beb2d14b663bd277158f386a86d0e62fef74
1//===-- asan_report.cc ----------------------------------------------------===// 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 AddressSanitizer, an address sanity checker. 11// 12// This file contains error reporting code. 13//===----------------------------------------------------------------------===// 14#include "asan_internal.h" 15#include "asan_mapping.h" 16#include "asan_report.h" 17#include "asan_stack.h" 18#include "asan_thread_registry.h" 19 20namespace __asan { 21 22// ---------------------- Address Descriptions ------------------- {{{1 23 24bool DescribeAddressIfShadow(uptr addr) { 25 if (AddrIsInMem(addr)) 26 return false; 27 static const char kAddrInShadowReport[] = 28 "Address %p is located in the %s.\n"; 29 if (AddrIsInShadowGap(addr)) { 30 AsanPrintf(kAddrInShadowReport, addr, "shadow gap area"); 31 return true; 32 } 33 if (AddrIsInHighShadow(addr)) { 34 AsanPrintf(kAddrInShadowReport, addr, "high shadow area"); 35 return true; 36 } 37 if (AddrIsInLowShadow(addr)) { 38 AsanPrintf(kAddrInShadowReport, addr, "low shadow area"); 39 return true; 40 } 41 CHECK(0 && "Address is not in memory and not in shadow?"); 42 return false; 43} 44 45bool DescribeAddressIfStack(uptr addr, uptr access_size) { 46 AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 47 if (!t) return false; 48 const sptr kBufSize = 4095; 49 char buf[kBufSize]; 50 uptr offset = 0; 51 const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 52 // This string is created by the compiler and has the following form: 53 // "FunctioName n alloc_1 alloc_2 ... alloc_n" 54 // where alloc_i looks like "offset size len ObjectName ". 55 CHECK(frame_descr); 56 // Report the function name and the offset. 57 const char *name_end = internal_strchr(frame_descr, ' '); 58 CHECK(name_end); 59 buf[0] = 0; 60 internal_strncat(buf, frame_descr, 61 Min(kBufSize, 62 static_cast<sptr>(name_end - frame_descr))); 63 AsanPrintf("Address %p is located at offset %zu " 64 "in frame <%s> of T%d's stack:\n", 65 (void*)addr, offset, buf, t->tid()); 66 // Report the number of stack objects. 67 char *p; 68 uptr n_objects = internal_simple_strtoll(name_end, &p, 10); 69 CHECK(n_objects > 0); 70 AsanPrintf(" This frame has %zu object(s):\n", n_objects); 71 // Report all objects in this frame. 72 for (uptr i = 0; i < n_objects; i++) { 73 uptr beg, size; 74 sptr len; 75 beg = internal_simple_strtoll(p, &p, 10); 76 size = internal_simple_strtoll(p, &p, 10); 77 len = internal_simple_strtoll(p, &p, 10); 78 if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 79 AsanPrintf("AddressSanitizer can't parse the stack frame " 80 "descriptor: |%s|\n", frame_descr); 81 break; 82 } 83 p++; 84 buf[0] = 0; 85 internal_strncat(buf, p, Min(kBufSize, len)); 86 p += len; 87 AsanPrintf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); 88 } 89 AsanPrintf("HINT: this may be a false positive if your program uses " 90 "some custom stack unwind mechanism\n" 91 " (longjmp and C++ exceptions *are* supported)\n"); 92 t->summary()->Announce(); 93 return true; 94} 95 96void DescribeAddress(uptr addr, uptr access_size) { 97 // Check if this is shadow or shadow gap. 98 if (DescribeAddressIfShadow(addr)) 99 return; 100 CHECK(AddrIsInMem(addr)); 101 if (DescribeAddressIfGlobal(addr)) 102 return; 103 if (DescribeAddressIfStack(addr, access_size)) 104 return; 105 // Assume it is a heap address. 106 DescribeHeapAddress(addr, access_size); 107} 108 109// -------------------- Different kinds of reports ----------------- {{{1 110 111void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { 112 AsanReport("ERROR: AddressSanitizer crashed on unknown address %p" 113 " (pc %p sp %p bp %p T%d)\n", 114 (void*)addr, (void*)pc, (void*)sp, (void*)bp, 115 asanThreadRegistry().GetCurrentTidOrInvalid()); 116 AsanPrintf("AddressSanitizer can not provide additional info. ABORTING\n"); 117 GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 118 stack.PrintStack(); 119 ShowStatsAndAbort(); 120} 121 122void ReportDoubleFree(uptr addr, AsanStackTrace *stack) { 123 AsanReport("ERROR: AddressSanitizer attempting double-free on %p:\n", addr); 124 stack->PrintStack(); 125 DescribeHeapAddress(addr, 1); 126 ShowStatsAndAbort(); 127} 128 129void ReportFreeNotMalloced(uptr addr, AsanStackTrace *stack) { 130 AsanReport("ERROR: AddressSanitizer attempting free on address " 131 "which was not malloc()-ed: %p\n", addr); 132 stack->PrintStack(); 133 ShowStatsAndAbort(); 134} 135 136void ReportMallocUsableSizeNotOwned(uptr addr, AsanStackTrace *stack) { 137 AsanReport("ERROR: AddressSanitizer attempting to call " 138 "malloc_usable_size() for pointer which is " 139 "not owned: %p\n", addr); 140 stack->PrintStack(); 141 DescribeHeapAddress(addr, 1); 142 ShowStatsAndAbort(); 143} 144 145void ReportAsanGetAllocatedSizeNotOwned(uptr addr, AsanStackTrace *stack) { 146 AsanReport("ERROR: AddressSanitizer attempting to call " 147 "__asan_get_allocated_size() for pointer which is " 148 "not owned: %p\n", addr); 149 stack->PrintStack(); 150 DescribeHeapAddress(addr, 1); 151 ShowStatsAndAbort(); 152} 153 154void ReportStringFunctionMemoryRangesOverlap( 155 const char *function, const char *offset1, uptr length1, 156 const char *offset2, uptr length2, AsanStackTrace *stack) { 157 AsanReport("ERROR: AddressSanitizer %s-param-overlap: " 158 "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 159 function, offset1, offset1 + length1, offset2, offset2 + length2); 160 stack->PrintStack(); 161 ShowStatsAndAbort(); 162} 163 164} // namespace __asan 165