17354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov//===-- asan_report.cc ----------------------------------------------------===// 27354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// 37354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// The LLVM Compiler Infrastructure 47354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// 57354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// This file is distributed under the University of Illinois Open Source 67354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// License. See LICENSE.TXT for details. 77354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// 87354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov//===----------------------------------------------------------------------===// 97354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// 107354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// This file is a part of AddressSanitizer, an address sanity checker. 117354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// 127354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov// This file contains error reporting code. 137354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov//===----------------------------------------------------------------------===// 149873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov#include "asan_flags.h" 157354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov#include "asan_internal.h" 16e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov#include "asan_mapping.h" 177354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov#include "asan_report.h" 187354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov#include "asan_stack.h" 19e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov#include "asan_thread.h" 207354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov#include "asan_thread_registry.h" 217354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 227354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonovnamespace __asan { 237354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 24f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov// -------------------- User-specified callbacks ----------------- {{{1 25c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic void (*error_report_callback)(const char*); 26c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic char *error_message_buffer = 0; 27c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_pos = 0; 28c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_size = 0; 29c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 30c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid AppendToErrorMessageBuffer(const char *buffer) { 31c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (error_message_buffer) { 32c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr length = internal_strlen(buffer); 33c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov CHECK_GE(error_message_buffer_size, error_message_buffer_pos); 34c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr remaining = error_message_buffer_size - error_message_buffer_pos; 35c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov internal_strncpy(error_message_buffer + error_message_buffer_pos, 36c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov buffer, remaining); 37c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer[error_message_buffer_size - 1] = '\0'; 38c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // FIXME: reallocate the buffer instead of truncating the message. 39c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos += remaining > length ? length : remaining; 40c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 41c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 42c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 43f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonovstatic void (*on_error_callback)(void); 44f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov 459873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// ---------------------- Helper functions ----------------------- {{{1 469873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 479873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovstatic void PrintBytes(const char *before, uptr *a) { 489873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov u8 *bytes = (u8*)a; 499873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov uptr byte_num = (__WORDSIZE) / 8; 50283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%s%p:", before, (void*)a); 519873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov for (uptr i = 0; i < byte_num; i++) { 52283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" %x%x", bytes[i] >> 4, bytes[i] & 15); 539873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 54283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("\n"); 559873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 569873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 579873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovstatic void PrintShadowMemoryForAddress(uptr addr) { 589873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (!AddrIsInMem(addr)) 599873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov return; 609873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov uptr shadow_addr = MemToShadow(addr); 61283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("Shadow byte and word:\n"); 62283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" %p: %x\n", (void*)shadow_addr, *(unsigned char*)shadow_addr); 639873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov uptr aligned_shadow = shadow_addr & ~(kWordSize - 1); 649873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov PrintBytes(" ", (uptr*)(aligned_shadow)); 65283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("More shadow bytes:\n"); 669873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov for (int i = -4; i <= 4; i++) { 679873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov const char *prefix = (i == 0) ? "=>" : " "; 689873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov PrintBytes(prefix, (uptr*)(aligned_shadow + i * kWordSize)); 699873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 709873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 719873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 729873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovstatic void PrintZoneForPointer(uptr ptr, uptr zone_ptr, 739873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov const char *zone_name) { 749873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_ptr) { 759873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_name) { 76283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n", 779873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr, zone_name); 789873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 79283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n", 809873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr); 819873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 829873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 83283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = 0\n", ptr); 849873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 859873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 869873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 87e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// ---------------------- Address Descriptions ------------------- {{{1 88e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 89e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovstatic bool IsASCII(unsigned char c) { 909873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov return /*0x00 <= c &&*/ c <= 0x7F; 91e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 92e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 93e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov// Check if the global is a zero-terminated ASCII string. If so, print it. 94e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovstatic void PrintGlobalNameIfASCII(const __asan_global &g) { 95e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov for (uptr p = g.beg; p < g.beg + g.size - 1; p++) { 96e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (!IsASCII(*(unsigned char*)p)) return; 97e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } 98e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (*(char*)(g.beg + g.size - 1) != 0) return; 99283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" '%s' is ascii string '%s'\n", g.name, (char*)g.beg); 100e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 101e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 102e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovbool DescribeAddressRelativeToGlobal(uptr addr, const __asan_global &g) { 103e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr < g.beg - kGlobalAndStackRedzone) return false; 104e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr >= g.beg + g.size_with_redzone) return false; 105283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%p is located ", (void*)addr); 106e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr < g.beg) { 107283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%zd bytes to the left", g.beg - addr); 108e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } else if (addr >= g.beg + g.size) { 109283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%zd bytes to the right", addr - (g.beg + g.size)); 110e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } else { 111283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%zd bytes inside", addr - g.beg); // Can it happen? 112e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } 113283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" of global variable '%s' (0x%zx) of size %zu\n", 114e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov g.name, g.beg, g.size); 115e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov PrintGlobalNameIfASCII(g); 116e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov return true; 117e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 118e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 119e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfShadow(uptr addr) { 120e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInMem(addr)) 121e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 122e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov static const char kAddrInShadowReport[] = 123e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "Address %p is located in the %s.\n"; 124e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInShadowGap(addr)) { 125283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "shadow gap area"); 126e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 127e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 128e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInHighShadow(addr)) { 129283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "high shadow area"); 130e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 131e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 132e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInLowShadow(addr)) { 133283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "low shadow area"); 134e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 135e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 136e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(0 && "Address is not in memory and not in shadow?"); 137e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 138e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 139e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 140e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfStack(uptr addr, uptr access_size) { 141e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 142e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (!t) return false; 143e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const sptr kBufSize = 4095; 144e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char buf[kBufSize]; 145e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr offset = 0; 146e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 147e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // This string is created by the compiler and has the following form: 148e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // "FunctioName n alloc_1 alloc_2 ... alloc_n" 149e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // where alloc_i looks like "offset size len ObjectName ". 150e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(frame_descr); 151e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report the function name and the offset. 152e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const char *name_end = internal_strchr(frame_descr, ' '); 153e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(name_end); 154e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov buf[0] = 0; 155e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov internal_strncat(buf, frame_descr, 156e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov Min(kBufSize, 157e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov static_cast<sptr>(name_end - frame_descr))); 158283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("Address %p is located at offset %zu " 159e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "in frame <%s> of T%d's stack:\n", 160e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov (void*)addr, offset, buf, t->tid()); 161e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report the number of stack objects. 162e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char *p; 163e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr n_objects = internal_simple_strtoll(name_end, &p, 10); 164e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(n_objects > 0); 165283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" This frame has %zu object(s):\n", n_objects); 166e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report all objects in this frame. 167e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov for (uptr i = 0; i < n_objects; i++) { 168e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr beg, size; 169e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov sptr len; 170e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov beg = internal_simple_strtoll(p, &p, 10); 171e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov size = internal_simple_strtoll(p, &p, 10); 172e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov len = internal_simple_strtoll(p, &p, 10); 173e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 174283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer can't parse the stack frame " 175e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "descriptor: |%s|\n", frame_descr); 176e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov break; 177e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 178e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p++; 179e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov buf[0] = 0; 180e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov internal_strncat(buf, p, Min(kBufSize, len)); 181e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p += len; 182283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); 183e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 184283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("HINT: this may be a false positive if your program uses " 185e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "some custom stack unwind mechanism\n" 186e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov " (longjmp and C++ exceptions *are* supported)\n"); 18771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(t->summary()); 188e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 189e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 190e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 191e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovvoid DescribeAddress(uptr addr, uptr access_size) { 192e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Check if this is shadow or shadow gap. 193e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfShadow(addr)) 194e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 195e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(AddrIsInMem(addr)); 196e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfGlobal(addr)) 197e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 198e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfStack(addr, access_size)) 199e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 200e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Assume it is a heap address. 201e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov DescribeHeapAddress(addr, access_size); 202e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 203e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 20471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov// ------------------- Thread description -------------------- {{{1 20571b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 20671b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonovvoid DescribeThread(AsanThreadSummary *summary) { 20771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov CHECK(summary); 20871b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // No need to announce the main thread. 20971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov if (summary->tid() == 0 || summary->announced()) { 21071b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov return; 21171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 21271b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov summary->set_announced(true); 21371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov Printf("Thread T%d created by T%d here:\n", 21471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov summary->tid(), summary->parent_tid()); 21571b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov PrintStack(summary->stack()); 21671b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // Recursively described parent thread if needed. 21771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov if (flags()->print_full_thread_history) { 21871b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov AsanThreadSummary *parent_summary = 21971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov asanThreadRegistry().FindByTid(summary->parent_tid()); 22071b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(parent_summary); 22171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 22271b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov} 22371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 224e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// -------------------- Different kinds of reports ----------------- {{{1 225e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 2269873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// Use ScopedInErrorReport to run common actions just before and 2279873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// immediately after printing error report. 2289873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovclass ScopedInErrorReport { 2299873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov public: 2309873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport() { 2319873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov static atomic_uint32_t num_calls; 2329873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 2339873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Do not print more than one report, otherwise they will mix up. 2349873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Error reporting functions shouldn't return at this situation, as 2359873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // they are defined as no-return. 236283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("AddressSanitizer: while reporting a bug found another one." 2379873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov "Ignoring.\n"); 238be98caf9fe5e7b94b2009616cf31f0d87cf98d67Alexey Samsonov // We can't use infinite busy loop here, as ASan may try to report an 239be98caf9fe5e7b94b2009616cf31f0d87cf98d67Alexey Samsonov // error while another error report is being printed (e.g. if the code 240be98caf9fe5e7b94b2009616cf31f0d87cf98d67Alexey Samsonov // that prints error report for buffer overflow results in SEGV). 2419873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov SleepForSeconds(Max(5, flags()->sleep_before_dying + 1)); 242be98caf9fe5e7b94b2009616cf31f0d87cf98d67Alexey Samsonov Die(); 2439873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 244f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov if (on_error_callback) { 245f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov on_error_callback(); 246f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov } 247283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("====================================================" 2489873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov "=============\n"); 2499873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 2509873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (curr_thread) { 2519873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // We started reporting an error message. Stop using the fake stack 2529873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // in case we call an instrumented function from a symbolizer. 2539873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov curr_thread->fake_stack().StopUsingFakeStack(); 2549873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 2559873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 2569873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Destructor is NORETURN, as functions that report errors are. 2579873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov NORETURN ~ScopedInErrorReport() { 2589873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Make sure the current thread is announced. 2599873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 2609873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (curr_thread) { 26171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(curr_thread->summary()); 2629873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 2639873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Print memory stats. 2649873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov __asan_print_accumulated_stats(); 2659873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (error_report_callback) { 2669873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov error_report_callback(error_message_buffer); 2679873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 268283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ABORTING\n"); 2699873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov Die(); 2709873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 2719873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov}; 2729873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 273f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic push 274f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic ignored "-Winvalid-noreturn" 275f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar 2767354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonovvoid ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { 2779873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 278283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer crashed on unknown address %p" 2797354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov " (pc %p sp %p bp %p T%d)\n", 2807354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov (void*)addr, (void*)pc, (void*)sp, (void*)bp, 2817354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov asanThreadRegistry().GetCurrentTidOrInvalid()); 282283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer can not provide additional info.\n"); 2837354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 284cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(&stack); 2857354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov} 2867354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 287c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportDoubleFree(uptr addr, StackTrace *stack) { 2889873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 289283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer attempting double-free on %p:\n", addr); 290cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 291f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 292f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 293f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 294c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportFreeNotMalloced(uptr addr, StackTrace *stack) { 2959873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 296283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer attempting free on address " 297f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "which was not malloc()-ed: %p\n", addr); 298cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 2999873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 300f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 301f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 302c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { 3039873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 304283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer attempting to call " 305f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "malloc_usable_size() for pointer which is " 306f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 307cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 308f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 309f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 310f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 311c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { 3129873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 313283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer attempting to call " 314f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "__asan_get_allocated_size() for pointer which is " 315f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 316cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 317f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 318f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 319f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 320487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonovvoid ReportStringFunctionMemoryRangesOverlap( 321487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov const char *function, const char *offset1, uptr length1, 322c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany const char *offset2, uptr length2, StackTrace *stack) { 3239873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 324283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer %s-param-overlap: " 325487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 326487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov function, offset1, offset1 + length1, offset2, offset2 + length2); 327cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 3289873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset1, length1); 3299873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset2, length2); 330487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov} 331f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 332f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic pop 333f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar 334663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov// ----------------------- Mac-specific reports ----------------- {{{1 335663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 336663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid WarnMacFreeUnallocated( 337c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 3389873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Just print a warning here. 339283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("free_common(%p) -- attempting to free unallocated memory.\n" 340663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "AddressSanitizer is ignoring this error on Mac OS now.\n", 341663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 342663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 343cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 3449873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 345663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 346663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 347f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic push 348f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic ignored "-Winvalid-noreturn" 349f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar 350663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacMzReallocUnknown( 351c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 3529873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 353283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n" 354663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 355663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 356663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 357cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 3589873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 359663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 360663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 361663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacCfReallocUnknown( 362c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 3639873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 364283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" 365663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 366663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 367663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 368cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 3699873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 370c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 371c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 372f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar#pragma clang diagnostic pop 373f4e21fb6369497a271373ef4530e33a40e607542Daniel Dunbar 374812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov} // namespace __asan 375812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 376812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov// --------------------------- Interface --------------------- {{{1 377812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonovusing namespace __asan; // NOLINT 378812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 379812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonovvoid __asan_report_error(uptr pc, uptr bp, uptr sp, 380812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov uptr addr, bool is_write, uptr access_size) { 3819873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 382c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 3839873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Determine the error type. 384c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov const char *bug_descr = "unknown-crash"; 385c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (AddrIsInMem(addr)) { 386c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov u8 *shadow_addr = (u8*)MemToShadow(addr); 387c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are accessing 16 bytes, look at the second shadow byte. 388c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 389c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 390c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are in the partial right redzone, look at the next shadow byte. 391c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr > 0 && *shadow_addr < 128) 392c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 393c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov switch (*shadow_addr) { 394c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapLeftRedzoneMagic: 395c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapRightRedzoneMagic: 396c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-buffer-overflow"; 397c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 398c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapFreeMagic: 399c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-use-after-free"; 400c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 401c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackLeftRedzoneMagic: 402c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-underflow"; 403c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 4043945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany case kAsanInitializationOrderMagic: 4053945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany bug_descr = "initialization-order-fiasco"; 4063945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany break; 407c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackMidRedzoneMagic: 408c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackRightRedzoneMagic: 409c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackPartialRedzoneMagic: 410c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-overflow"; 411c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 412c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackAfterReturnMagic: 413c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-use-after-return"; 414c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 415c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanUserPoisonedMemoryMagic: 416c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "use-after-poison"; 417c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 418c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanGlobalRedzoneMagic: 419c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "global-buffer-overflow"; 420c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 421c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 422c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 423c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 424283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ERROR: AddressSanitizer %s on address " 425c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", 426c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr, (void*)addr, pc, bp, sp); 427c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 4289873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov u32 curr_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 429283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("%s of size %zu at %p thread T%d\n", 430c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 431c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov access_size, (void*)addr, curr_tid); 432c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 433c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 434cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(&stack); 435c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 436c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov DescribeAddress(addr, access_size); 437c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 4389873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov PrintShadowMemoryForAddress(addr); 439c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 440c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 441c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { 442c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_report_callback = callback; 443c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (callback) { 444c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_size = 1 << 16; 445c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer = 446c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov (char*)MmapOrDie(error_message_buffer_size, __FUNCTION__); 447c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos = 0; 448c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 449c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 450f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov 451f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonovvoid NOINLINE __asan_set_on_error_callback(void (*callback)(void)) { 452f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov on_error_callback = callback; 453f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov} 454