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" 2058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany#include "sanitizer_common/sanitizer_common.h" 21ed20ebe35c64b8c7043447f6a48b0e5adc89adedSergey Matveev#include "sanitizer_common/sanitizer_flags.h" 2258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany#include "sanitizer_common/sanitizer_report_decorator.h" 236d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany#include "sanitizer_common/sanitizer_stackdepot.h" 249c92748b8fa3b833924138a6ae1e653972c9de3bAlexey Samsonov#include "sanitizer_common/sanitizer_symbolizer.h" 257354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 267354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonovnamespace __asan { 277354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 28f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov// -------------------- User-specified callbacks ----------------- {{{1 29c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic void (*error_report_callback)(const char*); 30c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic char *error_message_buffer = 0; 31c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_pos = 0; 32c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovstatic uptr error_message_buffer_size = 0; 33c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 34c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid AppendToErrorMessageBuffer(const char *buffer) { 35c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (error_message_buffer) { 36c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr length = internal_strlen(buffer); 37c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov CHECK_GE(error_message_buffer_size, error_message_buffer_pos); 38c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov uptr remaining = error_message_buffer_size - error_message_buffer_pos; 39c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov internal_strncpy(error_message_buffer + error_message_buffer_pos, 40c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov buffer, remaining); 41c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer[error_message_buffer_size - 1] = '\0'; 42c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // FIXME: reallocate the buffer instead of truncating the message. 43c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos += remaining > length ? length : remaining; 44c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 45c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 46c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 4758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany// ---------------------- Decorator ------------------------------ {{{1 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesclass Decorator: public __sanitizer::SanitizerCommonDecorator { 4958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany public: 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Decorator() : SanitizerCommonDecorator() { } 5158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Access() { return Blue(); } 5258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndAccess() { return Default(); } 5358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Location() { return Green(); } 5458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndLocation() { return Default(); } 5558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *Allocation() { return Magenta(); } 5658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany const char *EndAllocation() { return Default(); } 579514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany 589514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *ShadowByte(u8 byte) { 599514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany switch (byte) { 609514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapLeftRedzoneMagic: 619514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapRightRedzoneMagic: 629514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 639514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanHeapFreeMagic: 649514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 659514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackLeftRedzoneMagic: 669514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackMidRedzoneMagic: 679514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackRightRedzoneMagic: 689514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackPartialRedzoneMagic: 699514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 709514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackAfterReturnMagic: 719514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 729514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanInitializationOrderMagic: 739514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Cyan(); 749514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanUserPoisonedMemoryMagic: 752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines case kAsanContiguousContainerOOBMagic: 769514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Blue(); 779514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanStackUseAfterScopeMagic: 789514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Magenta(); 799514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanGlobalRedzoneMagic: 809514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Red(); 819514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany case kAsanInternalHeapMagic: 829514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Yellow(); 839514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany default: 849514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany return Default(); 859514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany } 869514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany } 879514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *EndShadowByte() { return Default(); } 8858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany}; 8958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany 909873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// ---------------------- Helper functions ----------------------- {{{1 919873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void PrintShadowByte(InternalScopedString *str, const char *before, 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines u8 byte, const char *after = "\n") { 949514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Decorator d; 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append("%s%s%x%x%s%s", before, d.ShadowByte(byte), byte >> 4, byte & 15, 962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines d.EndShadowByte(), after); 979514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany} 989514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void PrintShadowBytes(InternalScopedString *str, const char *before, 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines u8 *bytes, u8 *guilty, uptr n) { 1019514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany Decorator d; 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (before) str->append("%s%p:", before, bytes); 1039514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany for (uptr i = 0; i < n; i++) { 1049514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany u8 *p = bytes + i; 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines const char *before = 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " "; 1079514a53d7b56be6302c666291b21c0387f7ceca8Kostya Serebryany const char *after = p == guilty ? "]" : ""; 1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, before, *p, after); 1099873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append("\n"); 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void PrintLegend(InternalScopedString *str) { 1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append( 1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "Shadow byte legend (one shadow byte represents %d " 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "application bytes):\n", 1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (int)SHADOW_GRANULARITY); 1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Addressable: ", 0); 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append(" Partially addressable: "); 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " "); 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append("\n"); 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Heap left redzone: ", 1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanHeapLeftRedzoneMagic); 1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Heap right redzone: ", 1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanHeapRightRedzoneMagic); 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic); 1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack left redzone: ", 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackLeftRedzoneMagic); 1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack mid redzone: ", 1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackMidRedzoneMagic); 1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack right redzone: ", 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackRightRedzoneMagic); 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack partial redzone: ", 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackPartialRedzoneMagic); 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack after return: ", 1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackAfterReturnMagic); 1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Stack use after scope: ", 1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanStackUseAfterScopeMagic); 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic); 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Global init order: ", 1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanInitializationOrderMagic); 1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Poisoned by user: ", 1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanUserPoisonedMemoryMagic); 1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " Container overflow: ", 1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines kAsanContiguousContainerOOBMagic); 1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic); 1479873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 1489873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 14995f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryanystatic void PrintShadowMemoryForAddress(uptr addr) { 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!AddrIsInMem(addr)) return; 15195f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany uptr shadow_addr = MemToShadow(addr); 15295f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany const uptr n_bytes_per_row = 16; 15395f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1); 1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InternalScopedString str(4096 * 8); 1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("Shadow bytes around the buggy address:\n"); 15695f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany for (int i = -5; i <= 5; i++) { 15795f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany const char *prefix = (i == 0) ? "=>" : " "; 1582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintShadowBytes(&str, prefix, (u8 *)(aligned_shadow + i * n_bytes_per_row), 1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (u8 *)shadow_addr, n_bytes_per_row); 16095f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany } 1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (flags()->print_legend) PrintLegend(&str); 1622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", str.data()); 16395f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany} 16495f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany 1659873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovstatic void PrintZoneForPointer(uptr ptr, uptr zone_ptr, 1669873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov const char *zone_name) { 1679873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_ptr) { 1689873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (zone_name) { 169283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n", 1709873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr, zone_name); 1719873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 172283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n", 1739873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ptr, zone_ptr); 1749873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 1759873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } else { 176283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("malloc_zone_from_ptr(%p) = 0\n", ptr); 1779873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 1789873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov} 1799873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 180997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanovstatic void DescribeThread(AsanThread *t) { 181997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov if (t) 182997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(t->context()); 183997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov} 184997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov 185e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// ---------------------- Address Descriptions ------------------- {{{1 186e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 187e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonovstatic bool IsASCII(unsigned char c) { 1889873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov return /*0x00 <= c &&*/ c <= 0x7F; 189e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 190e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 191c9424276474a27bd7b6ae59e771371f850a08ba1Alexey Samsonovstatic const char *MaybeDemangleGlobalName(const char *name) { 192c9424276474a27bd7b6ae59e771371f850a08ba1Alexey Samsonov // We can spoil names of globals with C linkage, so use an heuristic 193c9424276474a27bd7b6ae59e771371f850a08ba1Alexey Samsonov // approach to check if the name should be demangled. 1942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bool should_demangle = false; 1952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (name[0] == '_' && name[1] == 'Z') 1962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines should_demangle = true; 1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (SANITIZER_WINDOWS && name[0] == '\01' && name[1] == '?') 1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines should_demangle = true; 1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return should_demangle ? Symbolizer::Get()->Demangle(name) : name; 201c9424276474a27bd7b6ae59e771371f850a08ba1Alexey Samsonov} 202c9424276474a27bd7b6ae59e771371f850a08ba1Alexey Samsonov 203939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov// Check if the global is a zero-terminated ASCII string. If so, print it. 2042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void PrintGlobalNameIfASCII(InternalScopedString *str, 2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines const __asan_global &g) { 206939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov for (uptr p = g.beg; p < g.beg + g.size - 1; p++) { 207939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov unsigned char c = *(unsigned char*)p; 208939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov if (c == '\0' || !IsASCII(c)) return; 209939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov } 210939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov if (*(char*)(g.beg + g.size - 1) != '\0') return; 2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str->append(" '%s' is ascii string '%s'\n", MaybeDemangleGlobalName(g.name), 2122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (char *)g.beg); 213939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov} 214939316c822cc46e62684464eecd5cb2cefcf41c5Alexey Samsonov 2155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const char *GlobalFilename(const __asan_global &g) { 2165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const char *res = g.module_name; 2175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines // Prefer the filename from source location, if is available. 2185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (g.location) 2195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines res = g.location->filename; 2205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines CHECK(res); 2215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return res; 2225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 2235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 2245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic void PrintGlobalLocation(InternalScopedString *str, 2255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const __asan_global &g) { 2265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines str->append("%s", GlobalFilename(g)); 2275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (!g.location) 2285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return; 2295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (g.location->line_no) 2305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines str->append(":%d", g.location->line_no); 2315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (g.location->column_no) 2325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines str->append(":%d", g.location->column_no); 2335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 2345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 235589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanovbool DescribeAddressRelativeToGlobal(uptr addr, uptr size, 236589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov const __asan_global &g) { 237a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany static const uptr kMinimalDistanceFromAnotherGlobal = 64; 238a3b0e5e4f9f48b2ed0baee10c0236eda7c21c660Kostya Serebryany if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false; 239e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr >= g.beg + g.size_with_redzone) return false; 2402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InternalScopedString str(4096); 24158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%s", d.Location()); 243e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov if (addr < g.beg) { 2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes to the left", (void *)addr, 2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines g.beg - addr); 246589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } else if (addr + size > g.beg + g.size) { 247589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (addr < g.beg + g.size) 248589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov addr = g.beg + g.size; 2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes to the right", (void *)addr, 2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines addr - (g.beg + g.size)); 251e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } else { 252589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov // Can it happen? 2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes inside", (void *)addr, addr - g.beg); 254e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov } 2555d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines str.append(" of global variable '%s' defined in '", 2565d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines MaybeDemangleGlobalName(g.name)); 2575d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines PrintGlobalLocation(&str, g); 2585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines str.append("' (0x%zx) of size %zu\n", g.beg, g.size); 2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%s", d.EndLocation()); 2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PrintGlobalNameIfASCII(&str, g); 2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", str.data()); 262e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov return true; 263e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov} 264e4bfca2b154a6ab4eda921aff454035f33f3551aAlexey Samsonov 265e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfShadow(uptr addr) { 266e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInMem(addr)) 267e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 268e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov static const char kAddrInShadowReport[] = 269e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "Address %p is located in the %s.\n"; 270e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInShadowGap(addr)) { 271283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "shadow gap area"); 272e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 273e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 274e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInHighShadow(addr)) { 275283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "high shadow area"); 276e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 277e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 278e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (AddrIsInLowShadow(addr)) { 279283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(kAddrInShadowReport, addr, "low shadow area"); 280e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 281e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 282e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(0 && "Address is not in memory and not in shadow?"); 283e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return false; 284e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 285e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 28650f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany// Return " (thread_name) " or an empty string if the name is empty. 28750f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryanyconst char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[], 28850f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany uptr buff_len) { 28950f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany const char *name = t->name; 29050f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany if (name[0] == '\0') return ""; 29150f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany buff[0] = 0; 29250f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany internal_strncat(buff, " (", 3); 29350f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany internal_strncat(buff, name, buff_len - 4); 29450f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany internal_strncat(buff, ")", 2); 29550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany return buff; 29650f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany} 29750f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany 29850f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryanyconst char *ThreadNameWithParenthesis(u32 tid, char buff[], 29950f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany uptr buff_len) { 30050f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany if (tid == kInvalidTid) return ""; 30150f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany asanThreadRegistry().CheckLocked(); 30250f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany AsanThreadContext *t = GetThreadContextByTidLocked(tid); 30350f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany return ThreadNameWithParenthesis(t, buff, buff_len); 30450f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany} 30550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany 306edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryanyvoid PrintAccessAndVarIntersection(const char *var_name, 307edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr var_beg, uptr var_size, 308edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr addr, uptr access_size, 309edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr prev_var_end, uptr next_var_beg) { 310edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr var_end = var_beg + var_size; 311edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr addr_end = addr + access_size; 312edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany const char *pos_descr = 0; 313edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany // If the variable [var_beg, var_end) is the nearest variable to the 314edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany // current memory access, indicate it in the log. 315edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany if (addr >= var_beg) { 316edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany if (addr_end <= var_end) 317edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany pos_descr = "is inside"; // May happen if this is a use-after-return. 318edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany else if (addr < var_end) 319edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany pos_descr = "partially overflows"; 320edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany else if (addr_end <= next_var_beg && 321edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany next_var_beg - addr_end >= addr - var_end) 322edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany pos_descr = "overflows"; 323edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany } else { 324edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany if (addr_end > var_beg) 325edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany pos_descr = "partially underflows"; 326edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany else if (addr >= prev_var_end && 327edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany addr - prev_var_end >= var_beg - addr_end) 328edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany pos_descr = "underflows"; 329edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany } 3302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InternalScopedString str(1024); 3312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append(" [%zd, %zd) '%s'", var_beg, var_beg + var_size, var_name); 332edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany if (pos_descr) { 333edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany Decorator d; 334edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany // FIXME: we may want to also print the size of the access here, 335edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany // but in case of accesses generated by memset it may be confusing. 3362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%s <== Memory access at offset %zd %s this variable%s\n", 3372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines d.Location(), addr, pos_descr, d.EndLocation()); 338edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany } else { 3392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("\n"); 340edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany } 3412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", str.data()); 342edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany} 343edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany 344edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryanystruct StackVarDescr { 345edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr beg; 346edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr size; 347edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany const char *name_pos; 34889fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany uptr name_len; 349edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany}; 350edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany 351e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovbool DescribeAddressIfStack(uptr addr, uptr access_size) { 352def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThread *t = FindThreadByStackAddress(addr); 353e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (!t) return false; 35489fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany const uptr kBufSize = 4095; 355e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char buf[kBufSize]; 356e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov uptr offset = 0; 35750f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany uptr frame_pc = 0; 35850f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany char tname[128]; 35950f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany const char *frame_descr = t->GetFrameNameByAddr(addr, &offset, &frame_pc); 360d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany 361d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany#ifdef __powerpc64__ 362d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany // On PowerPC64, the address of a function actually points to a 363d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany // three-doubleword data structure with the first field containing 364d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany // the address of the function's code. 365d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany frame_pc = *reinterpret_cast<uptr *>(frame_pc); 366d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany#endif 367d570bb4c7d82767d26ada0f923f84b10d8ec0fc6Kostya Serebryany 368e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // This string is created by the compiler and has the following form: 36950f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // "n alloc_1 alloc_2 ... alloc_n" 370e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // where alloc_i looks like "offset size len ObjectName ". 371e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(frame_descr); 37258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 37358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Location()); 37450f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany Printf("Address %p is located in stack of thread T%d%s " 37550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany "at offset %zu in frame\n", 37650f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany addr, t->tid(), 37750f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany ThreadNameWithParenthesis(t->tid(), tname, sizeof(tname)), 37850f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany offset); 37950f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // Now we print the frame where the alloca has happened. 38050f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // We print this frame as a stack trace with one element. 38150f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // The symbolizer may print more than one frame if inlining was involved. 38250f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // The frame numbers may be different than those in the stack trace printed 38350f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // previously. That's unfortunate, but I have no better solution, 38450f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // especially given that the alloca may be from entirely different place 38550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany // (e.g. use-after-scope, or different thread's stack). 38650f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany StackTrace alloca_stack; 38750f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany alloca_stack.trace[0] = frame_pc + 16; 38850f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany alloca_stack.size = 1; 38958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndLocation()); 3902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines alloca_stack.Print(); 391e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report the number of stack objects. 392e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov char *p; 39322917e961033a840c500761d3c7110b5a654fca4Timur Iskhodzhanov uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); 394a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany CHECK_GT(n_objects, 0); 395283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf(" This frame has %zu object(s):\n", n_objects); 396edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany 397e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Report all objects in this frame. 398edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany InternalScopedBuffer<StackVarDescr> vars(n_objects); 39989fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany for (uptr i = 0; i < n_objects; i++) { 40089fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany uptr beg, size; 40189fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany uptr len; 40289fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany beg = (uptr)internal_simple_strtoll(p, &p, 10); 40389fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany size = (uptr)internal_simple_strtoll(p, &p, 10); 40489fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany len = (uptr)internal_simple_strtoll(p, &p, 10); 40589fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany if (beg == 0 || size == 0 || *p != ' ') { 406283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("AddressSanitizer can't parse the stack frame " 407e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov "descriptor: |%s|\n", frame_descr); 408e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov break; 409e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 410e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p++; 411edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany vars[i].beg = beg; 412edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany vars[i].size = size; 413edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany vars[i].name_pos = p; 414edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany vars[i].name_len = len; 415e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov p += len; 416edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany } 41789fe5642529335dc5d13ce7f4e61bdea36fca508Kostya Serebryany for (uptr i = 0; i < n_objects; i++) { 418edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany buf[0] = 0; 419edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany internal_strncat(buf, vars[i].name_pos, 420edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany static_cast<uptr>(Min(kBufSize, vars[i].name_len))); 421edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany uptr prev_var_end = i ? vars[i - 1].beg + vars[i - 1].size : 0; 42222917e961033a840c500761d3c7110b5a654fca4Timur Iskhodzhanov uptr next_var_beg = i + 1 < n_objects ? vars[i + 1].beg : ~(0UL); 423edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany PrintAccessAndVarIntersection(buf, vars[i].beg, vars[i].size, 424edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany offset, access_size, 425edb39c7942fc9fe5043b7cce348bac0aec4c83ebKostya Serebryany prev_var_end, next_var_beg); 426e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov } 427283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("HINT: this may be a false positive if your program uses " 4280870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov "some custom stack unwind mechanism or swapcontext\n" 429e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov " (longjmp and C++ exceptions *are* supported)\n"); 430997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(t); 431e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return true; 432e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 433e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 4345c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonovstatic void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr, 4355c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov uptr access_size) { 436589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov sptr offset; 43758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 4382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InternalScopedString str(4096); 4392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%s", d.Location()); 440589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (chunk.AddrIsAtLeft(addr, access_size, &offset)) { 4412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes to the left of", (void *)addr, offset); 4425c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else if (chunk.AddrIsAtRight(addr, access_size, &offset)) { 443589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (offset < 0) { 444589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov addr -= offset; 445589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov offset = 0; 446589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } 4472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes to the right of", (void *)addr, offset); 448589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } else if (chunk.AddrIsInside(addr, access_size, &offset)) { 4492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located %zd bytes inside of", (void*)addr, offset); 4505c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else { 4512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%p is located somewhere around (this is AddressSanitizer bug!)", 4522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)addr); 4535c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } 4542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append(" %zu-byte region [%p,%p)\n", chunk.UsedSize(), 4552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)(chunk.Beg()), (void *)(chunk.End())); 4562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("%s", d.EndLocation()); 4572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", str.data()); 4585c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov} 4595c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov 4605c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonovvoid DescribeHeapAddress(uptr addr, uptr access_size) { 4615c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov AsanChunkView chunk = FindHeapChunkByAddress(addr); 462d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov if (!chunk.IsValid()) { 463d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov Printf("AddressSanitizer can not describe address in more detail " 464d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov "(wild memory access suspected).\n"); 465d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov return; 466d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov } 4675c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov DescribeAccessToHeapChunk(chunk, addr, access_size); 4685c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov CHECK(chunk.AllocTid() != kInvalidTid); 469def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().CheckLocked(); 470def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *alloc_thread = 471def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov GetThreadContextByTidLocked(chunk.AllocTid()); 4725c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov StackTrace alloc_stack; 4735c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov chunk.GetAllocStack(&alloc_stack); 474716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 47558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 476997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov AsanThreadContext *free_thread = 0; 4775c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov if (chunk.FreeTid() != kInvalidTid) { 478997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov free_thread = GetThreadContextByTidLocked(chunk.FreeTid()); 47958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(), 480def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov free_thread->tid, 48158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)), 48258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 4835c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov StackTrace free_stack; 4845c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov chunk.GetFreeStack(&free_stack); 4852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines free_stack.Print(); 48658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%spreviously allocated by thread T%d%s here:%s\n", 487def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov d.Allocation(), alloc_thread->tid, 48858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 48958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 4905c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } else { 49158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(), 492def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov alloc_thread->tid, 49358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), 49458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAllocation()); 4955c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov } 4962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines alloc_stack.Print(); 497997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(GetCurrentThread()); 498997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov if (free_thread) 499997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(free_thread); 500997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(alloc_thread); 5015c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov} 5025c153faa535f671dd0e8d40ab43397f2d3c6f6f5Alexey Samsonov 503e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonovvoid DescribeAddress(uptr addr, uptr access_size) { 504e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Check if this is shadow or shadow gap. 505e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfShadow(addr)) 506e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 507e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov CHECK(AddrIsInMem(addr)); 508589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov if (DescribeAddressIfGlobal(addr, access_size)) 509e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 510e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov if (DescribeAddressIfStack(addr, access_size)) 511e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov return; 512e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov // Assume it is a heap address. 513e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov DescribeHeapAddress(addr, access_size); 514e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov} 515e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 51671b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov// ------------------- Thread description -------------------- {{{1 51771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 518def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovvoid DescribeThread(AsanThreadContext *context) { 519def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov CHECK(context); 520def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().CheckLocked(); 52171b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // No need to announce the main thread. 522def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (context->tid == 0 || context->announced) { 52371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov return; 52471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 525def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov context->announced = true; 526716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 5272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InternalScopedString str(1024); 5282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append("Thread T%d%s", context->tid, 5292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ThreadNameWithParenthesis(context->tid, tname, sizeof(tname))); 5302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines str.append( 5312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " created by T%d%s here:\n", context->parent_tid, 5322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ThreadNameWithParenthesis(context->parent_tid, tname, sizeof(tname))); 5332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", str.data()); 5346d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany uptr stack_size; 5356d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany const uptr *stack_trace = StackDepotGet(context->stack_id, &stack_size); 5362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines StackTrace::PrintStack(stack_trace, stack_size); 53771b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov // Recursively described parent thread if needed. 53871b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov if (flags()->print_full_thread_history) { 539def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *parent_context = 540def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov GetThreadContextByTidLocked(context->parent_tid); 541def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov DescribeThread(parent_context); 54271b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov } 54371b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov} 54471b42c9740e6f73da607aaa539affb5c4807231cAlexey Samsonov 545e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov// -------------------- Different kinds of reports ----------------- {{{1 546e218beb2d14b663bd277158f386a86d0e62fef74Alexey Samsonov 5479873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// Use ScopedInErrorReport to run common actions just before and 5489873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov// immediately after printing error report. 5499873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonovclass ScopedInErrorReport { 5509873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov public: 5519873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport() { 5529873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov static atomic_uint32_t num_calls; 55362e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov static u32 reporting_thread_tid; 5549873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 5559873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Do not print more than one report, otherwise they will mix up. 5569873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Error reporting functions shouldn't return at this situation, as 5579873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // they are defined as no-return. 558283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("AddressSanitizer: while reporting a bug found another one." 5599873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov "Ignoring.\n"); 56089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov u32 current_tid = GetCurrentTidOrInvalid(); 56162e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov if (current_tid != reporting_thread_tid) { 56262e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // ASan found two bugs in different threads simultaneously. Sleep 56362e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // long enough to make sure that the thread which started to print 56462e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov // an error report will finish doing it. 56562e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov SleepForSeconds(Max(100, flags()->sleep_before_dying + 1)); 56662e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov } 567f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov // If we're still not dead for some reason, use raw _exit() instead of 568031633bef8dff03f4e8943a12e34856bd66bbc78Alexey Samsonov // Die() to bypass any additional checks. 569f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov internal__exit(flags()->exitcode); 5709873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 5716a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov ASAN_ON_ERROR(); 5727ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov // Make sure the registry and sanitizer report mutexes are locked while 5737ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov // we're printing an error report. 5747ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov // We can lock them only here to avoid self-deadlock in case of 575def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // recursive reports. 576def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().Lock(); 5777ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov CommonSanitizerReportMutex.Lock(); 57889c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov reporting_thread_tid = GetCurrentTidOrInvalid(); 579283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("====================================================" 58062e27098b97e5ef74931c536350123a3df9dec6dAlexey Samsonov "=============\n"); 5819873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 5829873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Destructor is NORETURN, as functions that report errors are. 5839873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov NORETURN ~ScopedInErrorReport() { 5849873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Make sure the current thread is announced. 585997454a41a1658837d72d69ec7def59616311243Timur Iskhodzhanov DescribeThread(GetCurrentThread()); 5862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // We may want to grab this lock again when printing stats. 5872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asanThreadRegistry().Unlock(); 5889873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Print memory stats. 58995f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany if (flags()->print_stats) 59095f630ae40cef78fb03b18110eff43bcf8d1c040Kostya Serebryany __asan_print_accumulated_stats(); 5919873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov if (error_report_callback) { 5929873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov error_report_callback(error_message_buffer); 5939873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 594283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Report("ABORTING\n"); 5959873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov Die(); 5969873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov } 5979873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov}; 5989873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov 5992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid ReportStackOverflow(uptr pc, uptr sp, uptr bp, void *context, uptr addr) { 6009873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 60158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 60258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 6032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report( 6042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "ERROR: AddressSanitizer: stack-overflow on address %p" 6052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " (pc %p sp %p bp %p T%d)\n", 6062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)addr, (void *)pc, (void *)sp, (void *)bp, 6072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GetCurrentTidOrInvalid()); 60858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 6092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GET_STACK_TRACE_SIGNAL(pc, bp, context); 6102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 6112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportErrorSummary("stack-overflow", &stack); 6122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 6132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 6142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid ReportSIGSEGV(uptr pc, uptr sp, uptr bp, void *context, uptr addr) { 6152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedInErrorReport in_report; 6162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Decorator d; 6172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.Warning()); 6182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report( 6192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "ERROR: AddressSanitizer: SEGV on unknown address %p" 6202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " (pc %p sp %p bp %p T%d)\n", 6212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)addr, (void *)pc, (void *)sp, (void *)bp, 6222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GetCurrentTidOrInvalid()); 6232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.EndWarning()); 6242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GET_STACK_TRACE_SIGNAL(pc, bp, context); 6252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 626d9def29fe0dc8fc70ef270dcc1a266ad9257ec1fAlexey Samsonov Printf("AddressSanitizer can not provide additional info.\n"); 6272fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary("SEGV", &stack); 6287354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov} 6297354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov 6301b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonovvoid ReportDoubleFree(uptr addr, StackTrace *free_stack) { 6319873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 63258f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 63358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 634a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany char tname[128]; 635a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany u32 curr_tid = GetCurrentTidOrInvalid(); 636a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany Report("ERROR: AddressSanitizer: attempting double-free on %p in " 637a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany "thread T%d%s:\n", 638a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany addr, curr_tid, 639a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname))); 64058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 6411b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov CHECK_GT(free_stack->size, 0); 6421b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); 6432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 644f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 6451b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov ReportErrorSummary("double-free", &stack); 646f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 647f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 6481b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonovvoid ReportFreeNotMalloced(uptr addr, StackTrace *free_stack) { 6499873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 65058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 65158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 652a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany char tname[128]; 653a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany u32 curr_tid = GetCurrentTidOrInvalid(); 65469d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting free on address " 655a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany "which was not malloc()-ed: %p in thread T%d%s\n", addr, 656a89a35acf3004de3e39f1074b8620fb3c423d41fKostya Serebryany curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname))); 65758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 6581b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov CHECK_GT(free_stack->size, 0); 6591b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); 6602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 6619873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 6621b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov ReportErrorSummary("bad-free", &stack); 663f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 664f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 6651b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonovvoid ReportAllocTypeMismatch(uptr addr, StackTrace *free_stack, 666fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany AllocType alloc_type, 667fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany AllocType dealloc_type) { 668fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany static const char *alloc_names[] = 669fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany {"INVALID", "malloc", "operator new", "operator new []"}; 670fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany static const char *dealloc_names[] = 671fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany {"INVALID", "free", "operator delete", "operator delete []"}; 672fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany CHECK_NE(alloc_type, dealloc_type); 673fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany ScopedInErrorReport in_report; 674fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Decorator d; 675fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Printf("%s", d.Warning()); 676fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", 677fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany alloc_names[alloc_type], dealloc_names[dealloc_type], addr); 678fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Printf("%s", d.EndWarning()); 6791b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov CHECK_GT(free_stack->size, 0); 6801b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); 6812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 682fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany DescribeHeapAddress(addr, 1); 6831b17f5b79d58c5aff291dde05727ad0b215b81c6Alexey Samsonov ReportErrorSummary("alloc-dealloc-mismatch", &stack); 684fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany Report("HINT: if you don't care about these warnings you may set " 685fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); 686fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany} 687fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany 688c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { 6899873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 69058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 69158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 69269d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting to call " 693f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "malloc_usable_size() for pointer which is " 694f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 69558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 6962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 697f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 6982fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary("bad-malloc_usable_size", stack); 699f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 700f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 7015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid ReportSanitizerGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { 7029873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 70358f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 70458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 70569d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: attempting to call " 7065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines "__sanitizer_get_allocated_size() for pointer which is " 707f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov "not owned: %p\n", addr); 70858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 7092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 710f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov DescribeHeapAddress(addr, 1); 7115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack); 712f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov} 713f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 714487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonovvoid ReportStringFunctionMemoryRangesOverlap( 715487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov const char *function, const char *offset1, uptr length1, 716c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany const char *offset2, uptr length2, StackTrace *stack) { 7179873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 71858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 7192673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany char bug_type[100]; 7202673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 72158f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 7222673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany Report("ERROR: AddressSanitizer: %s: " 723487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 7242673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany bug_type, offset1, offset1 + length1, offset2, offset2 + length2); 72558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 7262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 7279873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset1, length1); 7289873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeAddress((uptr)offset2, length2); 7292fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary(bug_type, stack); 730487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov} 731f7c1d18183d2dfbd02864cf47b3239d6a5d717c0Alexey Samsonov 7322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid ReportStringFunctionSizeOverflow(uptr offset, uptr size, 7332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines StackTrace *stack) { 7342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedInErrorReport in_report; 7352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Decorator d; 7362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines const char *bug_type = "negative-size-param"; 7372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.Warning()); 7382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size); 7392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.EndWarning()); 7402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 7412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DescribeAddress(offset, size); 7422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportErrorSummary(bug_type, stack); 7432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 7442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 7452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end, 7462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr old_mid, uptr new_mid, 7472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines StackTrace *stack) { 7482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedInErrorReport in_report; 7492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ERROR: AddressSanitizer: bad parameters to " 7502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "__sanitizer_annotate_contiguous_container:\n" 7512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " beg : %p\n" 7522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " end : %p\n" 7532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " old_mid : %p\n" 7542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines " new_mid : %p\n", 7552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines beg, end, old_mid, new_mid); 7562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 7572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack); 7582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 7592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 7605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid ReportODRViolation(const __asan_global *g1, u32 stack_id1, 7615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const __asan_global *g2, u32 stack_id2) { 7622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedInErrorReport in_report; 7632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Decorator d; 7642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.Warning()); 7652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ERROR: AddressSanitizer: odr-violation (%p):\n", g1->beg); 7662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.EndWarning()); 7675d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines InternalScopedString g1_loc(256), g2_loc(256); 7685d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines PrintGlobalLocation(&g1_loc, *g1); 7695d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines PrintGlobalLocation(&g2_loc, *g2); 7705d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines Printf(" [1] size=%zd %s %s\n", g1->size, g1->name, g1_loc.data()); 7715d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines Printf(" [2] size=%zd %s %s\n", g2->size, g2->name, g2_loc.data()); 7725d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (stack_id1 && stack_id2) { 7735d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines Printf("These globals were registered at these points:\n"); 7745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines Printf(" [1]:\n"); 7755d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines uptr stack_size; 7765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const uptr *stack_trace = StackDepotGet(stack_id1, &stack_size); 7775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines StackTrace::PrintStack(stack_trace, stack_size); 7785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines Printf(" [2]:\n"); 7795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines stack_trace = StackDepotGet(stack_id2, &stack_size); 7805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines StackTrace::PrintStack(stack_trace, stack_size); 7815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines } 7822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("HINT: if you don't care about these warnings you may set " 7832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "ASAN_OPTIONS=detect_odr_violation=0\n"); 7845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines ReportErrorSummary("odr-violation", g1_loc.data(), 0, g1->name); 7852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 7862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 7872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// ----------------------- CheckForInvalidPointerPair ----------- {{{1 7882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic NOINLINE void 7892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) { 7902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ScopedInErrorReport in_report; 7912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Decorator d; 7922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.Warning()); 7932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n", a1, a2); 7942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Printf("%s", d.EndWarning()); 7952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GET_STACK_TRACE_FATAL(pc, bp); 7962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 7972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DescribeAddress(a1, 1); 7982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DescribeAddress(a2, 1); 7992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportErrorSummary("invalid-pointer-pair", &stack); 8002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 8012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 8022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic INLINE void CheckForInvalidPointerPair(void *p1, void *p2) { 8032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!flags()->detect_invalid_pointer_pairs) return; 8042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr a1 = reinterpret_cast<uptr>(p1); 8052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr a2 = reinterpret_cast<uptr>(p2); 8062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines AsanChunkView chunk1 = FindHeapChunkByAddress(a1); 8072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines AsanChunkView chunk2 = FindHeapChunkByAddress(a2); 8082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bool valid1 = chunk1.IsValid(); 8092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bool valid2 = chunk2.IsValid(); 8102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if ((valid1 != valid2) || (valid1 && valid2 && !chunk1.Eq(chunk2))) { 8112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GET_CALLER_PC_BP_SP; \ 8122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return ReportInvalidPointerPair(pc, bp, sp, a1, a2); 8132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 8142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 815663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov// ----------------------- Mac-specific reports ----------------- {{{1 816663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 817663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid WarnMacFreeUnallocated( 818c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 8199873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Just print a warning here. 820283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("free_common(%p) -- attempting to free unallocated memory.\n" 821663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "AddressSanitizer is ignoring this error on Mac OS now.\n", 822663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 823663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 8242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 8259873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 826663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 827663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 828663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacMzReallocUnknown( 829c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 8309873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 831283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n" 832663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 833663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 834663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 8352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 8369873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 837663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov} 838663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov 839663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonovvoid ReportMacCfReallocUnknown( 840c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack) { 8419873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 842283c296b64bc55deec9698260b3427a9b050a925Kostya Serebryany Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" 843663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov "This is an unrecoverable problem, exiting now.\n", 844663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov addr); 845663c50134e01feefb6c5418c6ec7753be951c14fAlexey Samsonov PrintZoneForPointer(addr, zone_ptr, zone_name); 8462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack->Print(); 8479873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov DescribeHeapAddress(addr, 1); 848c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 849c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 850812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov} // namespace __asan 851812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 852812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov// --------------------------- Interface --------------------- {{{1 853812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonovusing namespace __asan; // NOLINT 854812ff90eaad0e4555554ffb81db0e611ec434e10Alexey Samsonov 8552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write, 8562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr access_size) { 8579873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov ScopedInErrorReport in_report; 858c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 8599873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov // Determine the error type. 860c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov const char *bug_descr = "unknown-crash"; 861c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (AddrIsInMem(addr)) { 862c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov u8 *shadow_addr = (u8*)MemToShadow(addr); 863c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are accessing 16 bytes, look at the second shadow byte. 864c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 865c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 866c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov // If we are in the partial right redzone, look at the next shadow byte. 867c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (*shadow_addr > 0 && *shadow_addr < 128) 868c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov shadow_addr++; 869c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov switch (*shadow_addr) { 870c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapLeftRedzoneMagic: 871c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapRightRedzoneMagic: 872c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-buffer-overflow"; 873c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 874c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanHeapFreeMagic: 875c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "heap-use-after-free"; 876c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 877c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackLeftRedzoneMagic: 878c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-underflow"; 879c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 8803945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany case kAsanInitializationOrderMagic: 8813945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany bug_descr = "initialization-order-fiasco"; 8823945c58f9db42671b1a3b865fde5008f09a3a40eKostya Serebryany break; 883c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackMidRedzoneMagic: 884c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackRightRedzoneMagic: 885c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackPartialRedzoneMagic: 886c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-buffer-overflow"; 887c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 888c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanStackAfterReturnMagic: 889c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "stack-use-after-return"; 890c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 891c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanUserPoisonedMemoryMagic: 892c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "use-after-poison"; 893c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 8942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines case kAsanContiguousContainerOOBMagic: 8952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bug_descr = "container-overflow"; 8962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines break; 897d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov case kAsanStackUseAfterScopeMagic: 898d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov bug_descr = "stack-use-after-scope"; 899d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854Alexey Samsonov break; 900c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov case kAsanGlobalRedzoneMagic: 901c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr = "global-buffer-overflow"; 902c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov break; 903c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 904c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 90558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Decorator d; 90658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.Warning()); 90769d8ede30a0ef32c74af7e4e795eb4b4e7fb1d36Kostya Serebryany Report("ERROR: AddressSanitizer: %s on address " 908c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov "%p at pc 0x%zx bp 0x%zx sp 0x%zx\n", 909c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov bug_descr, (void*)addr, pc, bp, sp); 91058f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s", d.EndWarning()); 911c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 91289c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov u32 curr_tid = GetCurrentTidOrInvalid(); 913716e2f25123bf9b20fbc6b582803a3929b78b96dKostya Serebryany char tname[128]; 91458f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany Printf("%s%s of size %zu at %p thread T%d%s%s\n", 91558f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.Access(), 91658f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 91758f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany access_size, (void*)addr, curr_tid, 91858f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)), 91958f54555c2528f863e211a0679c2c423cfa55fb2Kostya Serebryany d.EndAccess()); 920c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 921a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_FATAL(pc, bp); 9222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack.Print(); 923c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 924c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov DescribeAddress(addr, access_size); 9252fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary(bug_descr, &stack); 9269873792adb79e9daa1594564cbe5b2d680c5ed13Alexey Samsonov PrintShadowMemoryForAddress(addr); 927c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 928c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov 929c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonovvoid NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { 930c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_report_callback = callback; 931c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov if (callback) { 932c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_size = 1 << 16; 933c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer = 9342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (char*)MmapOrDie(error_message_buffer_size, __func__); 935c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov error_message_buffer_pos = 0; 936c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov } 937c98570beff64ec0a513dcc11a4662ffba70e43ddAlexey Samsonov} 938f657a1977b6053c76ca8393f574da7593ea3ea12Alexey Samsonov 93917a7c6763224300f6740b5e7fae274734afec675Kostya Serebryanyvoid __asan_describe_address(uptr addr) { 94017a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany DescribeAddress(addr, 1); 94117a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany} 94217a7c6763224300f6740b5e7fae274734afec675Kostya Serebryany 9432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" { 9442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesSANITIZER_INTERFACE_ATTRIBUTE 9452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __sanitizer_ptr_sub(void *a, void *b) { 9462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines CheckForInvalidPointerPair(a, b); 9472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 9482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesSANITIZER_INTERFACE_ATTRIBUTE 9492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __sanitizer_ptr_cmp(void *a, void *b) { 9502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines CheckForInvalidPointerPair(a, b); 9512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 9522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // extern "C" 9532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 9546a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov#if !SANITIZER_SUPPORTS_WEAK_HOOKS 955866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonov// Provide default implementation of __asan_on_error that does nothing 956866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonov// and may be overriden by user. 9573c80c6c574850106481f82b9e23d1c728458d4a9Timur IskhodzhanovSANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE 958866334332ff8c2a1b7f3715224614b6b75a7578cAlexey Samsonovvoid __asan_on_error() {} 9596a08d29b2020004b801ca69d8aea5872a7e67d72Alexey Samsonov#endif 960