brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.4 KiB · 99d6bda Raw
676 lines · cpp
1//===-- asan_errors.cpp -----------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of AddressSanitizer, an address sanity checker.10//11// ASan implementation for error structures.12//===----------------------------------------------------------------------===//13 14#include "asan_errors.h"15 16#include "asan_descriptions.h"17#include "asan_mapping.h"18#include "asan_poisoning.h"19#include "asan_report.h"20#include "asan_stack.h"21#include "sanitizer_common/sanitizer_stackdepot.h"22 23namespace __asan {24 25static void OnStackUnwind(const SignalContext &sig,26                          const void *callback_context,27                          BufferedStackTrace *stack) {28  bool fast = common_flags()->fast_unwind_on_fatal;29#if SANITIZER_FREEBSD || SANITIZER_NETBSD30  // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()31  // yields the call stack of the signal's handler and not of the code32  // that raised the signal (as it does on Linux).33  fast = true;34#endif35  // Tests and maybe some users expect that scariness is going to be printed36  // just before the stack. As only asan has scariness score we have no37  // corresponding code in the sanitizer_common and we use this callback to38  // print it.39  static_cast<const ScarinessScoreBase *>(callback_context)->Print();40  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,41                fast);42}43 44void ErrorDeadlySignal::Print() {45  ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);46}47 48void ErrorDoubleFree::Print() {49  Decorator d;50  Printf("%s", d.Error());51  Report("ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n",52         scariness.GetDescription(), (void *)addr_description.addr,53         AsanThreadIdAndName(tid).c_str());54  Printf("%s", d.Default());55  scariness.Print();56  GET_STACK_TRACE_FATAL(second_free_stack->trace[0],57                        second_free_stack->top_frame_bp);58  stack.Print();59  addr_description.Print();60  ReportErrorSummary(scariness.GetDescription(), &stack);61}62 63void ErrorNewDeleteTypeMismatch::Print() {64  Decorator d;65  Printf("%s", d.Error());66  Report("ERROR: AddressSanitizer: %s on %p in thread %s:\n",67         scariness.GetDescription(), (void *)addr_description.addr,68         AsanThreadIdAndName(tid).c_str());69  Printf("%s  object passed to delete has wrong type:\n", d.Default());70  if (delete_size != 0) {71    Printf(72        "  size of the allocated type:   %zd bytes;\n"73        "  size of the deallocated type: %zd bytes.\n",74        addr_description.chunk_access.chunk_size, delete_size);75  }76  const uptr user_alignment =77      addr_description.chunk_access.user_requested_alignment;78  if (delete_alignment != user_alignment) {79    char user_alignment_str[32];80    char delete_alignment_str[32];81    internal_snprintf(user_alignment_str, sizeof(user_alignment_str),82                      "%zd bytes", user_alignment);83    internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str),84                      "%zd bytes", delete_alignment);85    static const char *kDefaultAlignment = "default-aligned";86    Printf(87        "  alignment of the allocated type:   %s;\n"88        "  alignment of the deallocated type: %s.\n",89        user_alignment > 0 ? user_alignment_str : kDefaultAlignment,90        delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment);91  }92  CHECK_GT(free_stack->size, 0);93  scariness.Print();94  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);95  stack.Print();96  addr_description.Print();97  ReportErrorSummary(scariness.GetDescription(), &stack);98  Report(99      "HINT: if you don't care about these errors you may set "100      "ASAN_OPTIONS=new_delete_type_mismatch=0\n");101}102 103void ErrorFreeNotMalloced::Print() {104  Decorator d;105  Printf("%s", d.Error());106  Report(107      "ERROR: AddressSanitizer: attempting free on address "108      "which was not malloc()-ed: %p in thread %s\n",109      (void *)addr_description.Address(), AsanThreadIdAndName(tid).c_str());110  Printf("%s", d.Default());111  CHECK_GT(free_stack->size, 0);112  scariness.Print();113  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);114  stack.Print();115  addr_description.Print();116  ReportErrorSummary(scariness.GetDescription(), &stack);117}118 119void ErrorAllocTypeMismatch::Print() {120  static const char *alloc_names[] = {"INVALID", "malloc", "operator new",121                                      "operator new []"};122  static const char *dealloc_names[] = {"INVALID", "free", "operator delete",123                                        "operator delete []"};124  CHECK_NE(alloc_type, dealloc_type);125  Decorator d;126  Printf("%s", d.Error());127  Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",128         scariness.GetDescription(), alloc_names[alloc_type],129         dealloc_names[dealloc_type], (void *)addr_description.Address());130  Printf("%s", d.Default());131  CHECK_GT(dealloc_stack->size, 0);132  scariness.Print();133  GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);134  stack.Print();135  addr_description.Print();136  ReportErrorSummary(scariness.GetDescription(), &stack);137  Report(138      "HINT: if you don't care about these errors you may set "139      "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");140}141 142void ErrorMallocUsableSizeNotOwned::Print() {143  Decorator d;144  Printf("%s", d.Error());145  Report(146      "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "147      "pointer which is not owned: %p\n",148      (void *)addr_description.Address());149  Printf("%s", d.Default());150  stack->Print();151  addr_description.Print();152  ReportErrorSummary(scariness.GetDescription(), stack);153}154 155void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {156  Decorator d;157  Printf("%s", d.Error());158  Report(159      "ERROR: AddressSanitizer: attempting to call "160      "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",161      (void *)addr_description.Address());162  Printf("%s", d.Default());163  stack->Print();164  addr_description.Print();165  ReportErrorSummary(scariness.GetDescription(), stack);166}167 168void ErrorCallocOverflow::Print() {169  Decorator d;170  Printf("%s", d.Error());171  Report(172      "ERROR: AddressSanitizer: calloc parameters overflow: count * size "173      "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",174      count, size, AsanThreadIdAndName(tid).c_str());175  Printf("%s", d.Default());176  stack->Print();177  PrintHintAllocatorCannotReturnNull();178  ReportErrorSummary(scariness.GetDescription(), stack);179}180 181void ErrorReallocArrayOverflow::Print() {182  Decorator d;183  Printf("%s", d.Error());184  Report(185      "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size "186      "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",187      count, size, AsanThreadIdAndName(tid).c_str());188  Printf("%s", d.Default());189  stack->Print();190  PrintHintAllocatorCannotReturnNull();191  ReportErrorSummary(scariness.GetDescription(), stack);192}193 194void ErrorPvallocOverflow::Print() {195  Decorator d;196  Printf("%s", d.Error());197  Report(198      "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx "199      "rounded up to system page size 0x%zx cannot be represented in type "200      "size_t (thread %s)\n",201      size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str());202  Printf("%s", d.Default());203  stack->Print();204  PrintHintAllocatorCannotReturnNull();205  ReportErrorSummary(scariness.GetDescription(), stack);206}207 208void ErrorInvalidAllocationAlignment::Print() {209  Decorator d;210  Printf("%s", d.Error());211  Report(212      "ERROR: AddressSanitizer: invalid allocation alignment: %zd, "213      "alignment must be a power of two (thread %s)\n",214      alignment, AsanThreadIdAndName(tid).c_str());215  Printf("%s", d.Default());216  stack->Print();217  PrintHintAllocatorCannotReturnNull();218  ReportErrorSummary(scariness.GetDescription(), stack);219}220 221void ErrorInvalidAlignedAllocAlignment::Print() {222  Decorator d;223  Printf("%s", d.Error());224#if SANITIZER_POSIX225  Report("ERROR: AddressSanitizer: invalid alignment requested in "226         "aligned_alloc: %zd, alignment must be a power of two and the "227         "requested size 0x%zx must be a multiple of alignment "228         "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str());229#else230  Report("ERROR: AddressSanitizer: invalid alignment requested in "231         "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of "232         "alignment (thread %s)\n", alignment, size,233         AsanThreadIdAndName(tid).c_str());234#endif235  Printf("%s", d.Default());236  stack->Print();237  PrintHintAllocatorCannotReturnNull();238  ReportErrorSummary(scariness.GetDescription(), stack);239}240 241void ErrorInvalidPosixMemalignAlignment::Print() {242  Decorator d;243  Printf("%s", d.Error());244  Report(245      "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: "246      "%zd, alignment must be a power of two and a multiple of sizeof(void*) "247      "== %zd (thread %s)\n",248      alignment, sizeof(void *), AsanThreadIdAndName(tid).c_str());249  Printf("%s", d.Default());250  stack->Print();251  PrintHintAllocatorCannotReturnNull();252  ReportErrorSummary(scariness.GetDescription(), stack);253}254 255void ErrorAllocationSizeTooBig::Print() {256  Decorator d;257  Printf("%s", d.Error());258  Report(259      "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after "260      "adjustments for alignment, red zones etc.) exceeds maximum supported "261      "size of 0x%zx (thread %s)\n",262      user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str());263  Printf("%s", d.Default());264  stack->Print();265  PrintHintAllocatorCannotReturnNull();266  ReportErrorSummary(scariness.GetDescription(), stack);267}268 269void ErrorRssLimitExceeded::Print() {270  Decorator d;271  Printf("%s", d.Error());272  Report(273      "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to "274      "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb);275  Printf("%s", d.Default());276  stack->Print();277  PrintHintAllocatorCannotReturnNull();278  ReportErrorSummary(scariness.GetDescription(), stack);279}280 281void ErrorOutOfMemory::Print() {282  Decorator d;283  Printf("%s", d.Error());284  ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size);285  Printf("%s", d.Default());286  stack->Print();287  PrintHintAllocatorCannotReturnNull();288  ReportErrorSummary(scariness.GetDescription(), stack);289}290 291void ErrorStringFunctionMemoryRangesOverlap::Print() {292  Decorator d;293  char bug_type[100];294  internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);295  Printf("%s", d.Error());296  Report(297      "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "298      "overlap\n",299      bug_type, (void *)addr1_description.Address(),300      (void *)(addr1_description.Address() + length1),301      (void *)addr2_description.Address(),302      (void *)(addr2_description.Address() + length2));303  Printf("%s", d.Default());304  scariness.Print();305  stack->Print();306  addr1_description.Print();307  addr2_description.Print();308  ReportErrorSummary(bug_type, stack);309}310 311void ErrorStringFunctionSizeOverflow::Print() {312  Decorator d;313  Printf("%s", d.Error());314  Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",315         scariness.GetDescription(), size);316  Printf("%s", d.Default());317  scariness.Print();318  stack->Print();319  addr_description.Print();320  ReportErrorSummary(scariness.GetDescription(), stack);321}322 323void ErrorBadParamsToAnnotateContiguousContainer::Print() {324  Report(325      "ERROR: AddressSanitizer: bad parameters to "326      "__sanitizer_annotate_contiguous_container:\n"327      "      beg     : %p\n"328      "      end     : %p\n"329      "      old_mid : %p\n"330      "      new_mid : %p\n",331      (void *)beg, (void *)end, (void *)old_mid, (void *)new_mid);332  stack->Print();333  ReportErrorSummary(scariness.GetDescription(), stack);334}335 336void ErrorBadParamsToAnnotateDoubleEndedContiguousContainer::Print() {337  Report(338      "ERROR: AddressSanitizer: bad parameters to "339      "__sanitizer_annotate_double_ended_contiguous_container:\n"340      "      storage_beg        : %p\n"341      "      storage_end        : %p\n"342      "      old_container_beg  : %p\n"343      "      old_container_end  : %p\n"344      "      new_container_beg  : %p\n"345      "      new_container_end  : %p\n",346      (void *)storage_beg, (void *)storage_end, (void *)old_container_beg,347      (void *)old_container_end, (void *)new_container_beg,348      (void *)new_container_end);349  stack->Print();350  ReportErrorSummary(scariness.GetDescription(), stack);351}352 353void ErrorBadParamsToCopyContiguousContainerAnnotations::Print() {354  Report(355      "ERROR: AddressSanitizer: bad parameters to "356      "__sanitizer_copy_contiguous_container_annotations:\n"357      "      src_storage_beg : %p\n"358      "      src_storage_end : %p\n"359      "      dst_storage_beg : %p\n"360      "      new_storage_end : %p\n",361      (void *)old_storage_beg, (void *)old_storage_end, (void *)new_storage_beg,362      (void *)new_storage_end);363  stack->Print();364  ReportErrorSummary(scariness.GetDescription(), stack);365}366 367void ErrorODRViolation::Print() {368  Decorator d;369  Printf("%s", d.Error());370  Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),371         (void *)global1.beg);372  Printf("%s", d.Default());373  InternalScopedString g1_loc;374  InternalScopedString g2_loc;375  PrintGlobalLocation(&g1_loc, global1, /*print_module_name=*/true);376  PrintGlobalLocation(&g2_loc, global2, /*print_module_name=*/true);377  Printf("  [1] size=%zd '%s' %s\n", global1.size,378         MaybeDemangleGlobalName(global1.name), g1_loc.data());379  Printf("  [2] size=%zd '%s' %s\n", global2.size,380         MaybeDemangleGlobalName(global2.name), g2_loc.data());381  if (stack_id1 && stack_id2) {382    Printf("These globals were registered at these points:\n");383    Printf("  [1]:\n");384    StackDepotGet(stack_id1).Print();385    Printf("  [2]:\n");386    StackDepotGet(stack_id2).Print();387  }388  Report(389      "HINT: if you don't care about these errors you may set "390      "ASAN_OPTIONS=detect_odr_violation=0\n");391  InternalScopedString error_msg;392  error_msg.AppendF("%s: global '%s' at %s", scariness.GetDescription(),393                    MaybeDemangleGlobalName(global1.name), g1_loc.data());394  ReportErrorSummary(error_msg.data());395}396 397void ErrorInvalidPointerPair::Print() {398  Decorator d;399  Printf("%s", d.Error());400  Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),401         (void *)addr1_description.Address(),402         (void *)addr2_description.Address());403  Printf("%s", d.Default());404  GET_STACK_TRACE_FATAL(pc, bp);405  stack.Print();406  addr1_description.Print();407  addr2_description.Print();408  ReportErrorSummary(scariness.GetDescription(), &stack);409}410 411static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {412  return s[-1] > 127 && s[1] > 127;413}414 415ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,416                           bool is_write_, uptr access_size_)417    : ErrorBase(tid),418      addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),419      pc(pc_),420      bp(bp_),421      sp(sp_),422      access_size(access_size_),423      is_write(is_write_),424      shadow_val(0) {425  scariness.Clear();426  if (access_size) {427    if (access_size <= 9) {428      char desr[] = "?-byte";429      desr[0] = '0' + access_size;430      scariness.Scare(access_size + access_size / 2, desr);431    } else if (access_size >= 10) {432      scariness.Scare(15, "multi-byte");433    }434    is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");435 436    // Determine the error type.437    bug_descr = "unknown-crash";438    if (AddrIsInMem(addr)) {439      u8 *shadow_addr = (u8 *)MemToShadow(addr);440      // If we are accessing 16 bytes, look at the second shadow byte.441      if (*shadow_addr == 0 && access_size > ASAN_SHADOW_GRANULARITY)442        shadow_addr++;443      // If we are in the partial right redzone, look at the next shadow byte.444      if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;445      bool far_from_bounds = false;446      shadow_val = *shadow_addr;447      int bug_type_score = 0;448      // For use-after-frees reads are almost as bad as writes.449      int read_after_free_bonus = 0;450      switch (shadow_val) {451        case kAsanHeapLeftRedzoneMagic:452        case kAsanArrayCookieMagic:453          bug_descr = "heap-buffer-overflow";454          bug_type_score = 10;455          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);456          break;457        case kAsanHeapFreeMagic:458          bug_descr = "heap-use-after-free";459          bug_type_score = 20;460          if (!is_write) read_after_free_bonus = 18;461          break;462        case kAsanStackLeftRedzoneMagic:463          bug_descr = "stack-buffer-underflow";464          bug_type_score = 25;465          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);466          break;467        case kAsanInitializationOrderMagic:468          bug_descr = "initialization-order-fiasco";469          bug_type_score = 1;470          break;471        case kAsanStackMidRedzoneMagic:472        case kAsanStackRightRedzoneMagic:473          bug_descr = "stack-buffer-overflow";474          bug_type_score = 25;475          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);476          break;477        case kAsanStackAfterReturnMagic:478          bug_descr = "stack-use-after-return";479          bug_type_score = 30;480          if (!is_write) read_after_free_bonus = 18;481          break;482        case kAsanUserPoisonedMemoryMagic:483          bug_descr = "use-after-poison";484          bug_type_score = 20;485          break;486        case kAsanContiguousContainerOOBMagic:487          bug_descr = "container-overflow";488          bug_type_score = 10;489          break;490        case kAsanStackUseAfterScopeMagic:491          bug_descr = "stack-use-after-scope";492          bug_type_score = 10;493          break;494        case kAsanGlobalRedzoneMagic:495          bug_descr = "global-buffer-overflow";496          bug_type_score = 10;497          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);498          break;499        case kAsanIntraObjectRedzone:500          bug_descr = "intra-object-overflow";501          bug_type_score = 10;502          break;503        case kAsanAllocaLeftMagic:504        case kAsanAllocaRightMagic:505          bug_descr = "dynamic-stack-buffer-overflow";506          bug_type_score = 25;507          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);508          break;509      }510      scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);511      if (far_from_bounds) scariness.Scare(10, "far-from-bounds");512    }513  }514}515 516static void PrintContainerOverflowHint() {517  Printf(518      "HINT: if you don't care about these errors you may set "519      "ASAN_OPTIONS=detect_container_overflow=0.\n"520      "Or if supported by the container library, pass "521      "-D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ to the compiler to disable "522      " instrumentation.\n"523      "If you suspect a false positive see also: "524      "https://github.com/google/sanitizers/wiki/"525      "AddressSanitizerContainerOverflow.\n");526}527 528static void PrintShadowByte(InternalScopedString *str, const char *before,529    u8 byte, const char *after = "\n") {530  PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);531}532 533static void PrintLegend(InternalScopedString *str) {534  str->AppendF(535      "Shadow byte legend (one shadow byte represents %d "536      "application bytes):\n",537      (int)ASAN_SHADOW_GRANULARITY);538  PrintShadowByte(str, "  Addressable:           ", 0);539  str->AppendF("  Partially addressable: ");540  for (u8 i = 1; i < ASAN_SHADOW_GRANULARITY; i++)541    PrintShadowByte(str, "", i, " ");542  str->AppendF("\n");543  PrintShadowByte(str, "  Heap left redzone:       ",544                  kAsanHeapLeftRedzoneMagic);545  PrintShadowByte(str, "  Freed heap region:       ", kAsanHeapFreeMagic);546  PrintShadowByte(str, "  Stack left redzone:      ",547                  kAsanStackLeftRedzoneMagic);548  PrintShadowByte(str, "  Stack mid redzone:       ",549                  kAsanStackMidRedzoneMagic);550  PrintShadowByte(str, "  Stack right redzone:     ",551                  kAsanStackRightRedzoneMagic);552  PrintShadowByte(str, "  Stack after return:      ",553                  kAsanStackAfterReturnMagic);554  PrintShadowByte(str, "  Stack use after scope:   ",555                  kAsanStackUseAfterScopeMagic);556  PrintShadowByte(str, "  Global redzone:          ", kAsanGlobalRedzoneMagic);557  PrintShadowByte(str, "  Global init order:       ",558                  kAsanInitializationOrderMagic);559  PrintShadowByte(str, "  Poisoned by user:        ",560                  kAsanUserPoisonedMemoryMagic);561  PrintShadowByte(str, "  Container overflow:      ",562                  kAsanContiguousContainerOOBMagic);563  PrintShadowByte(str, "  Array cookie:            ",564                  kAsanArrayCookieMagic);565  PrintShadowByte(str, "  Intra object redzone:    ",566                  kAsanIntraObjectRedzone);567  PrintShadowByte(str, "  ASan internal:           ", kAsanInternalHeapMagic);568  PrintShadowByte(str, "  Left alloca redzone:     ", kAsanAllocaLeftMagic);569  PrintShadowByte(str, "  Right alloca redzone:    ", kAsanAllocaRightMagic);570}571 572static void PrintShadowBytes(InternalScopedString *str, const char *before,573                             u8 *bytes, u8 *guilty, uptr n) {574  Decorator d;575  if (before)576    str->AppendF("%s%p:", before,577                 (void *)ShadowToMem(reinterpret_cast<uptr>(bytes)));578  for (uptr i = 0; i < n; i++) {579    u8 *p = bytes + i;580    const char *before =581        p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";582    const char *after = p == guilty ? "]" : "";583    PrintShadowByte(str, before, *p, after);584  }585  str->AppendF("\n");586}587 588static void PrintShadowMemoryForAddress(uptr addr) {589  if (!AddrIsInMem(addr)) return;590  uptr shadow_addr = MemToShadow(addr);591  const uptr n_bytes_per_row = 16;592  uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);593  InternalScopedString str;594  str.AppendF("Shadow bytes around the buggy address:\n");595  for (int i = -5; i <= 5; i++) {596    uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;597    // Skip rows that would be outside the shadow range. This can happen when598    // the user address is near the bottom, top, or shadow gap of the address599    // space.600    if (!AddrIsInShadow(row_shadow_addr)) continue;601    const char *prefix = (i == 0) ? "=>" : "  ";602    PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,603                     n_bytes_per_row);604  }605  if (flags()->print_legend) PrintLegend(&str);606  Printf("%s", str.data());607}608 609static void CheckPoisonRecords(uptr addr) {610  if (!AddrIsInMem(addr))611    return;612 613  u8 *shadow_addr = (u8 *)MemToShadow(addr);614  // If we are in the partial right redzone, look at the next shadow byte.615  if (*shadow_addr > 0 && *shadow_addr < 128)616    shadow_addr++;617  u8 shadow_val = *shadow_addr;618 619  if (shadow_val != kAsanUserPoisonedMemoryMagic)620    return;621 622  Printf("\n");623 624  if (flags()->poison_history_size <= 0) {625    Printf(626        "NOTE: the stack trace above identifies the code that *accessed* "627        "the poisoned memory.\n");628    Printf(629        "To identify the code that *poisoned* the memory, try the "630        "experimental setting ASAN_OPTIONS=poison_history_size=<size>.\n");631    return;632  }633 634  PoisonRecord record;635  if (FindPoisonRecord(addr, record)) {636    StackTrace poison_stack = StackDepotGet(record.stack_id);637    if (poison_stack.size > 0) {638      Printf("Memory was manually poisoned by thread T%u:\n", record.thread_id);639      poison_stack.Print();640    }641  } else {642    Printf("ERROR: no matching poison tracking record found.\n");643    Printf("Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n");644  }645}646 647void ErrorGeneric::Print() {648  Decorator d;649  Printf("%s", d.Error());650  uptr addr = addr_description.Address();651  Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",652         bug_descr, (void *)addr, (void *)pc, (void *)bp, (void *)sp);653  Printf("%s", d.Default());654 655  Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),656         access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,657         (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());658 659  scariness.Print();660  GET_STACK_TRACE_FATAL(pc, bp);661  stack.Print();662 663  // Pass bug_descr because we have a special case for664  // initialization-order-fiasco665  addr_description.Print(bug_descr);666  if (shadow_val == kAsanContiguousContainerOOBMagic)667    PrintContainerOverflowHint();668  ReportErrorSummary(bug_descr, &stack);669  PrintShadowMemoryForAddress(addr);670 671  // This is an experimental flag, hence we don't make a special handler.672  CheckPoisonRecords(addr);673}674 675}  // namespace __asan676