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