asan_report.cc revision 95f630ae40cef78fb03b18110eff43bcf8d1c040
134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project//===-- asan_report.cc ----------------------------------------------------===// 234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project// 334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project// The LLVM Compiler Infrastructure 434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project// 534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project// This file is distributed under the University of Illinois Open Source 6bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// License. See LICENSE.TXT for details. 7bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// 8bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes//===----------------------------------------------------------------------===// 9bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// 10bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// This file is a part of AddressSanitizer, an address sanity checker. 11bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// 12bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// This file contains error reporting code. 13bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes//===----------------------------------------------------------------------===// 14bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_flags.h" 15bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_internal.h" 16bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_mapping.h" 17bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_report.h" 18bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_stack.h" 19bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_thread.h" 20bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "asan_thread_registry.h" 21bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "sanitizer_common/sanitizer_common.h" 22bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "sanitizer_common/sanitizer_report_decorator.h" 23bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes#include "sanitizer_common/sanitizer_symbolizer.h" 24bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes 25bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesnamespace __asan { 26bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes 27bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// -------------------- User-specified callbacks ----------------- {{{1 28bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesstatic void (*error_report_callback)(const char*); 29bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesstatic char *error_message_buffer = 0; 30bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesstatic uptr error_message_buffer_pos = 0; 31bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesstatic uptr error_message_buffer_size = 0; 32bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes 33bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughesvoid AppendToErrorMessageBuffer(const char *buffer) { 34bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes if (error_message_buffer) { 3534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project uptr length = internal_strlen(buffer); 3634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project CHECK_GE(error_message_buffer_size, error_message_buffer_pos); 3734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project uptr remaining = error_message_buffer_size - error_message_buffer_pos; 38f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown internal_strncpy(error_message_buffer + error_message_buffer_pos, 39f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown buffer, remaining); 40f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error_message_buffer[error_message_buffer_size - 1] = '\0'; 41bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes // FIXME: reallocate the buffer instead of truncating the message. 42bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes error_message_buffer_pos += remaining > length ? length : remaining; 43bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes } 44bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes} 45bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes 46bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes// ---------------------- Decorator ------------------------------ {{{1 47f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownbool PrintsToTtyCached() { 48f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown static int cached = 0; 49f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown static bool prints_to_tty; 50f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!cached) { // Ok wrt threads since we are printing only from one thread. 51f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown prints_to_tty = PrintsToTty(); 52f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cached = 1; 53f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 54f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return prints_to_tty; 55f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 56f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownclass Decorator: private __sanitizer::AnsiColorDecorator { 57f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown public: 58f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { } 59f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *Warning() { return Red(); } 60f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *EndWarning() { return Default(); } 61f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *Access() { return Blue(); } 62f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *EndAccess() { return Default(); } 63f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *Location() { return Green(); } 64f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *EndLocation() { return Default(); } 65f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *Allocation() { return Magenta(); } 66f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *EndAllocation() { return Default(); } 67f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 68f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *ShadowByte(u8 byte) { 69f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown switch (byte) { 70f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanHeapLeftRedzoneMagic: 71f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanHeapRightRedzoneMagic: 72bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes return Red(); 73f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanHeapFreeMagic: 74f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Magenta(); 75f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackLeftRedzoneMagic: 76f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackMidRedzoneMagic: 77f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackRightRedzoneMagic: 78f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackPartialRedzoneMagic: 79f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Red(); 80f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackAfterReturnMagic: 81f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Magenta(); 82f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanInitializationOrderMagic: 83f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Cyan(); 84f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanUserPoisonedMemoryMagic: 85f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Blue(); 86f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanStackUseAfterScopeMagic: 87f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Magenta(); 88f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanGlobalRedzoneMagic: 89f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Red(); 90f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case kAsanInternalHeapMagic: 91f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Yellow(); 92f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown default: 93f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return Default(); 94f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 95f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 96f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *EndShadowByte() { return Default(); } 97f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown}; 98f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 99f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown// ---------------------- Helper functions ----------------------- {{{1 100f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 101f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void PrintShadowByte(const char *before, u8 byte, 102f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *after = "\n") { 103f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Decorator d; 10410bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes Printf("%s%s%x%x%s%s", before, 105f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown d.ShadowByte(byte), byte >> 4, byte & 15, d.EndShadowByte(), after); 106f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 107f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 108f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void PrintShadowBytes(const char *before, u8 *bytes, 109f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown u8 *guilty, uptr n) { 110f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Decorator d; 111f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (before) 112f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Printf("%s%p:", before, bytes); 113f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (uptr i = 0; i < n; i++) { 114f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown u8 *p = bytes + i; 115f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *before = p == guilty ? "[" : 116f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown p - 1 == guilty ? "" : " "; 117f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *after = p == guilty ? "]" : ""; 118f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(before, *p, after); 119bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes } 120f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Printf("\n"); 121f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 122f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 123f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void PrintLegend() { 124f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Printf("Shadow byte legend (one shadow byte represents %d " 125f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "application bytes):\n", (int)SHADOW_GRANULARITY); 126f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Addressable: ", 0); 127bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes Printf(" Partially addressable: "); 128bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes for (uptr i = 1; i < SHADOW_GRANULARITY; i++) 129bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes PrintShadowByte("", i, " "); 130bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes Printf("\n"); 131bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes PrintShadowByte(" Heap left redzone: ", kAsanHeapLeftRedzoneMagic); 132bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes PrintShadowByte(" Heap righ redzone: ", kAsanHeapRightRedzoneMagic); 133f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Freed Heap region: ", kAsanHeapFreeMagic); 134f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack left redzone: ", kAsanStackLeftRedzoneMagic); 135f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack mid redzone: ", kAsanStackMidRedzoneMagic); 136f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack right redzone: ", kAsanStackRightRedzoneMagic); 137f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack partial redzone: ", kAsanStackPartialRedzoneMagic); 138f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack after return: ", kAsanStackAfterReturnMagic); 139f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PrintShadowByte(" Stack use after scope: ", kAsanStackUseAfterScopeMagic); 140a0b125c9afa56cc094f215fba1501aed5bbf9b66Lorenzo Colitti PrintShadowByte(" Global redzone: ", kAsanGlobalRedzoneMagic); 14110bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes PrintShadowByte(" Global init order: ", kAsanInitializationOrderMagic); 14210bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes PrintShadowByte(" Poisoned by user: ", kAsanUserPoisonedMemoryMagic); 14310bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes PrintShadowByte(" ASan internal: ", kAsanInternalHeapMagic); 144bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes} 14510bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes 14610bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughesstatic void PrintShadowMemoryForAddress(uptr addr) { 14710bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes if (!AddrIsInMem(addr)) 14810bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes return; 149f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown uptr shadow_addr = MemToShadow(addr); 15010bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes const uptr n_bytes_per_row = 16; 15110bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1); 15210bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes Printf("Shadow bytes around the buggy address:\n"); 15310bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes for (int i = -5; i <= 5; i++) { 15410bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes const char *prefix = (i == 0) ? "=>" : " "; 15510bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes PrintShadowBytes(prefix, 156a0b125c9afa56cc094f215fba1501aed5bbf9b66Lorenzo Colitti (u8*)(aligned_shadow + i * n_bytes_per_row), 157a0b125c9afa56cc094f215fba1501aed5bbf9b66Lorenzo Colitti (u8*)shadow_addr, n_bytes_per_row); 158bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes } 15910bd42d0e743697d1b541eac35d7889f17d70ca6Elliott Hughes if (flags()->print_legend) 160bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes PrintLegend(); 161bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes} 162bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes 163f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void PrintZoneForPointer(uptr ptr, uptr zone_ptr, 16434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project const char *zone_name) { 16534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (zone_ptr) { 1662f063cfda5a6f48f4a1eef6c394c0361243b2ee8Chris Dearman if (zone_name) { 1672f063cfda5a6f48f4a1eef6c394c0361243b2ee8Chris Dearman Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n", 16834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ptr, zone_ptr, zone_name); 16934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } else { 17034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n", 17134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ptr, zone_ptr); 17234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 17334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } else { 17434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project Printf("malloc_zone_from_ptr(%p) = 0\n", ptr); 175bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes } 176bb0c2d52fc596f5e21652486c0b6a0b3e3b7e4cbElliott Hughes} 17734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 178// ---------------------- Address Descriptions ------------------- {{{1 179 180static bool IsASCII(unsigned char c) { 181 return /*0x00 <= c &&*/ c <= 0x7F; 182} 183 184// Check if the global is a zero-terminated ASCII string. If so, print it. 185static void PrintGlobalNameIfASCII(const __asan_global &g) { 186 for (uptr p = g.beg; p < g.beg + g.size - 1; p++) { 187 if (!IsASCII(*(unsigned char*)p)) return; 188 } 189 if (*(char*)(g.beg + g.size - 1) != 0) return; 190 Printf(" '%s' is ascii string '%s'\n", g.name, (char*)g.beg); 191} 192 193bool DescribeAddressRelativeToGlobal(uptr addr, const __asan_global &g) { 194 static const uptr kMinimalDistanceFromAnotherGlobal = 64; 195 if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; 196 if (addr >= g.beg + g.size_with_redzone) return false; 197 Decorator d; 198 Printf("%s", d.Location()); 199 Printf("%p is located ", (void*)addr); 200 if (addr < g.beg) { 201 Printf("%zd bytes to the left", g.beg - addr); 202 } else if (addr >= g.beg + g.size) { 203 Printf("%zd bytes to the right", addr - (g.beg + g.size)); 204 } else { 205 Printf("%zd bytes inside", addr - g.beg); // Can it happen? 206 } 207 Printf(" of global variable '%s' (0x%zx) of size %zu\n", 208 g.name, g.beg, g.size); 209 Printf("%s", d.EndLocation()); 210 PrintGlobalNameIfASCII(g); 211 return true; 212} 213 214bool DescribeAddressIfShadow(uptr addr) { 215 if (AddrIsInMem(addr)) 216 return false; 217 static const char kAddrInShadowReport[] = 218 "Address %p is located in the %s.\n"; 219 if (AddrIsInShadowGap(addr)) { 220 Printf(kAddrInShadowReport, addr, "shadow gap area"); 221 return true; 222 } 223 if (AddrIsInHighShadow(addr)) { 224 Printf(kAddrInShadowReport, addr, "high shadow area"); 225 return true; 226 } 227 if (AddrIsInLowShadow(addr)) { 228 Printf(kAddrInShadowReport, addr, "low shadow area"); 229 return true; 230 } 231 CHECK(0 && "Address is not in memory and not in shadow?"); 232 return false; 233} 234 235bool DescribeAddressIfStack(uptr addr, uptr access_size) { 236 AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 237 if (!t) return false; 238 const sptr kBufSize = 4095; 239 char buf[kBufSize]; 240 uptr offset = 0; 241 const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 242 // This string is created by the compiler and has the following form: 243 // "FunctioName n alloc_1 alloc_2 ... alloc_n" 244 // where alloc_i looks like "offset size len ObjectName ". 245 CHECK(frame_descr); 246 // Report the function name and the offset. 247 const char *name_end = internal_strchr(frame_descr, ' '); 248 CHECK(name_end); 249 buf[0] = 0; 250 internal_strncat(buf, frame_descr, 251 Min(kBufSize, 252 static_cast<sptr>(name_end - frame_descr))); 253 Decorator d; 254 Printf("%s", d.Location()); 255 Printf("Address %p is located at offset %zu " 256 "in frame <%s> of T%d's stack:\n", 257 (void*)addr, offset, Demangle(buf), t->tid()); 258 Printf("%s", d.EndLocation()); 259 // Report the number of stack objects. 260 char *p; 261 uptr n_objects = internal_simple_strtoll(name_end, &p, 10); 262 CHECK(n_objects > 0); 263 Printf(" This frame has %zu object(s):\n", n_objects); 264 // Report all objects in this frame. 265 for (uptr i = 0; i < n_objects; i++) { 266 uptr beg, size; 267 sptr len; 268 beg = internal_simple_strtoll(p, &p, 10); 269 size = internal_simple_strtoll(p, &p, 10); 270 len = internal_simple_strtoll(p, &p, 10); 271 if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 272 Printf("AddressSanitizer can't parse the stack frame " 273 "descriptor: |%s|\n", frame_descr); 274 break; 275 } 276 p++; 277 buf[0] = 0; 278 internal_strncat(buf, p, Min(kBufSize, len)); 279 p += len; 280 Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); 281 } 282 Printf("HINT: this may be a false positive if your program uses " 283 "some custom stack unwind mechanism or swapcontext\n" 284 " (longjmp and C++ exceptions *are* supported)\n"); 285 DescribeThread(t->summary()); 286 return true; 287} 288 289static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr, 290 uptr access_size) { 291 uptr offset; 292 Decorator d; 293 Printf("%s", d.Location()); 294 Printf("%p is located ", (void*)addr); 295 if (chunk.AddrIsInside(addr, access_size, &offset)) { 296 Printf("%zu bytes inside of", offset); 297 } else if (chunk.AddrIsAtLeft(addr, access_size, &offset)) { 298 Printf("%zu bytes to the left of", offset); 299 } else if (chunk.AddrIsAtRight(addr, access_size, &offset)) { 300 Printf("%zu bytes to the right of", offset); 301 } else { 302 Printf(" somewhere around (this is AddressSanitizer bug!)"); 303 } 304 Printf(" %zu-byte region [%p,%p)\n", chunk.UsedSize(), 305 (void*)(chunk.Beg()), (void*)(chunk.End())); 306 Printf("%s", d.EndLocation()); 307} 308 309// Return " (thread_name) " or an empty string if the name is empty. 310const char *ThreadNameWithParenthesis(AsanThreadSummary *t, char buff[], 311 uptr buff_len) { 312 const char *name = t->name(); 313 if (*name == 0) return ""; 314 buff[0] = 0; 315 internal_strncat(buff, " (", 3); 316 internal_strncat(buff, name, buff_len - 4); 317 internal_strncat(buff, ")", 2); 318 return buff; 319} 320 321const char *ThreadNameWithParenthesis(u32 tid, char buff[], 322 uptr buff_len) { 323 if (tid == kInvalidTid) return ""; 324 AsanThreadSummary *t = asanThreadRegistry().FindByTid(tid); 325 return ThreadNameWithParenthesis(t, buff, buff_len); 326} 327 328void DescribeHeapAddress(uptr addr, uptr access_size) { 329 AsanChunkView chunk = FindHeapChunkByAddress(addr); 330 if (!chunk.IsValid()) return; 331 DescribeAccessToHeapChunk(chunk, addr, access_size); 332 CHECK(chunk.AllocTid() != kInvalidTid); 333 AsanThreadSummary *alloc_thread = 334 asanThreadRegistry().FindByTid(chunk.AllocTid()); 335 StackTrace alloc_stack; 336 chunk.GetAllocStack(&alloc_stack); 337 AsanThread *t = asanThreadRegistry().GetCurrent(); 338 CHECK(t); 339 char tname[128]; 340 Decorator d; 341 if (chunk.FreeTid() != kInvalidTid) { 342 AsanThreadSummary *free_thread = 343 asanThreadRegistry().FindByTid(chunk.FreeTid()); 344 Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(), 345 free_thread->tid(), 346 ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)), 347 d.EndAllocation()); 348 StackTrace free_stack; 349 chunk.GetFreeStack(&free_stack); 350 PrintStack(&free_stack); 351 Printf("%spreviously allocated by thread T%d%s here:%s\n", 352 d.Allocation(), alloc_thread->tid(), 353 ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 354 d.EndAllocation()); 355 PrintStack(&alloc_stack); 356 DescribeThread(t->summary()); 357 DescribeThread(free_thread); 358 DescribeThread(alloc_thread); 359 } else { 360 Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(), 361 alloc_thread->tid(), 362 ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 363 d.EndAllocation()); 364 PrintStack(&alloc_stack); 365 DescribeThread(t->summary()); 366 DescribeThread(alloc_thread); 367 } 368} 369 370void DescribeAddress(uptr addr, uptr access_size) { 371 // Check if this is shadow or shadow gap. 372 if (DescribeAddressIfShadow(addr)) 373 return; 374 CHECK(AddrIsInMem(addr)); 375 if (DescribeAddressIfGlobal(addr)) 376 return; 377 if (DescribeAddressIfStack(addr, access_size)) 378 return; 379 // Assume it is a heap address. 380 DescribeHeapAddress(addr, access_size); 381} 382 383// ------------------- Thread description -------------------- {{{1 384 385void DescribeThread(AsanThreadSummary *summary) { 386 CHECK(summary); 387 // No need to announce the main thread. 388 if (summary->tid() == 0 || summary->announced()) { 389 return; 390 } 391 summary->set_announced(true); 392 char tname[128]; 393 Printf("Thread T%d%s", summary->tid(), 394 ThreadNameWithParenthesis(summary->tid(), tname, sizeof(tname))); 395 Printf(" created by T%d%s here:\n", 396 summary->parent_tid(), 397 ThreadNameWithParenthesis(summary->parent_tid(), 398 tname, sizeof(tname))); 399 PrintStack(summary->stack()); 400 // Recursively described parent thread if needed. 401 if (flags()->print_full_thread_history) { 402 AsanThreadSummary *parent_summary = 403 asanThreadRegistry().FindByTid(summary->parent_tid()); 404 DescribeThread(parent_summary); 405 } 406} 407 408// -------------------- Different kinds of reports ----------------- {{{1 409 410// Use ScopedInErrorReport to run common actions just before and 411// immediately after printing error report. 412class ScopedInErrorReport { 413 public: 414 ScopedInErrorReport() { 415 static atomic_uint32_t num_calls; 416 static u32 reporting_thread_tid; 417 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 418 // Do not print more than one report, otherwise they will mix up. 419 // Error reporting functions shouldn't return at this situation, as 420 // they are defined as no-return. 421 Report("AddressSanitizer: while reporting a bug found another one." 422 "Ignoring.\n"); 423 u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 424 if (current_tid != reporting_thread_tid) { 425 // ASan found two bugs in different threads simultaneously. Sleep 426 // long enough to make sure that the thread which started to print 427 // an error report will finish doing it. 428 SleepForSeconds(Max(100, flags()->sleep_before_dying + 1)); 429 } 430 // If we're still not dead for some reason, use raw Exit() instead of 431 // Die() to bypass any additional checks. 432 Exit(flags()->exitcode); 433 } 434 ASAN_ON_ERROR(); 435 reporting_thread_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 436 Printf("====================================================" 437 "=============\n"); 438 if (reporting_thread_tid != kInvalidTid) { 439 // We started reporting an error message. Stop using the fake stack 440 // in case we call an instrumented function from a symbolizer. 441 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 442 CHECK(curr_thread); 443 curr_thread->fake_stack().StopUsingFakeStack(); 444 } 445 } 446 // Destructor is NORETURN, as functions that report errors are. 447 NORETURN ~ScopedInErrorReport() { 448 // Make sure the current thread is announced. 449 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 450 if (curr_thread) { 451 DescribeThread(curr_thread->summary()); 452 } 453 // Print memory stats. 454 if (flags()->print_stats) 455 __asan_print_accumulated_stats(); 456 if (error_report_callback) { 457 error_report_callback(error_message_buffer); 458 } 459 Report("ABORTING\n"); 460 Die(); 461 } 462}; 463 464void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { 465 ScopedInErrorReport in_report; 466 Decorator d; 467 Printf("%s", d.Warning()); 468 Report("ERROR: AddressSanitizer: SEGV on unknown address %p" 469 " (pc %p sp %p bp %p T%d)\n", 470 (void*)addr, (void*)pc, (void*)sp, (void*)bp, 471 asanThreadRegistry().GetCurrentTidOrInvalid()); 472 Printf("%s", d.EndWarning()); 473 Printf("AddressSanitizer can not provide additional info.\n"); 474 GET_STACK_TRACE_FATAL(pc, bp); 475 PrintStack(&stack); 476} 477 478void ReportDoubleFree(uptr addr, StackTrace *stack) { 479 ScopedInErrorReport in_report; 480 Decorator d; 481 Printf("%s", d.Warning()); 482 Report("ERROR: AddressSanitizer: attempting double-free on %p:\n", addr); 483 Printf("%s", d.EndWarning()); 484 PrintStack(stack); 485 DescribeHeapAddress(addr, 1); 486} 487 488void ReportFreeNotMalloced(uptr addr, StackTrace *stack) { 489 ScopedInErrorReport in_report; 490 Decorator d; 491 Printf("%s", d.Warning()); 492 Report("ERROR: AddressSanitizer: attempting free on address " 493 "which was not malloc()-ed: %p\n", addr); 494 Printf("%s", d.EndWarning()); 495 PrintStack(stack); 496 DescribeHeapAddress(addr, 1); 497} 498 499void ReportAllocTypeMismatch(uptr addr, StackTrace *stack, 500 AllocType alloc_type, 501 AllocType dealloc_type) { 502 static const char *alloc_names[] = 503 {"INVALID", "malloc", "operator new", "operator new []"}; 504 static const char *dealloc_names[] = 505 {"INVALID", "free", "operator delete", "operator delete []"}; 506 CHECK_NE(alloc_type, dealloc_type); 507 ScopedInErrorReport in_report; 508 Decorator d; 509 Printf("%s", d.Warning()); 510 Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", 511 alloc_names[alloc_type], dealloc_names[dealloc_type], addr); 512 Printf("%s", d.EndWarning()); 513 PrintStack(stack); 514 DescribeHeapAddress(addr, 1); 515 Report("HINT: if you don't care about these warnings you may set " 516 "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); 517} 518 519void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { 520 ScopedInErrorReport in_report; 521 Decorator d; 522 Printf("%s", d.Warning()); 523 Report("ERROR: AddressSanitizer: attempting to call " 524 "malloc_usable_size() for pointer which is " 525 "not owned: %p\n", addr); 526 Printf("%s", d.EndWarning()); 527 PrintStack(stack); 528 DescribeHeapAddress(addr, 1); 529} 530 531void ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { 532 ScopedInErrorReport in_report; 533 Decorator d; 534 Printf("%s", d.Warning()); 535 Report("ERROR: AddressSanitizer: attempting to call " 536 "__asan_get_allocated_size() for pointer which is " 537 "not owned: %p\n", addr); 538 Printf("%s", d.EndWarning()); 539 PrintStack(stack); 540 DescribeHeapAddress(addr, 1); 541} 542 543void ReportStringFunctionMemoryRangesOverlap( 544 const char *function, const char *offset1, uptr length1, 545 const char *offset2, uptr length2, StackTrace *stack) { 546 ScopedInErrorReport in_report; 547 Decorator d; 548 Printf("%s", d.Warning()); 549 Report("ERROR: AddressSanitizer: %s-param-overlap: " 550 "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 551 function, offset1, offset1 + length1, offset2, offset2 + length2); 552 Printf("%s", d.EndWarning()); 553 PrintStack(stack); 554 DescribeAddress((uptr)offset1, length1); 555 DescribeAddress((uptr)offset2, length2); 556} 557 558// ----------------------- Mac-specific reports ----------------- {{{1 559 560void WarnMacFreeUnallocated( 561 uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 562 // Just print a warning here. 563 Printf("free_common(%p) -- attempting to free unallocated memory.\n" 564 "AddressSanitizer is ignoring this error on Mac OS now.\n", 565 addr); 566 PrintZoneForPointer(addr, zone_ptr, zone_name); 567 PrintStack(stack); 568 DescribeHeapAddress(addr, 1); 569} 570 571void ReportMacMzReallocUnknown( 572 uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 573 ScopedInErrorReport in_report; 574 Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n" 575 "This is an unrecoverable problem, exiting now.\n", 576 addr); 577 PrintZoneForPointer(addr, zone_ptr, zone_name); 578 PrintStack(stack); 579 DescribeHeapAddress(addr, 1); 580} 581 582void ReportMacCfReallocUnknown( 583 uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 584 ScopedInErrorReport in_report; 585 Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" 586 "This is an unrecoverable problem, exiting now.\n", 587 addr); 588 PrintZoneForPointer(addr, zone_ptr, zone_name); 589 PrintStack(stack); 590 DescribeHeapAddress(addr, 1); 591} 592 593} // namespace __asan 594 595// --------------------------- Interface --------------------- {{{1 596using namespace __asan; // NOLINT 597 598void __asan_report_error(uptr pc, uptr bp, uptr sp, 599 uptr addr, bool is_write, uptr access_size) { 600 ScopedInErrorReport in_report; 601 602 // Determine the error type. 603 const char *bug_descr = "unknown-crash"; 604 if (AddrIsInMem(addr)) { 605 u8 *shadow_addr = (u8*)MemToShadow(addr); 606 // If we are accessing 16 bytes, look at the second shadow byte. 607 if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 608 shadow_addr++; 609 // If we are in the partial right redzone, look at the next shadow byte. 610 if (*shadow_addr > 0 && *shadow_addr < 128) 611 shadow_addr++; 612 switch (*shadow_addr) { 613 case kAsanHeapLeftRedzoneMagic: 614 case kAsanHeapRightRedzoneMagic: 615 bug_descr = "heap-buffer-overflow"; 616 break; 617 case kAsanHeapFreeMagic: 618 bug_descr = "heap-use-after-free"; 619 break; 620 case kAsanStackLeftRedzoneMagic: 621 bug_descr = "stack-buffer-underflow"; 622 break; 623 case kAsanInitializationOrderMagic: 624 bug_descr = "initialization-order-fiasco"; 625 break; 626 case kAsanStackMidRedzoneMagic: 627 case kAsanStackRightRedzoneMagic: 628 case kAsanStackPartialRedzoneMagic: 629 bug_descr = "stack-buffer-overflow"; 630 break; 631 case kAsanStackAfterReturnMagic: 632 bug_descr = "stack-use-after-return"; 633 break; 634 case kAsanUserPoisonedMemoryMagic: 635 bug_descr = "use-after-poison"; 636 break; 637 case kAsanStackUseAfterScopeMagic: 638 bug_descr = "stack-use-after-scope"; 639 break; 640 case kAsanGlobalRedzoneMagic: 641 bug_descr = "global-buffer-overflow"; 642 break; 643 } 644 } 645 Decorator d; 646 Printf("%s", d.Warning()); 647 Report("ERROR: AddressSanitizer: %s on address " 648 "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", 649 bug_descr, (void*)addr, pc, bp, sp); 650 Printf("%s", d.EndWarning()); 651 652 u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 653 char tname[128]; 654 Printf("%s%s of size %zu at %p thread T%d%s%s\n", 655 d.Access(), 656 access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 657 access_size, (void*)addr, curr_tid, 658 ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)), 659 d.EndAccess()); 660 661 GET_STACK_TRACE_FATAL(pc, bp); 662 PrintStack(&stack); 663 664 DescribeAddress(addr, access_size); 665 666 PrintShadowMemoryForAddress(addr); 667} 668 669void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { 670 error_report_callback = callback; 671 if (callback) { 672 error_message_buffer_size = 1 << 16; 673 error_message_buffer = 674 (char*)MmapOrDie(error_message_buffer_size, __FUNCTION__); 675 error_message_buffer_pos = 0; 676 } 677} 678 679void __asan_describe_address(uptr addr) { 680 DescribeAddress(addr, 1); 681} 682 683#if !SANITIZER_SUPPORTS_WEAK_HOOKS 684// Provide default implementation of __asan_on_error that does nothing 685// and may be overriden by user. 686SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE NOINLINE 687void __asan_on_error() {} 688#endif 689