asan_report.cc revision 89c1384464848c1ad041becf8b97936fa10de21b
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" 2158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany#include "sanitizer_common/sanitizer_common.h" 2258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany#include "sanitizer_common/sanitizer_report_decorator.h" 239c92748b8fa3b833924138a6ae1e653972c9de3bAlexey Samsonov#include "sanitizer_common/sanitizer_symbolizer.h" 247354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 257354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonovnamespace __asan { 267354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 27f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov// -------------------- User-specified callbacks ----------------- {{{1 28c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic void (*error_report_callback)(const char*); 29c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic char *error_message_buffer = 0; 30c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_pos = 0; 31c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_size = 0; 32c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 33c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid AppendToErrorMessageBuffer(const char *buffer) { 34c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (error_message_buffer) { 35c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr length = internal_strlen(buffer); 36c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov CHECK_GE(error_message_buffer_size, error_message_buffer_pos); 37c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr remaining = error_message_buffer_size - error_message_buffer_pos; 38c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov internal_strncpy(error_message_buffer + error_message_buffer_pos, 39c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov buffer, remaining); 40c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer[error_message_buffer_size - 1] = '\0'; 41c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // FIXME: reallocate the buffer instead of truncating the message. 42c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos += remaining > length ? length : remaining; 43c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 44c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 45c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 4658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany// ---------------------- Decorator ------------------------------ {{{1 479514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryanybool PrintsToTtyCached() { 489514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany static int cached = 0; 499514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany static bool prints_to_tty; 509514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany if (!cached) { // Ok wrt threads since we are printing only from one thread. 519514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany prints_to_tty = PrintsToTty(); 529514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany cached = 1; 539514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany } 549514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return prints_to_tty; 559514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany} 5658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryanyclass Decorator: private __sanitizer::AnsiColorDecorator { 5758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany public: 589514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { } 5958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Warning() { return Red(); } 6058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndWarning() { return Default(); } 6158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Access() { return Blue(); } 6258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndAccess() { return Default(); } 6358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Location() { return Green(); } 6458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndLocation() { return Default(); } 6558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Allocation() { return Magenta(); } 6658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndAllocation() { return Default(); } 679514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany 689514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *ShadowByte(u8 byte) { 699514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany switch (byte) { 709514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapLeftRedzoneMagic: 719514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapRightRedzoneMagic: 729514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 739514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapFreeMagic: 749514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 759514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackLeftRedzoneMagic: 769514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackMidRedzoneMagic: 779514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackRightRedzoneMagic: 789514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackPartialRedzoneMagic: 799514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 809514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackAfterReturnMagic: 819514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 829514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanInitializationOrderMagic: 839514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Cyan(); 849514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanUserPoisonedMemoryMagic: 859514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Blue(); 869514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackUseAfterScopeMagic: 879514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 889514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanGlobalRedzoneMagic: 899514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 909514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanInternalHeapMagic: 919514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Yellow(); 929514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany default: 939514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Default(); 949514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany } 959514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany } 969514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *EndShadowByte() { return Default(); } 9758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany}; 9858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany 999873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// ---------------------- Helper functions ----------------------- {{{1 1009873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 1019514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryanystatic void PrintShadowByte(const char *before, u8 byte, 1029514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *after = "\n") { 1039514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Decorator d; 1049514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Printf("%s%s%x%x%s%s", before, 1059514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany d.ShadowByte(byte), byte >> 4, byte & 15, d.EndShadowByte(), after); 1069514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany} 1079514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany 1089514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryanystatic void PrintShadowBytes(const char *before, u8 *bytes, 1099514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany u8 *guilty, uptr n) { 1109514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Decorator d; 1119514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany if (before) 1129514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Printf("%s%p:", before, bytes); 1139514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany for (uptr i = 0; i < n; i++) { 1149514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany u8 *p = bytes + i; 1159514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *before = p == guilty ? "[" : 1169514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany p - 1 == guilty ? "" : " "; 1179514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *after = p == guilty ? "]" : ""; 1189514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(before, *p, after); 1199873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 120283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("\n"); 1219873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 1229873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 12395f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryanystatic void PrintLegend() { 1249514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Printf("Shadow byte legend (one shadow byte represents %d " 1259514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany "application bytes):\n", (int)SHADOW_GRANULARITY); 1269514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Addressable: ", 0); 1279514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Printf(" Partially addressable: "); 1289514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany for (uptr i = 1; i < SHADOW_GRANULARITY; i++) 1299514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte("", i, " "); 1309514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Printf("\n"); 1319514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Heap left redzone: ", kAsanHeapLeftRedzoneMagic); 1329514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Heap righ redzone: ", kAsanHeapRightRedzoneMagic); 1339514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Freed Heap region: ", kAsanHeapFreeMagic); 1349514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack left redzone: ", kAsanStackLeftRedzoneMagic); 1359514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack mid redzone: ", kAsanStackMidRedzoneMagic); 1369514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack right redzone: ", kAsanStackRightRedzoneMagic); 1379514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack partial redzone: ", kAsanStackPartialRedzoneMagic); 1389514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack after return: ", kAsanStackAfterReturnMagic); 1399514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Stack use after scope: ", kAsanStackUseAfterScopeMagic); 1409514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Global redzone: ", kAsanGlobalRedzoneMagic); 1419514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Global init order: ", kAsanInitializationOrderMagic); 1429514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" Poisoned by user: ", kAsanUserPoisonedMemoryMagic); 1439514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany PrintShadowByte(" ASan internal: ", kAsanInternalHeapMagic); 1449873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 1459873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 14695f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryanystatic void PrintShadowMemoryForAddress(uptr addr) { 14795f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany if (!AddrIsInMem(addr)) 14895f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany return; 14995f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany uptr shadow_addr = MemToShadow(addr); 15095f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany const uptr n_bytes_per_row = 16; 15195f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1); 15295f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany Printf("Shadow bytes around the buggy address:\n"); 15395f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany for (int i = -5; i <= 5; i++) { 15495f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany const char *prefix = (i == 0) ? "=>" : " "; 15595f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany PrintShadowBytes(prefix, 15695f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany (u8*)(aligned_shadow + i * n_bytes_per_row), 15795f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany (u8*)shadow_addr, n_bytes_per_row); 15895f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany } 15995f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany if (flags()->print_legend) 16095f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany PrintLegend(); 16195f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany} 16295f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany 1639873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovstatic void PrintZoneForPointer(uptr ptr, uptr zone_ptr, 1649873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov const char *zone_name) { 1659873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_ptr) { 1669873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_name) { 167283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n", 1689873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr, zone_name); 1699873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 170283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n", 1719873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr); 1729873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 1739873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 174283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = 0\n", ptr); 1759873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 1769873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 1779873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 178e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// ---------------------- Address Descriptions ------------------- {{{1 179e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 180e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovstatic bool IsASCII(unsigned char c) { 1819873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov return /*0x00 <= c &&*/ c <= 0x7F; 182e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 183e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 184e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov// Check if the global is a zero-terminated ASCII string. If so, print it. 185e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovstatic void PrintGlobalNameIfASCII(const __asan_global &g) { 186e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov for (uptr p = g.beg; p < g.beg + g.size - 1; p++) { 187e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (!IsASCII(*(unsigned char*)p)) return; 188e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } 189e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (*(char*)(g.beg + g.size - 1) != 0) return; 190283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" '%s' is ascii string '%s'\n", g.name, (char*)g.beg); 191e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 192e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 193589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanovbool DescribeAddressRelativeToGlobal(uptr addr, uptr size, 194589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov const __asan_global &g) { 195a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany static const uptr kMinimalDistanceFromAnotherGlobal = 64; 196a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; 197e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr >= g.beg + g.size_with_redzone) return false; 19858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 19958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Location()); 200e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr < g.beg) { 201589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes to the left", (void*)addr, g.beg - addr); 202589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } else if (addr + size > g.beg + g.size) { 203589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (addr < g.beg + g.size) 204589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov addr = g.beg + g.size; 205589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes to the right", (void*)addr, 206589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov addr - (g.beg + g.size)); 207e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } else { 208589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov // Can it happen? 209589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes inside", (void*)addr, addr - g.beg); 210e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } 21160c9f441255211f17c4d355ead94392ba1841355Kostya Serebryany Printf(" of global variable '%s' from '%s' (0x%zx) of size %zu\n", 21260c9f441255211f17c4d355ead94392ba1841355Kostya Serebryany g.name, g.module_name, g.beg, g.size); 21358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndLocation()); 214e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov PrintGlobalNameIfASCII(g); 215e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov return true; 216e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 217e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 218e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfShadow(uptr addr) { 219e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInMem(addr)) 220e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 221e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov static const char kAddrInShadowReport[] = 222e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "Address %p is located in the %s.\n"; 223e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInShadowGap(addr)) { 224283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "shadow gap area"); 225e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 226e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 227e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInHighShadow(addr)) { 228283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "high shadow area"); 229e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 230e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 231e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInLowShadow(addr)) { 232283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "low shadow area"); 233e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 234e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 235e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(0 && "Address is not in memory and not in shadow?"); 236e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 237e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 238e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 239e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfStack(uptr addr, uptr access_size) { 240e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 241e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (!t) return false; 242e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const sptr kBufSize = 4095; 243e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char buf[kBufSize]; 244e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr offset = 0; 245e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 246e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // This string is created by the compiler and has the following form: 247e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // "FunctioName n alloc_1 alloc_2 ... alloc_n" 248e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // where alloc_i looks like "offset size len ObjectName ". 249e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(frame_descr); 250e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report the function name and the offset. 251e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov const char *name_end = internal_strchr(frame_descr, ' '); 252e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(name_end); 253e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov buf[0] = 0; 254e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov internal_strncat(buf, frame_descr, 255e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov Min(kBufSize, 256e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov static_cast<sptr>(name_end - frame_descr))); 25758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 25858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Location()); 259283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("Address %p is located at offset %zu " 260e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "in frame <%s> of T%d's stack:\n", 2619c92748b8fa3b833924138a6ae1e653972c9de3bAlexey Samsonov (void*)addr, offset, Demangle(buf), t->tid()); 26258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndLocation()); 263e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report the number of stack objects. 264e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char *p; 265e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr n_objects = internal_simple_strtoll(name_end, &p, 10); 266e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(n_objects > 0); 267283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" This frame has %zu object(s):\n", n_objects); 268e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report all objects in this frame. 269e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov for (uptr i = 0; i < n_objects; i++) { 270e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr beg, size; 271e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov sptr len; 272e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov beg = internal_simple_strtoll(p, &p, 10); 273e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov size = internal_simple_strtoll(p, &p, 10); 274e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov len = internal_simple_strtoll(p, &p, 10); 275e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 276283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer can't parse the stack frame " 277e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "descriptor: |%s|\n", frame_descr); 278e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov break; 279e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 280e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p++; 281e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov buf[0] = 0; 282e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov internal_strncat(buf, p, Min(kBufSize, len)); 283e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p += len; 284283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); 285e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 286283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("HINT: this may be a false positive if your program uses " 2870870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov "some custom stack unwind mechanism or swapcontext\n" 288e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov " (longjmp and C++ exceptions *are* supported)\n"); 28971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(t->summary()); 290e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 291e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 292e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 2935c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonovstatic void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr, 2945c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov uptr access_size) { 295589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov sptr offset; 29658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 29758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Location()); 298589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (chunk.AddrIsAtLeft(addr, access_size, &offset)) { 299589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes to the left of", (void*)addr, offset); 3005c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else if (chunk.AddrIsAtRight(addr, access_size, &offset)) { 301589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (offset < 0) { 302589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov addr -= offset; 303589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov offset = 0; 304589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } 305589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes to the right of", (void*)addr, offset); 306589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } else if (chunk.AddrIsInside(addr, access_size, &offset)) { 307589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located %zd bytes inside of", (void*)addr, offset); 3085c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else { 309589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov Printf("%p is located somewhere around (this is AddressSanitizer bug!)", 310589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov (void*)addr); 3115c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } 3125c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov Printf(" %zu-byte region [%p,%p)\n", chunk.UsedSize(), 3135c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov (void*)(chunk.Beg()), (void*)(chunk.End())); 31458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndLocation()); 3155c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov} 3165c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov 317716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany// Return " (thread_name) " or an empty string if the name is empty. 318716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryanyconst char *ThreadNameWithParenthesis(AsanThreadSummary *t, char buff[], 319716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany uptr buff_len) { 320716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany const char *name = t->name(); 321716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany if (*name == 0) return ""; 322716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany buff[0] = 0; 323716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany internal_strncat(buff, " (", 3); 324716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany internal_strncat(buff, name, buff_len - 4); 325716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany internal_strncat(buff, ")", 2); 326716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany return buff; 327716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany} 328716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany 329716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryanyconst char *ThreadNameWithParenthesis(u32 tid, char buff[], 330716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany uptr buff_len) { 331716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany if (tid == kInvalidTid) return ""; 332716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany AsanThreadSummary *t = asanThreadRegistry().FindByTid(tid); 333716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany return ThreadNameWithParenthesis(t, buff, buff_len); 334716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany} 335716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany 3365c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonovvoid DescribeHeapAddress(uptr addr, uptr access_size) { 3375c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov AsanChunkView chunk = FindHeapChunkByAddress(addr); 3385c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov if (!chunk.IsValid()) return; 3395c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeAccessToHeapChunk(chunk, addr, access_size); 3405c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov CHECK(chunk.AllocTid() != kInvalidTid); 3415c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov AsanThreadSummary *alloc_thread = 3425c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov asanThreadRegistry().FindByTid(chunk.AllocTid()); 3435c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov StackTrace alloc_stack; 3445c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov chunk.GetAllocStack(&alloc_stack); 34589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov AsanThread *t = GetCurrentThread(); 3465c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov CHECK(t); 347716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 34858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 3495c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov if (chunk.FreeTid() != kInvalidTid) { 3505c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov AsanThreadSummary *free_thread = 3515c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov asanThreadRegistry().FindByTid(chunk.FreeTid()); 35258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(), 35358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany free_thread->tid(), 35458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)), 35558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 3565c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov StackTrace free_stack; 3575c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov chunk.GetFreeStack(&free_stack); 3585c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov PrintStack(&free_stack); 35958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%spreviously allocated by thread T%d%s here:%s\n", 36058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.Allocation(), alloc_thread->tid(), 36158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 36258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 3635c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov PrintStack(&alloc_stack); 3645c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeThread(t->summary()); 3655c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeThread(free_thread); 3665c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeThread(alloc_thread); 3675c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else { 36858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(), 36958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany alloc_thread->tid(), 37058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 37158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 3725c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov PrintStack(&alloc_stack); 3735c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeThread(t->summary()); 3745c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeThread(alloc_thread); 3755c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } 3765c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov} 3775c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov 378e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovvoid DescribeAddress(uptr addr, uptr access_size) { 379e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Check if this is shadow or shadow gap. 380e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfShadow(addr)) 381e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 382e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(AddrIsInMem(addr)); 383589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (DescribeAddressIfGlobal(addr, access_size)) 384e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 385e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfStack(addr, access_size)) 386e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 387e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Assume it is a heap address. 388e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov DescribeHeapAddress(addr, access_size); 389e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 390e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 39171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov// ------------------- Thread description -------------------- {{{1 39271b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 39371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonovvoid DescribeThread(AsanThreadSummary *summary) { 39471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov CHECK(summary); 39571b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // No need to announce the main thread. 39671b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov if (summary->tid() == 0 || summary->announced()) { 39771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov return; 39871b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 39971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov summary->set_announced(true); 400716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 401716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany Printf("Thread T%d%s", summary->tid(), 402716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany ThreadNameWithParenthesis(summary->tid(), tname, sizeof(tname))); 403716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany Printf(" created by T%d%s here:\n", 404716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany summary->parent_tid(), 405716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany ThreadNameWithParenthesis(summary->parent_tid(), 406716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany tname, sizeof(tname))); 40771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov PrintStack(summary->stack()); 40871b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // Recursively described parent thread if needed. 40971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov if (flags()->print_full_thread_history) { 41071b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov AsanThreadSummary *parent_summary = 41171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov asanThreadRegistry().FindByTid(summary->parent_tid()); 41271b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(parent_summary); 41371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 41471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov} 41571b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 416e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// -------------------- Different kinds of reports ----------------- {{{1 417e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 4189873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// Use ScopedInErrorReport to run common actions just before and 4199873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// immediately after printing error report. 4209873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovclass ScopedInErrorReport { 4219873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov public: 4229873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport() { 4239873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov static atomic_uint32_t num_calls; 42462e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov static u32 reporting_thread_tid; 4259873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 4269873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Do not print more than one report, otherwise they will mix up. 4279873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Error reporting functions shouldn't return at this situation, as 4289873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // they are defined as no-return. 429283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("AddressSanitizer: while reporting a bug found another one." 4309873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov "Ignoring.\n"); 43189c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov u32 current_tid = GetCurrentTidOrInvalid(); 43262e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov if (current_tid != reporting_thread_tid) { 43362e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // ASan found two bugs in different threads simultaneously. Sleep 43462e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // long enough to make sure that the thread which started to print 43562e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // an error report will finish doing it. 43662e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov SleepForSeconds(Max(100, flags()->sleep_before_dying + 1)); 43762e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov } 438f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov // If we're still not dead for some reason, use raw _exit() instead of 439031633bef8dff03f4e8943a12e34856bd66bbc78Alexey Samsonov // Die() to bypass any additional checks. 440f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov internal__exit(flags()->exitcode); 4419873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 4426a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov ASAN_ON_ERROR(); 44389c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov reporting_thread_tid = GetCurrentTidOrInvalid(); 444283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("====================================================" 44562e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov "=============\n"); 44662e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov if (reporting_thread_tid != kInvalidTid) { 4479873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // We started reporting an error message. Stop using the fake stack 4489873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // in case we call an instrumented function from a symbolizer. 44989c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov AsanThread *curr_thread = GetCurrentThread(); 45062e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov CHECK(curr_thread); 4519873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov curr_thread->fake_stack().StopUsingFakeStack(); 4529873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 4539873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 4549873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Destructor is NORETURN, as functions that report errors are. 4559873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov NORETURN ~ScopedInErrorReport() { 4569873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Make sure the current thread is announced. 45789c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov AsanThread *curr_thread = GetCurrentThread(); 4589873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (curr_thread) { 45971b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov DescribeThread(curr_thread->summary()); 4609873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 4619873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Print memory stats. 46295f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany if (flags()->print_stats) 46395f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany __asan_print_accumulated_stats(); 4649873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (error_report_callback) { 4659873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov error_report_callback(error_message_buffer); 4669873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 467283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ABORTING\n"); 4689873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov Die(); 4699873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 4709873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov}; 4719873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 4722673fd8406197c42f16cede6d287f72169298c2eKostya Serebryanystatic void ReportSummary(const char *error_type, StackTrace *stack) { 4732673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany if (!stack->size) return; 4742673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany if (IsSymbolizerAvailable()) { 4752673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany AddressInfo ai; 4762673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany // Currently, we include the first stack frame into the report summary. 4772673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). 4782673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany SymbolizeCode(stack->trace[0], &ai, 1); 4792673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportErrorSummary(error_type, 4802673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany StripPathPrefix(ai.file, flags()->strip_path_prefix), 4812673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ai.line, ai.function); 4822673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany } 4832673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany // FIXME: do we need to print anything at all if there is no symbolizer? 4842673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany} 4852673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany 4867354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonovvoid ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { 4879873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 48858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 48958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 49069d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: SEGV on unknown address %p" 4917354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov " (pc %p sp %p bp %p T%d)\n", 4927354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov (void*)addr, (void*)pc, (void*)sp, (void*)bp, 49389c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov GetCurrentTidOrInvalid()); 49458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 495283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer can not provide additional info.\n"); 496a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_FATAL(pc, bp); 497cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(&stack); 4982673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("SEGV", &stack); 4997354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov} 5007354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 501c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportDoubleFree(uptr addr, StackTrace *stack) { 5029873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 50358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 50458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 50569d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting double-free on %p:\n", addr); 50658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 507cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 508f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 5092673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("double-free", stack); 510f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 511f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 512c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportFreeNotMalloced(uptr addr, StackTrace *stack) { 5139873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 51458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 51558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 51669d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting free on address " 517f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "which was not malloc()-ed: %p\n", addr); 51858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 519cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 5209873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 5212673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("bad-free", stack); 522f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 523f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 524fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid ReportAllocTypeMismatch(uptr addr, StackTrace *stack, 525fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany AllocType alloc_type, 526fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany AllocType dealloc_type) { 527fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany static const char *alloc_names[] = 528fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany {"INVALID", "malloc", "operator new", "operator new []"}; 529fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany static const char *dealloc_names[] = 530fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany {"INVALID", "free", "operator delete", "operator delete []"}; 531fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany CHECK_NE(alloc_type, dealloc_type); 532fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany ScopedInErrorReport in_report; 533fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Decorator d; 534fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Printf("%s", d.Warning()); 535fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", 536fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany alloc_names[alloc_type], dealloc_names[dealloc_type], addr); 537fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Printf("%s", d.EndWarning()); 538fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany PrintStack(stack); 539fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany DescribeHeapAddress(addr, 1); 5402673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("alloc-dealloc-mismatch", stack); 541fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Report("HINT: if you don't care about these warnings you may set " 542fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); 543fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany} 544fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany 545c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { 5469873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 54758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 54858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 54969d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting to call " 550f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "malloc_usable_size() for pointer which is " 551f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 55258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 553cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 554f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 5552673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("bad-malloc_usable_size", stack); 556f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 557f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 558c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { 5599873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 56058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 56158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 56269d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting to call " 563f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "__asan_get_allocated_size() for pointer which is " 564f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 56558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 566cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 567f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 5682673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary("bad-__asan_get_allocated_size", stack); 569f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 570f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 571487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonovvoid ReportStringFunctionMemoryRangesOverlap( 572487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov const char *function, const char *offset1, uptr length1, 573c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany const char *offset2, uptr length2, StackTrace *stack) { 5749873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 57558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 5762673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany char bug_type[100]; 5772673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 57858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 5792673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany Report("ERROR: AddressSanitizer: %s: " 580487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 5812673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany bug_type, offset1, offset1 + length1, offset2, offset2 + length2); 58258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 583cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 5849873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset1, length1); 5859873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset2, length2); 5862673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary(bug_type, stack); 587487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov} 588f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 589663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov// ----------------------- Mac-specific reports ----------------- {{{1 590663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 591663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid WarnMacFreeUnallocated( 592c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 5939873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Just print a warning here. 594283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("free_common(%p) -- attempting to free unallocated memory.\n" 595663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "AddressSanitizer is ignoring this error on Mac OS now.\n", 596663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 597663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 598cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 5999873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 600663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 601663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 602663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacMzReallocUnknown( 603c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 6049873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 605283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n" 606663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 607663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 608663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 609cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 6109873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 611663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 612663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 613663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacCfReallocUnknown( 614c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 6159873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 616283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" 617663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 618663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 619663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 620cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(stack); 6219873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 622c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 623c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 624812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov} // namespace __asan 625812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 626812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov// --------------------------- Interface --------------------- {{{1 627812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonovusing namespace __asan; // NOLINT 628812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 629812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonovvoid __asan_report_error(uptr pc, uptr bp, uptr sp, 630812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov uptr addr, bool is_write, uptr access_size) { 6319873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 632c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 6339873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Determine the error type. 634c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov const char *bug_descr = "unknown-crash"; 635c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (AddrIsInMem(addr)) { 636c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov u8 *shadow_addr = (u8*)MemToShadow(addr); 637c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are accessing 16 bytes, look at the second shadow byte. 638c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 639c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 640c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are in the partial right redzone, look at the next shadow byte. 641c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr > 0 && *shadow_addr < 128) 642c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 643c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov switch (*shadow_addr) { 644c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapLeftRedzoneMagic: 645c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapRightRedzoneMagic: 646c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-buffer-overflow"; 647c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 648c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapFreeMagic: 649c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-use-after-free"; 650c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 651c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackLeftRedzoneMagic: 652c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-underflow"; 653c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 6543945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany case kAsanInitializationOrderMagic: 6553945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany bug_descr = "initialization-order-fiasco"; 6563945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany break; 657c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackMidRedzoneMagic: 658c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackRightRedzoneMagic: 659c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackPartialRedzoneMagic: 660c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-overflow"; 661c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 662c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackAfterReturnMagic: 663c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-use-after-return"; 664c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 665c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanUserPoisonedMemoryMagic: 666c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "use-after-poison"; 667c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 668d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov case kAsanStackUseAfterScopeMagic: 669d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov bug_descr = "stack-use-after-scope"; 670d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov break; 671c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanGlobalRedzoneMagic: 672c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "global-buffer-overflow"; 673c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 674c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 675c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 67658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 67758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 67869d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: %s on address " 679c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", 680c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr, (void*)addr, pc, bp, sp); 68158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 682c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 68389c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov u32 curr_tid = GetCurrentTidOrInvalid(); 684716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 68558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s%s of size %zu at %p thread T%d%s%s\n", 68658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.Access(), 68758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 68858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany access_size, (void*)addr, curr_tid, 68958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)), 69058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAccess()); 691c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 692a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_FATAL(pc, bp); 693cc347222d55967fdb775429a8a0a3a5d795b8b50Kostya Serebryany PrintStack(&stack); 694c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 695c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov DescribeAddress(addr, access_size); 6962673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany ReportSummary(bug_descr, &stack); 6979873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov PrintShadowMemoryForAddress(addr); 698c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 699c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 700c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { 701c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_report_callback = callback; 702c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (callback) { 703c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_size = 1 << 16; 704c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer = 705c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov (char*)MmapOrDie(error_message_buffer_size, __FUNCTION__); 706c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos = 0; 707c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 708c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 709f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov 71017a7c6763224300f6740b5e7fae274734afec675Kostya Serebryanyvoid __asan_describe_address(uptr addr) { 71117a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany DescribeAddress(addr, 1); 71217a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany} 71317a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany 7146a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov#if !SANITIZER_SUPPORTS_WEAK_HOOKS 715866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonov// Provide default implementation of __asan_on_error that does nothing 716866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonov// and may be overriden by user. 717866334332ff8c2a1b7f3715224614b6b75a7578cAlexey SamsonovSANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE NOINLINE 718866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonovvoid __asan_on_error() {} 7196a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov#endif 720