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