asan_report.cc revision cdce50bda3603770cc4ef80cbb613c78b8e47a17
1//===-- asan_report.cc ----------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of AddressSanitizer, an address sanity checker.
11//
12// This file contains error reporting code.
13//===----------------------------------------------------------------------===//
14#include "asan_flags.h"
15#include "asan_internal.h"
16#include "asan_mapping.h"
17#include "asan_report.h"
18#include "asan_stack.h"
19#include "asan_thread.h"
20#include "sanitizer_common/sanitizer_common.h"
21#include "sanitizer_common/sanitizer_flags.h"
22#include "sanitizer_common/sanitizer_report_decorator.h"
23#include "sanitizer_common/sanitizer_stackdepot.h"
24#include "sanitizer_common/sanitizer_symbolizer.h"
25
26namespace __asan {
27
28// -------------------- User-specified callbacks ----------------- {{{1
29static void (*error_report_callback)(const char*);
30static char *error_message_buffer = 0;
31static uptr error_message_buffer_pos = 0;
32static uptr error_message_buffer_size = 0;
33
34struct ReportData {
35  uptr pc;
36  uptr sp;
37  uptr bp;
38  uptr addr;
39  bool is_write;
40  uptr access_size;
41  const char *description;
42};
43
44static bool report_happened = false;
45static ReportData report_data = {};
46
47void AppendToErrorMessageBuffer(const char *buffer) {
48  if (error_message_buffer) {
49    uptr length = internal_strlen(buffer);
50    CHECK_GE(error_message_buffer_size, error_message_buffer_pos);
51    uptr remaining = error_message_buffer_size - error_message_buffer_pos;
52    internal_strncpy(error_message_buffer + error_message_buffer_pos,
53                     buffer, remaining);
54    error_message_buffer[error_message_buffer_size - 1] = '\0';
55    // FIXME: reallocate the buffer instead of truncating the message.
56    error_message_buffer_pos += Min(remaining, length);
57  }
58}
59
60// ---------------------- Decorator ------------------------------ {{{1
61class Decorator: public __sanitizer::SanitizerCommonDecorator {
62 public:
63  Decorator() : SanitizerCommonDecorator() { }
64  const char *Access()     { return Blue(); }
65  const char *EndAccess()  { return Default(); }
66  const char *Location()   { return Green(); }
67  const char *EndLocation() { return Default(); }
68  const char *Allocation()  { return Magenta(); }
69  const char *EndAllocation()  { return Default(); }
70
71  const char *ShadowByte(u8 byte) {
72    switch (byte) {
73      case kAsanHeapLeftRedzoneMagic:
74      case kAsanHeapRightRedzoneMagic:
75      case kAsanArrayCookieMagic:
76        return Red();
77      case kAsanHeapFreeMagic:
78        return Magenta();
79      case kAsanStackLeftRedzoneMagic:
80      case kAsanStackMidRedzoneMagic:
81      case kAsanStackRightRedzoneMagic:
82      case kAsanStackPartialRedzoneMagic:
83        return Red();
84      case kAsanStackAfterReturnMagic:
85        return Magenta();
86      case kAsanInitializationOrderMagic:
87        return Cyan();
88      case kAsanUserPoisonedMemoryMagic:
89      case kAsanContiguousContainerOOBMagic:
90      case kAsanAllocaLeftMagic:
91      case kAsanAllocaRightMagic:
92        return Blue();
93      case kAsanStackUseAfterScopeMagic:
94        return Magenta();
95      case kAsanGlobalRedzoneMagic:
96        return Red();
97      case kAsanInternalHeapMagic:
98        return Yellow();
99      case kAsanIntraObjectRedzone:
100        return Yellow();
101      default:
102        return Default();
103    }
104  }
105  const char *EndShadowByte() { return Default(); }
106  const char *MemoryByte() { return Magenta(); }
107  const char *EndMemoryByte() { return Default(); }
108};
109
110// ---------------------- Helper functions ----------------------- {{{1
111
112static void PrintMemoryByte(InternalScopedString *str, const char *before,
113    u8 byte, bool in_shadow, const char *after = "\n") {
114  Decorator d;
115  str->append("%s%s%x%x%s%s", before,
116              in_shadow ? d.ShadowByte(byte) : d.MemoryByte(),
117              byte >> 4, byte & 15,
118              in_shadow ? d.EndShadowByte() : d.EndMemoryByte(), after);
119}
120
121static void PrintShadowByte(InternalScopedString *str, const char *before,
122    u8 byte, const char *after = "\n") {
123  PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
124}
125
126static void PrintShadowBytes(InternalScopedString *str, const char *before,
127                             u8 *bytes, u8 *guilty, uptr n) {
128  Decorator d;
129  if (before) str->append("%s%p:", before, bytes);
130  for (uptr i = 0; i < n; i++) {
131    u8 *p = bytes + i;
132    const char *before =
133        p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
134    const char *after = p == guilty ? "]" : "";
135    PrintShadowByte(str, before, *p, after);
136  }
137  str->append("\n");
138}
139
140static void PrintLegend(InternalScopedString *str) {
141  str->append(
142      "Shadow byte legend (one shadow byte represents %d "
143      "application bytes):\n",
144      (int)SHADOW_GRANULARITY);
145  PrintShadowByte(str, "  Addressable:           ", 0);
146  str->append("  Partially addressable: ");
147  for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " ");
148  str->append("\n");
149  PrintShadowByte(str, "  Heap left redzone:       ",
150                  kAsanHeapLeftRedzoneMagic);
151  PrintShadowByte(str, "  Heap right redzone:      ",
152                  kAsanHeapRightRedzoneMagic);
153  PrintShadowByte(str, "  Freed heap region:       ", kAsanHeapFreeMagic);
154  PrintShadowByte(str, "  Stack left redzone:      ",
155                  kAsanStackLeftRedzoneMagic);
156  PrintShadowByte(str, "  Stack mid redzone:       ",
157                  kAsanStackMidRedzoneMagic);
158  PrintShadowByte(str, "  Stack right redzone:     ",
159                  kAsanStackRightRedzoneMagic);
160  PrintShadowByte(str, "  Stack partial redzone:   ",
161                  kAsanStackPartialRedzoneMagic);
162  PrintShadowByte(str, "  Stack after return:      ",
163                  kAsanStackAfterReturnMagic);
164  PrintShadowByte(str, "  Stack use after scope:   ",
165                  kAsanStackUseAfterScopeMagic);
166  PrintShadowByte(str, "  Global redzone:          ", kAsanGlobalRedzoneMagic);
167  PrintShadowByte(str, "  Global init order:       ",
168                  kAsanInitializationOrderMagic);
169  PrintShadowByte(str, "  Poisoned by user:        ",
170                  kAsanUserPoisonedMemoryMagic);
171  PrintShadowByte(str, "  Container overflow:      ",
172                  kAsanContiguousContainerOOBMagic);
173  PrintShadowByte(str, "  Array cookie:            ",
174                  kAsanArrayCookieMagic);
175  PrintShadowByte(str, "  Intra object redzone:    ",
176                  kAsanIntraObjectRedzone);
177  PrintShadowByte(str, "  ASan internal:           ", kAsanInternalHeapMagic);
178  PrintShadowByte(str, "  Left alloca redzone:     ", kAsanAllocaLeftMagic);
179  PrintShadowByte(str, "  Right alloca redzone:    ", kAsanAllocaRightMagic);
180}
181
182void MaybeDumpInstructionBytes(uptr pc) {
183  if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
184    return;
185  InternalScopedString str(1024);
186  str.append("First 16 instruction bytes at pc: ");
187  if (IsAccessibleMemoryRange(pc, 16)) {
188    for (int i = 0; i < 16; ++i) {
189      PrintMemoryByte(&str, "", ((u8 *)pc)[i], /*in_shadow*/false, " ");
190    }
191    str.append("\n");
192  } else {
193    str.append("unaccessible\n");
194  }
195  Report("%s", str.data());
196}
197
198static void PrintShadowMemoryForAddress(uptr addr) {
199  if (!AddrIsInMem(addr)) return;
200  uptr shadow_addr = MemToShadow(addr);
201  const uptr n_bytes_per_row = 16;
202  uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
203  InternalScopedString str(4096 * 8);
204  str.append("Shadow bytes around the buggy address:\n");
205  for (int i = -5; i <= 5; i++) {
206    const char *prefix = (i == 0) ? "=>" : "  ";
207    PrintShadowBytes(&str, prefix, (u8 *)(aligned_shadow + i * n_bytes_per_row),
208                     (u8 *)shadow_addr, n_bytes_per_row);
209  }
210  if (flags()->print_legend) PrintLegend(&str);
211  Printf("%s", str.data());
212}
213
214static void PrintZoneForPointer(uptr ptr, uptr zone_ptr,
215                                const char *zone_name) {
216  if (zone_ptr) {
217    if (zone_name) {
218      Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n",
219                 ptr, zone_ptr, zone_name);
220    } else {
221      Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n",
222                 ptr, zone_ptr);
223    }
224  } else {
225    Printf("malloc_zone_from_ptr(%p) = 0\n", ptr);
226  }
227}
228
229static void DescribeThread(AsanThread *t) {
230  if (t)
231    DescribeThread(t->context());
232}
233
234// ---------------------- Address Descriptions ------------------- {{{1
235
236static bool IsASCII(unsigned char c) {
237  return /*0x00 <= c &&*/ c <= 0x7F;
238}
239
240static const char *MaybeDemangleGlobalName(const char *name) {
241  // We can spoil names of globals with C linkage, so use an heuristic
242  // approach to check if the name should be demangled.
243  bool should_demangle = false;
244  if (name[0] == '_' && name[1] == 'Z')
245    should_demangle = true;
246  else if (SANITIZER_WINDOWS && name[0] == '\01' && name[1] == '?')
247    should_demangle = true;
248
249  return should_demangle ? Symbolizer::GetOrInit()->Demangle(name) : name;
250}
251
252// Check if the global is a zero-terminated ASCII string. If so, print it.
253static void PrintGlobalNameIfASCII(InternalScopedString *str,
254                                   const __asan_global &g) {
255  for (uptr p = g.beg; p < g.beg + g.size - 1; p++) {
256    unsigned char c = *(unsigned char*)p;
257    if (c == '\0' || !IsASCII(c)) return;
258  }
259  if (*(char*)(g.beg + g.size - 1) != '\0') return;
260  str->append("  '%s' is ascii string '%s'\n", MaybeDemangleGlobalName(g.name),
261              (char *)g.beg);
262}
263
264static const char *GlobalFilename(const __asan_global &g) {
265  const char *res = g.module_name;
266  // Prefer the filename from source location, if is available.
267  if (g.location)
268    res = g.location->filename;
269  CHECK(res);
270  return res;
271}
272
273static void PrintGlobalLocation(InternalScopedString *str,
274                                const __asan_global &g) {
275  str->append("%s", GlobalFilename(g));
276  if (!g.location)
277    return;
278  if (g.location->line_no)
279    str->append(":%d", g.location->line_no);
280  if (g.location->column_no)
281    str->append(":%d", g.location->column_no);
282}
283
284static void DescribeAddressRelativeToGlobal(uptr addr, uptr size,
285                                            const __asan_global &g) {
286  InternalScopedString str(4096);
287  Decorator d;
288  str.append("%s", d.Location());
289  if (addr < g.beg) {
290    str.append("%p is located %zd bytes to the left", (void *)addr,
291               g.beg - addr);
292  } else if (addr + size > g.beg + g.size) {
293    if (addr < g.beg + g.size)
294      addr = g.beg + g.size;
295    str.append("%p is located %zd bytes to the right", (void *)addr,
296               addr - (g.beg + g.size));
297  } else {
298    // Can it happen?
299    str.append("%p is located %zd bytes inside", (void *)addr, addr - g.beg);
300  }
301  str.append(" of global variable '%s' defined in '",
302             MaybeDemangleGlobalName(g.name));
303  PrintGlobalLocation(&str, g);
304  str.append("' (0x%zx) of size %zu\n", g.beg, g.size);
305  str.append("%s", d.EndLocation());
306  PrintGlobalNameIfASCII(&str, g);
307  Printf("%s", str.data());
308}
309
310static bool DescribeAddressIfGlobal(uptr addr, uptr size,
311                                    const char *bug_type) {
312  // Assume address is close to at most four globals.
313  const int kMaxGlobalsInReport = 4;
314  __asan_global globals[kMaxGlobalsInReport];
315  u32 reg_sites[kMaxGlobalsInReport];
316  int globals_num =
317      GetGlobalsForAddress(addr, globals, reg_sites, ARRAY_SIZE(globals));
318  if (globals_num == 0)
319    return false;
320  for (int i = 0; i < globals_num; i++) {
321    DescribeAddressRelativeToGlobal(addr, size, globals[i]);
322    if (0 == internal_strcmp(bug_type, "initialization-order-fiasco") &&
323        reg_sites[i]) {
324      Printf("  registered at:\n");
325      StackDepotGet(reg_sites[i]).Print();
326    }
327  }
328  return true;
329}
330
331bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr, bool print) {
332  if (AddrIsInMem(addr))
333    return false;
334  const char *area_type = nullptr;
335  if (AddrIsInShadowGap(addr)) area_type = "shadow gap";
336  else if (AddrIsInHighShadow(addr)) area_type = "high shadow";
337  else if (AddrIsInLowShadow(addr)) area_type = "low shadow";
338  if (area_type != nullptr) {
339    if (print) {
340      Printf("Address %p is located in the %s area.\n", addr, area_type);
341    } else {
342      CHECK(descr);
343      descr->region_kind = area_type;
344    }
345    return true;
346  }
347  CHECK(0 && "Address is not in memory and not in shadow?");
348  return false;
349}
350
351// Return " (thread_name) " or an empty string if the name is empty.
352const char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[],
353                                      uptr buff_len) {
354  const char *name = t->name;
355  if (name[0] == '\0') return "";
356  buff[0] = 0;
357  internal_strncat(buff, " (", 3);
358  internal_strncat(buff, name, buff_len - 4);
359  internal_strncat(buff, ")", 2);
360  return buff;
361}
362
363const char *ThreadNameWithParenthesis(u32 tid, char buff[],
364                                      uptr buff_len) {
365  if (tid == kInvalidTid) return "";
366  asanThreadRegistry().CheckLocked();
367  AsanThreadContext *t = GetThreadContextByTidLocked(tid);
368  return ThreadNameWithParenthesis(t, buff, buff_len);
369}
370
371static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
372                                          uptr access_size, uptr prev_var_end,
373                                          uptr next_var_beg) {
374  uptr var_end = var.beg + var.size;
375  uptr addr_end = addr + access_size;
376  const char *pos_descr = 0;
377  // If the variable [var.beg, var_end) is the nearest variable to the
378  // current memory access, indicate it in the log.
379  if (addr >= var.beg) {
380    if (addr_end <= var_end)
381      pos_descr = "is inside";  // May happen if this is a use-after-return.
382    else if (addr < var_end)
383      pos_descr = "partially overflows";
384    else if (addr_end <= next_var_beg &&
385             next_var_beg - addr_end >= addr - var_end)
386      pos_descr = "overflows";
387  } else {
388    if (addr_end > var.beg)
389      pos_descr = "partially underflows";
390    else if (addr >= prev_var_end &&
391             addr - prev_var_end >= var.beg - addr_end)
392      pos_descr = "underflows";
393  }
394  InternalScopedString str(1024);
395  str.append("    [%zd, %zd)", var.beg, var_end);
396  // Render variable name.
397  str.append(" '");
398  for (uptr i = 0; i < var.name_len; ++i) {
399    str.append("%c", var.name_pos[i]);
400  }
401  str.append("'");
402  if (pos_descr) {
403    Decorator d;
404    // FIXME: we may want to also print the size of the access here,
405    // but in case of accesses generated by memset it may be confusing.
406    str.append("%s <== Memory access at offset %zd %s this variable%s\n",
407               d.Location(), addr, pos_descr, d.EndLocation());
408  } else {
409    str.append("\n");
410  }
411  Printf("%s", str.data());
412}
413
414bool ParseFrameDescription(const char *frame_descr,
415                           InternalMmapVector<StackVarDescr> *vars) {
416  CHECK(frame_descr);
417  char *p;
418  // This string is created by the compiler and has the following form:
419  // "n alloc_1 alloc_2 ... alloc_n"
420  // where alloc_i looks like "offset size len ObjectName".
421  uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10);
422  if (n_objects == 0)
423    return false;
424
425  for (uptr i = 0; i < n_objects; i++) {
426    uptr beg  = (uptr)internal_simple_strtoll(p, &p, 10);
427    uptr size = (uptr)internal_simple_strtoll(p, &p, 10);
428    uptr len  = (uptr)internal_simple_strtoll(p, &p, 10);
429    if (beg == 0 || size == 0 || *p != ' ') {
430      return false;
431    }
432    p++;
433    StackVarDescr var = {beg, size, p, len};
434    vars->push_back(var);
435    p += len;
436  }
437
438  return true;
439}
440
441bool DescribeAddressIfStack(uptr addr, uptr access_size) {
442  AsanThread *t = FindThreadByStackAddress(addr);
443  if (!t) return false;
444
445  Decorator d;
446  char tname[128];
447  Printf("%s", d.Location());
448  Printf("Address %p is located in stack of thread T%d%s", addr, t->tid(),
449         ThreadNameWithParenthesis(t->tid(), tname, sizeof(tname)));
450
451  // Try to fetch precise stack frame for this access.
452  AsanThread::StackFrameAccess access;
453  if (!t->GetStackFrameAccessByAddr(addr, &access)) {
454    Printf("%s\n", d.EndLocation());
455    return true;
456  }
457  Printf(" at offset %zu in frame%s\n", access.offset, d.EndLocation());
458
459  // Now we print the frame where the alloca has happened.
460  // We print this frame as a stack trace with one element.
461  // The symbolizer may print more than one frame if inlining was involved.
462  // The frame numbers may be different than those in the stack trace printed
463  // previously. That's unfortunate, but I have no better solution,
464  // especially given that the alloca may be from entirely different place
465  // (e.g. use-after-scope, or different thread's stack).
466#if defined(__powerpc64__) && defined(__BIG_ENDIAN__)
467  // On PowerPC64 ELFv1, the address of a function actually points to a
468  // three-doubleword data structure with the first field containing
469  // the address of the function's code.
470  access.frame_pc = *reinterpret_cast<uptr *>(access.frame_pc);
471#endif
472  access.frame_pc += 16;
473  Printf("%s", d.EndLocation());
474  StackTrace alloca_stack(&access.frame_pc, 1);
475  alloca_stack.Print();
476
477  InternalMmapVector<StackVarDescr> vars(16);
478  if (!ParseFrameDescription(access.frame_descr, &vars)) {
479    Printf("AddressSanitizer can't parse the stack frame "
480           "descriptor: |%s|\n", access.frame_descr);
481    // 'addr' is a stack address, so return true even if we can't parse frame
482    return true;
483  }
484  uptr n_objects = vars.size();
485  // Report the number of stack objects.
486  Printf("  This frame has %zu object(s):\n", n_objects);
487
488  // Report all objects in this frame.
489  for (uptr i = 0; i < n_objects; i++) {
490    uptr prev_var_end = i ? vars[i - 1].beg + vars[i - 1].size : 0;
491    uptr next_var_beg = i + 1 < n_objects ? vars[i + 1].beg : ~(0UL);
492    PrintAccessAndVarIntersection(vars[i], access.offset, access_size,
493                                  prev_var_end, next_var_beg);
494  }
495  Printf("HINT: this may be a false positive if your program uses "
496         "some custom stack unwind mechanism or swapcontext\n");
497  if (SANITIZER_WINDOWS)
498    Printf("      (longjmp, SEH and C++ exceptions *are* supported)\n");
499  else
500    Printf("      (longjmp and C++ exceptions *are* supported)\n");
501
502  DescribeThread(t);
503  return true;
504}
505
506static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr,
507                                      uptr access_size) {
508  sptr offset;
509  Decorator d;
510  InternalScopedString str(4096);
511  str.append("%s", d.Location());
512  if (chunk.AddrIsAtLeft(addr, access_size, &offset)) {
513    str.append("%p is located %zd bytes to the left of", (void *)addr, offset);
514  } else if (chunk.AddrIsAtRight(addr, access_size, &offset)) {
515    if (offset < 0) {
516      addr -= offset;
517      offset = 0;
518    }
519    str.append("%p is located %zd bytes to the right of", (void *)addr, offset);
520  } else if (chunk.AddrIsInside(addr, access_size, &offset)) {
521    str.append("%p is located %zd bytes inside of", (void*)addr, offset);
522  } else {
523    str.append("%p is located somewhere around (this is AddressSanitizer bug!)",
524               (void *)addr);
525  }
526  str.append(" %zu-byte region [%p,%p)\n", chunk.UsedSize(),
527             (void *)(chunk.Beg()), (void *)(chunk.End()));
528  str.append("%s", d.EndLocation());
529  Printf("%s", str.data());
530}
531
532void DescribeHeapAddress(uptr addr, uptr access_size) {
533  AsanChunkView chunk = FindHeapChunkByAddress(addr);
534  if (!chunk.IsValid()) {
535    Printf("AddressSanitizer can not describe address in more detail "
536           "(wild memory access suspected).\n");
537    return;
538  }
539  DescribeAccessToHeapChunk(chunk, addr, access_size);
540  CHECK(chunk.AllocTid() != kInvalidTid);
541  asanThreadRegistry().CheckLocked();
542  AsanThreadContext *alloc_thread =
543      GetThreadContextByTidLocked(chunk.AllocTid());
544  StackTrace alloc_stack = chunk.GetAllocStack();
545  char tname[128];
546  Decorator d;
547  AsanThreadContext *free_thread = 0;
548  if (chunk.FreeTid() != kInvalidTid) {
549    free_thread = GetThreadContextByTidLocked(chunk.FreeTid());
550    Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(),
551           free_thread->tid,
552           ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)),
553           d.EndAllocation());
554    StackTrace free_stack = chunk.GetFreeStack();
555    free_stack.Print();
556    Printf("%spreviously allocated by thread T%d%s here:%s\n",
557           d.Allocation(), alloc_thread->tid,
558           ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
559           d.EndAllocation());
560  } else {
561    Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(),
562           alloc_thread->tid,
563           ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
564           d.EndAllocation());
565  }
566  alloc_stack.Print();
567  DescribeThread(GetCurrentThread());
568  if (free_thread)
569    DescribeThread(free_thread);
570  DescribeThread(alloc_thread);
571}
572
573static void DescribeAddress(uptr addr, uptr access_size, const char *bug_type) {
574  // Check if this is shadow or shadow gap.
575  if (DescribeAddressIfShadow(addr))
576    return;
577  CHECK(AddrIsInMem(addr));
578  if (DescribeAddressIfGlobal(addr, access_size, bug_type))
579    return;
580  if (DescribeAddressIfStack(addr, access_size))
581    return;
582  // Assume it is a heap address.
583  DescribeHeapAddress(addr, access_size);
584}
585
586// ------------------- Thread description -------------------- {{{1
587
588void DescribeThread(AsanThreadContext *context) {
589  CHECK(context);
590  asanThreadRegistry().CheckLocked();
591  // No need to announce the main thread.
592  if (context->tid == 0 || context->announced) {
593    return;
594  }
595  context->announced = true;
596  char tname[128];
597  InternalScopedString str(1024);
598  str.append("Thread T%d%s", context->tid,
599             ThreadNameWithParenthesis(context->tid, tname, sizeof(tname)));
600  if (context->parent_tid == kInvalidTid) {
601    str.append(" created by unknown thread\n");
602    Printf("%s", str.data());
603    return;
604  }
605  str.append(
606      " created by T%d%s here:\n", context->parent_tid,
607      ThreadNameWithParenthesis(context->parent_tid, tname, sizeof(tname)));
608  Printf("%s", str.data());
609  StackDepotGet(context->stack_id).Print();
610  // Recursively described parent thread if needed.
611  if (flags()->print_full_thread_history) {
612    AsanThreadContext *parent_context =
613        GetThreadContextByTidLocked(context->parent_tid);
614    DescribeThread(parent_context);
615  }
616}
617
618// -------------------- Different kinds of reports ----------------- {{{1
619
620// Use ScopedInErrorReport to run common actions just before and
621// immediately after printing error report.
622class ScopedInErrorReport {
623 public:
624  explicit ScopedInErrorReport(ReportData *report = nullptr) {
625    static atomic_uint32_t num_calls;
626    static u32 reporting_thread_tid;
627    if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
628      // Do not print more than one report, otherwise they will mix up.
629      // Error reporting functions shouldn't return at this situation, as
630      // they are defined as no-return.
631      Report("AddressSanitizer: while reporting a bug found another one. "
632                 "Ignoring.\n");
633      u32 current_tid = GetCurrentTidOrInvalid();
634      if (current_tid != reporting_thread_tid) {
635        // ASan found two bugs in different threads simultaneously. Sleep
636        // long enough to make sure that the thread which started to print
637        // an error report will finish doing it.
638        SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
639      }
640      // If we're still not dead for some reason, use raw _exit() instead of
641      // Die() to bypass any additional checks.
642      internal__exit(flags()->exitcode);
643    }
644    if (report) report_data = *report;
645    report_happened = true;
646    ASAN_ON_ERROR();
647    // Make sure the registry and sanitizer report mutexes are locked while
648    // we're printing an error report.
649    // We can lock them only here to avoid self-deadlock in case of
650    // recursive reports.
651    asanThreadRegistry().Lock();
652    CommonSanitizerReportMutex.Lock();
653    reporting_thread_tid = GetCurrentTidOrInvalid();
654    Printf("===================================================="
655           "=============\n");
656  }
657  // Destructor is NORETURN, as functions that report errors are.
658  NORETURN ~ScopedInErrorReport() {
659    // Make sure the current thread is announced.
660    DescribeThread(GetCurrentThread());
661    // We may want to grab this lock again when printing stats.
662    asanThreadRegistry().Unlock();
663    // Print memory stats.
664    if (flags()->print_stats)
665      __asan_print_accumulated_stats();
666    if (error_report_callback) {
667      error_report_callback(error_message_buffer);
668    }
669    Report("ABORTING\n");
670    Die();
671  }
672};
673
674void ReportStackOverflow(const SignalContext &sig) {
675  ScopedInErrorReport in_report;
676  Decorator d;
677  Printf("%s", d.Warning());
678  Report(
679      "ERROR: AddressSanitizer: stack-overflow on address %p"
680      " (pc %p bp %p sp %p T%d)\n",
681      (void *)sig.addr, (void *)sig.pc, (void *)sig.bp, (void *)sig.sp,
682      GetCurrentTidOrInvalid());
683  Printf("%s", d.EndWarning());
684  GET_STACK_TRACE_SIGNAL(sig);
685  stack.Print();
686  ReportErrorSummary("stack-overflow", &stack);
687}
688
689void ReportSIGSEGV(const char *description, const SignalContext &sig) {
690  ScopedInErrorReport in_report;
691  Decorator d;
692  Printf("%s", d.Warning());
693  Report(
694      "ERROR: AddressSanitizer: %s on unknown address %p"
695      " (pc %p bp %p sp %p T%d)\n",
696      description, (void *)sig.addr, (void *)sig.pc, (void *)sig.bp,
697      (void *)sig.sp, GetCurrentTidOrInvalid());
698  if (sig.pc < GetPageSizeCached()) {
699    Report("Hint: pc points to the zero page.\n");
700  }
701  Printf("%s", d.EndWarning());
702  GET_STACK_TRACE_SIGNAL(sig);
703  stack.Print();
704  MaybeDumpInstructionBytes(sig.pc);
705  Printf("AddressSanitizer can not provide additional info.\n");
706  ReportErrorSummary("SEGV", &stack);
707}
708
709void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
710  ScopedInErrorReport in_report;
711  Decorator d;
712  Printf("%s", d.Warning());
713  char tname[128];
714  u32 curr_tid = GetCurrentTidOrInvalid();
715  Report("ERROR: AddressSanitizer: attempting double-free on %p in "
716         "thread T%d%s:\n",
717         addr, curr_tid,
718         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
719  Printf("%s", d.EndWarning());
720  CHECK_GT(free_stack->size, 0);
721  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
722  stack.Print();
723  DescribeHeapAddress(addr, 1);
724  ReportErrorSummary("double-free", &stack);
725}
726
727void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
728                                 BufferedStackTrace *free_stack) {
729  ScopedInErrorReport in_report;
730  Decorator d;
731  Printf("%s", d.Warning());
732  char tname[128];
733  u32 curr_tid = GetCurrentTidOrInvalid();
734  Report("ERROR: AddressSanitizer: new-delete-type-mismatch on %p in "
735         "thread T%d%s:\n",
736         addr, curr_tid,
737         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
738  Printf("%s  object passed to delete has wrong type:\n", d.EndWarning());
739  Printf("  size of the allocated type:   %zd bytes;\n"
740         "  size of the deallocated type: %zd bytes.\n",
741         asan_mz_size(reinterpret_cast<void*>(addr)), delete_size);
742  CHECK_GT(free_stack->size, 0);
743  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
744  stack.Print();
745  DescribeHeapAddress(addr, 1);
746  ReportErrorSummary("new-delete-type-mismatch", &stack);
747  Report("HINT: if you don't care about these warnings you may set "
748         "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
749}
750
751void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) {
752  ScopedInErrorReport in_report;
753  Decorator d;
754  Printf("%s", d.Warning());
755  char tname[128];
756  u32 curr_tid = GetCurrentTidOrInvalid();
757  Report("ERROR: AddressSanitizer: attempting free on address "
758             "which was not malloc()-ed: %p in thread T%d%s\n", addr,
759         curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
760  Printf("%s", d.EndWarning());
761  CHECK_GT(free_stack->size, 0);
762  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
763  stack.Print();
764  DescribeHeapAddress(addr, 1);
765  ReportErrorSummary("bad-free", &stack);
766}
767
768void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
769                             AllocType alloc_type,
770                             AllocType dealloc_type) {
771  static const char *alloc_names[] =
772    {"INVALID", "malloc", "operator new", "operator new []"};
773  static const char *dealloc_names[] =
774    {"INVALID", "free", "operator delete", "operator delete []"};
775  CHECK_NE(alloc_type, dealloc_type);
776  ScopedInErrorReport in_report;
777  Decorator d;
778  Printf("%s", d.Warning());
779  Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n",
780        alloc_names[alloc_type], dealloc_names[dealloc_type], addr);
781  Printf("%s", d.EndWarning());
782  CHECK_GT(free_stack->size, 0);
783  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
784  stack.Print();
785  DescribeHeapAddress(addr, 1);
786  ReportErrorSummary("alloc-dealloc-mismatch", &stack);
787  Report("HINT: if you don't care about these warnings you may set "
788         "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
789}
790
791void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack) {
792  ScopedInErrorReport in_report;
793  Decorator d;
794  Printf("%s", d.Warning());
795  Report("ERROR: AddressSanitizer: attempting to call "
796             "malloc_usable_size() for pointer which is "
797             "not owned: %p\n", addr);
798  Printf("%s", d.EndWarning());
799  stack->Print();
800  DescribeHeapAddress(addr, 1);
801  ReportErrorSummary("bad-malloc_usable_size", stack);
802}
803
804void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
805                                             BufferedStackTrace *stack) {
806  ScopedInErrorReport in_report;
807  Decorator d;
808  Printf("%s", d.Warning());
809  Report("ERROR: AddressSanitizer: attempting to call "
810             "__sanitizer_get_allocated_size() for pointer which is "
811             "not owned: %p\n", addr);
812  Printf("%s", d.EndWarning());
813  stack->Print();
814  DescribeHeapAddress(addr, 1);
815  ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack);
816}
817
818void ReportStringFunctionMemoryRangesOverlap(const char *function,
819                                             const char *offset1, uptr length1,
820                                             const char *offset2, uptr length2,
821                                             BufferedStackTrace *stack) {
822  ScopedInErrorReport in_report;
823  Decorator d;
824  char bug_type[100];
825  internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
826  Printf("%s", d.Warning());
827  Report("ERROR: AddressSanitizer: %s: "
828             "memory ranges [%p,%p) and [%p, %p) overlap\n", \
829             bug_type, offset1, offset1 + length1, offset2, offset2 + length2);
830  Printf("%s", d.EndWarning());
831  stack->Print();
832  DescribeAddress((uptr)offset1, length1, bug_type);
833  DescribeAddress((uptr)offset2, length2, bug_type);
834  ReportErrorSummary(bug_type, stack);
835}
836
837void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
838                                      BufferedStackTrace *stack) {
839  ScopedInErrorReport in_report;
840  Decorator d;
841  const char *bug_type = "negative-size-param";
842  Printf("%s", d.Warning());
843  Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
844  Printf("%s", d.EndWarning());
845  stack->Print();
846  DescribeAddress(offset, size, bug_type);
847  ReportErrorSummary(bug_type, stack);
848}
849
850void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
851                                                  uptr old_mid, uptr new_mid,
852                                                  BufferedStackTrace *stack) {
853  ScopedInErrorReport in_report;
854  Report("ERROR: AddressSanitizer: bad parameters to "
855         "__sanitizer_annotate_contiguous_container:\n"
856         "      beg     : %p\n"
857         "      end     : %p\n"
858         "      old_mid : %p\n"
859         "      new_mid : %p\n",
860         beg, end, old_mid, new_mid);
861  uptr granularity = SHADOW_GRANULARITY;
862  if (!IsAligned(beg, granularity))
863    Report("ERROR: beg is not aligned by %d\n", granularity);
864  stack->Print();
865  ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
866}
867
868void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
869                        const __asan_global *g2, u32 stack_id2) {
870  ScopedInErrorReport in_report;
871  Decorator d;
872  Printf("%s", d.Warning());
873  Report("ERROR: AddressSanitizer: odr-violation (%p):\n", g1->beg);
874  Printf("%s", d.EndWarning());
875  InternalScopedString g1_loc(256), g2_loc(256);
876  PrintGlobalLocation(&g1_loc, *g1);
877  PrintGlobalLocation(&g2_loc, *g2);
878  Printf("  [1] size=%zd '%s' %s\n", g1->size,
879         MaybeDemangleGlobalName(g1->name), g1_loc.data());
880  Printf("  [2] size=%zd '%s' %s\n", g2->size,
881         MaybeDemangleGlobalName(g2->name), g2_loc.data());
882  if (stack_id1 && stack_id2) {
883    Printf("These globals were registered at these points:\n");
884    Printf("  [1]:\n");
885    StackDepotGet(stack_id1).Print();
886    Printf("  [2]:\n");
887    StackDepotGet(stack_id2).Print();
888  }
889  Report("HINT: if you don't care about these warnings you may set "
890         "ASAN_OPTIONS=detect_odr_violation=0\n");
891  InternalScopedString error_msg(256);
892  error_msg.append("odr-violation: global '%s' at %s",
893                   MaybeDemangleGlobalName(g1->name), g1_loc.data());
894  ReportErrorSummary(error_msg.data());
895}
896
897// ----------------------- CheckForInvalidPointerPair ----------- {{{1
898static NOINLINE void
899ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {
900  ScopedInErrorReport in_report;
901  const char *bug_type = "invalid-pointer-pair";
902  Decorator d;
903  Printf("%s", d.Warning());
904  Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n", a1, a2);
905  Printf("%s", d.EndWarning());
906  GET_STACK_TRACE_FATAL(pc, bp);
907  stack.Print();
908  DescribeAddress(a1, 1, bug_type);
909  DescribeAddress(a2, 1, bug_type);
910  ReportErrorSummary(bug_type, &stack);
911}
912
913static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
914  if (!flags()->detect_invalid_pointer_pairs) return;
915  uptr a1 = reinterpret_cast<uptr>(p1);
916  uptr a2 = reinterpret_cast<uptr>(p2);
917  AsanChunkView chunk1 = FindHeapChunkByAddress(a1);
918  AsanChunkView chunk2 = FindHeapChunkByAddress(a2);
919  bool valid1 = chunk1.IsValid();
920  bool valid2 = chunk2.IsValid();
921  if ((valid1 != valid2) || (valid1 && valid2 && !chunk1.Eq(chunk2))) {
922    GET_CALLER_PC_BP_SP;                                              \
923    return ReportInvalidPointerPair(pc, bp, sp, a1, a2);
924  }
925}
926// ----------------------- Mac-specific reports ----------------- {{{1
927
928void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
929                            BufferedStackTrace *stack) {
930  // Just print a warning here.
931  Printf("free_common(%p) -- attempting to free unallocated memory.\n"
932             "AddressSanitizer is ignoring this error on Mac OS now.\n",
933             addr);
934  PrintZoneForPointer(addr, zone_ptr, zone_name);
935  stack->Print();
936  DescribeHeapAddress(addr, 1);
937}
938
939void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
940                               BufferedStackTrace *stack) {
941  ScopedInErrorReport in_report;
942  Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n"
943             "This is an unrecoverable problem, exiting now.\n",
944             addr);
945  PrintZoneForPointer(addr, zone_ptr, zone_name);
946  stack->Print();
947  DescribeHeapAddress(addr, 1);
948}
949
950void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
951                               BufferedStackTrace *stack) {
952  ScopedInErrorReport in_report;
953  Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n"
954             "This is an unrecoverable problem, exiting now.\n",
955             addr);
956  PrintZoneForPointer(addr, zone_ptr, zone_name);
957  stack->Print();
958  DescribeHeapAddress(addr, 1);
959}
960
961}  // namespace __asan
962
963// --------------------------- Interface --------------------- {{{1
964using namespace __asan;  // NOLINT
965
966void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
967                         uptr access_size, u32 exp) {
968  ENABLE_FRAME_POINTER;
969
970  // Optimization experiments.
971  // The experiments can be used to evaluate potential optimizations that remove
972  // instrumentation (assess false negatives). Instead of completely removing
973  // some instrumentation, compiler can emit special calls into runtime
974  // (e.g. __asan_report_exp_load1 instead of __asan_report_load1) and pass
975  // mask of experiments (exp).
976  // The reaction to a non-zero value of exp is to be defined.
977  (void)exp;
978
979  // Determine the error type.
980  const char *bug_descr = "unknown-crash";
981  if (AddrIsInMem(addr)) {
982    u8 *shadow_addr = (u8*)MemToShadow(addr);
983    // If we are accessing 16 bytes, look at the second shadow byte.
984    if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY)
985      shadow_addr++;
986    // If we are in the partial right redzone, look at the next shadow byte.
987    if (*shadow_addr > 0 && *shadow_addr < 128)
988      shadow_addr++;
989    switch (*shadow_addr) {
990      case kAsanHeapLeftRedzoneMagic:
991      case kAsanHeapRightRedzoneMagic:
992      case kAsanArrayCookieMagic:
993        bug_descr = "heap-buffer-overflow";
994        break;
995      case kAsanHeapFreeMagic:
996        bug_descr = "heap-use-after-free";
997        break;
998      case kAsanStackLeftRedzoneMagic:
999        bug_descr = "stack-buffer-underflow";
1000        break;
1001      case kAsanInitializationOrderMagic:
1002        bug_descr = "initialization-order-fiasco";
1003        break;
1004      case kAsanStackMidRedzoneMagic:
1005      case kAsanStackRightRedzoneMagic:
1006      case kAsanStackPartialRedzoneMagic:
1007        bug_descr = "stack-buffer-overflow";
1008        break;
1009      case kAsanStackAfterReturnMagic:
1010        bug_descr = "stack-use-after-return";
1011        break;
1012      case kAsanUserPoisonedMemoryMagic:
1013        bug_descr = "use-after-poison";
1014        break;
1015      case kAsanContiguousContainerOOBMagic:
1016        bug_descr = "container-overflow";
1017        break;
1018      case kAsanStackUseAfterScopeMagic:
1019        bug_descr = "stack-use-after-scope";
1020        break;
1021      case kAsanGlobalRedzoneMagic:
1022        bug_descr = "global-buffer-overflow";
1023        break;
1024      case kAsanIntraObjectRedzone:
1025        bug_descr = "intra-object-overflow";
1026        break;
1027      case kAsanAllocaLeftMagic:
1028      case kAsanAllocaRightMagic:
1029        bug_descr = "dynamic-stack-buffer-overflow";
1030        break;
1031    }
1032  }
1033
1034  ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,
1035                        bug_descr };
1036  ScopedInErrorReport in_report(&report);
1037
1038  Decorator d;
1039  Printf("%s", d.Warning());
1040  Report("ERROR: AddressSanitizer: %s on address "
1041             "%p at pc %p bp %p sp %p\n",
1042             bug_descr, (void*)addr, pc, bp, sp);
1043  Printf("%s", d.EndWarning());
1044
1045  u32 curr_tid = GetCurrentTidOrInvalid();
1046  char tname[128];
1047  Printf("%s%s of size %zu at %p thread T%d%s%s\n",
1048         d.Access(),
1049         access_size ? (is_write ? "WRITE" : "READ") : "ACCESS",
1050         access_size, (void*)addr, curr_tid,
1051         ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)),
1052         d.EndAccess());
1053
1054  GET_STACK_TRACE_FATAL(pc, bp);
1055  stack.Print();
1056
1057  DescribeAddress(addr, access_size, bug_descr);
1058  ReportErrorSummary(bug_descr, &stack);
1059  PrintShadowMemoryForAddress(addr);
1060}
1061
1062void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
1063  error_report_callback = callback;
1064  if (callback) {
1065    error_message_buffer_size = 1 << 16;
1066    error_message_buffer =
1067        (char*)MmapOrDie(error_message_buffer_size, __func__);
1068    error_message_buffer_pos = 0;
1069  }
1070}
1071
1072void __asan_describe_address(uptr addr) {
1073  // Thread registry must be locked while we're describing an address.
1074  asanThreadRegistry().Lock();
1075  DescribeAddress(addr, 1, "");
1076  asanThreadRegistry().Unlock();
1077}
1078
1079int __asan_report_present() {
1080  return report_happened ? 1 : 0;
1081}
1082
1083uptr __asan_get_report_pc() {
1084  return report_data.pc;
1085}
1086
1087uptr __asan_get_report_bp() {
1088  return report_data.bp;
1089}
1090
1091uptr __asan_get_report_sp() {
1092  return report_data.sp;
1093}
1094
1095uptr __asan_get_report_address() {
1096  return report_data.addr;
1097}
1098
1099int __asan_get_report_access_type() {
1100  return report_data.is_write ? 1 : 0;
1101}
1102
1103uptr __asan_get_report_access_size() {
1104  return report_data.access_size;
1105}
1106
1107const char *__asan_get_report_description() {
1108  return report_data.description;
1109}
1110
1111extern "C" {
1112SANITIZER_INTERFACE_ATTRIBUTE
1113void __sanitizer_ptr_sub(void *a, void *b) {
1114  CheckForInvalidPointerPair(a, b);
1115}
1116SANITIZER_INTERFACE_ATTRIBUTE
1117void __sanitizer_ptr_cmp(void *a, void *b) {
1118  CheckForInvalidPointerPair(a, b);
1119}
1120}  // extern "C"
1121
1122#if !SANITIZER_SUPPORTS_WEAK_HOOKS
1123// Provide default implementation of __asan_on_error that does nothing
1124// and may be overriden by user.
1125SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE
1126void __asan_on_error() {}
1127#endif
1128