blob: 1bade8c416991fb58990980377c33fa661307bfe [file] [log] [blame]
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +00001//===-- asan_errors.cc ------------------------------------------*- C++ -*-===//
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// ASan implementation for error structures.
13//===----------------------------------------------------------------------===//
14
15#include "asan_errors.h"
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000016#include <signal.h>
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000017#include "asan_descriptions.h"
Filipe Cabecinhasb50a5b32016-09-15 08:10:48 +000018#include "asan_mapping.h"
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000019#include "asan_report.h"
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +000020#include "asan_stack.h"
Filipe Cabecinhas719db0c2016-09-15 08:10:52 +000021#include "sanitizer_common/sanitizer_stackdepot.h"
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +000022
23namespace __asan {
24
Vitaly Buka21ddc622017-09-14 22:44:03 +000025static void OnStackUnwind(const SignalContext &sig,
26 const void *callback_context,
27 BufferedStackTrace *stack) {
Vitaly Buka86dd0882017-09-18 06:56:57 +000028 bool fast = common_flags()->fast_unwind_on_fatal;
29#if SANITIZER_FREEBSD || SANITIZER_NETBSD
30 // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
31 // yields the call stack of the signal's handler and not of the code
32 // that raised the signal (as it does on Linux).
33 fast = true;
34#endif
Vitaly Buka21ddc622017-09-14 22:44:03 +000035 // Tests and maybe some users expect that scariness is going to be printed
36 // just before the stack. As only asan has scariness score we have no
37 // corresponding code in the sanitizer_common and we use this callback to
38 // print it.
39 static_cast<const ScarinessScoreBase *>(callback_context)->Print();
Vitaly Buka66f32fc2017-11-09 07:53:06 +000040 GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast);
Vitaly Buka21ddc622017-09-14 22:44:03 +000041}
42
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000043void ErrorDeadlySignal::Print() {
Vitaly Buka21ddc622017-09-14 22:44:03 +000044 ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000045}
46
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000047void ErrorDoubleFree::Print() {
48 Decorator d;
49 Printf("%s", d.Warning());
50 char tname[128];
51 Report(
Kuba Mracek48090f52016-11-28 21:18:15 +000052 "ERROR: AddressSanitizer: attempting %s on %p in "
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000053 "thread T%d%s:\n",
Kuba Mracek48090f52016-11-28 21:18:15 +000054 scariness.GetDescription(), addr_description.addr, tid,
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000055 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
Vitaly Buka36266b62017-09-11 20:55:49 +000056 Printf("%s", d.Default());
Filipe Cabecinhas453b5552016-08-31 09:39:47 +000057 scariness.Print();
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000058 GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
59 second_free_stack->top_frame_bp);
60 stack.Print();
61 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +000062 ReportErrorSummary(scariness.GetDescription(), &stack);
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000063}
64
Alex Shlyapnikova53b55f2017-10-25 17:21:37 +000065void ErrorNewDeleteTypeMismatch::Print() {
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +000066 Decorator d;
67 Printf("%s", d.Warning());
68 char tname[128];
69 Report(
Kuba Mracek48090f52016-11-28 21:18:15 +000070 "ERROR: AddressSanitizer: %s on %p in thread "
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +000071 "T%d%s:\n",
Kuba Mracek48090f52016-11-28 21:18:15 +000072 scariness.GetDescription(), addr_description.addr, tid,
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +000073 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
Vitaly Buka36266b62017-09-11 20:55:49 +000074 Printf("%s object passed to delete has wrong type:\n", d.Default());
Alex Shlyapnikova53b55f2017-10-25 17:21:37 +000075 if (delete_size != 0) {
76 Printf(
77 " size of the allocated type: %zd bytes;\n"
78 " size of the deallocated type: %zd bytes.\n",
79 addr_description.chunk_access.chunk_size, delete_size);
80 }
81 const uptr user_alignment =
82 addr_description.chunk_access.user_requested_alignment;
83 if (delete_alignment != user_alignment) {
84 char user_alignment_str[32];
85 char delete_alignment_str[32];
86 internal_snprintf(user_alignment_str, sizeof(user_alignment_str),
87 "%zd bytes", user_alignment);
88 internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str),
89 "%zd bytes", delete_alignment);
90 static const char *kDefaultAlignment = "default-aligned";
91 Printf(
92 " alignment of the allocated type: %s;\n"
93 " alignment of the deallocated type: %s.\n",
94 user_alignment > 0 ? user_alignment_str : kDefaultAlignment,
95 delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment);
96 }
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +000097 CHECK_GT(free_stack->size, 0);
98 scariness.Print();
99 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
100 stack.Print();
101 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000102 ReportErrorSummary(scariness.GetDescription(), &stack);
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +0000103 Report(
104 "HINT: if you don't care about these errors you may set "
105 "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
106}
107
Filipe Cabecinhas6fb54622016-09-13 20:47:29 +0000108void ErrorFreeNotMalloced::Print() {
109 Decorator d;
110 Printf("%s", d.Warning());
111 char tname[128];
112 Report(
113 "ERROR: AddressSanitizer: attempting free on address "
114 "which was not malloc()-ed: %p in thread T%d%s\n",
115 addr_description.Address(), tid,
116 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
Vitaly Buka36266b62017-09-11 20:55:49 +0000117 Printf("%s", d.Default());
Filipe Cabecinhas6fb54622016-09-13 20:47:29 +0000118 CHECK_GT(free_stack->size, 0);
119 scariness.Print();
120 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
121 stack.Print();
122 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000123 ReportErrorSummary(scariness.GetDescription(), &stack);
Filipe Cabecinhas6fb54622016-09-13 20:47:29 +0000124}
125
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000126void ErrorAllocTypeMismatch::Print() {
127 static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
128 "operator new []"};
129 static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
130 "operator delete []"};
131 CHECK_NE(alloc_type, dealloc_type);
132 Decorator d;
133 Printf("%s", d.Warning());
Kuba Mracek48090f52016-11-28 21:18:15 +0000134 Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
135 scariness.GetDescription(),
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000136 alloc_names[alloc_type], dealloc_names[dealloc_type],
137 addr_description.addr);
Vitaly Buka36266b62017-09-11 20:55:49 +0000138 Printf("%s", d.Default());
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000139 CHECK_GT(dealloc_stack->size, 0);
140 scariness.Print();
141 GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
142 stack.Print();
143 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000144 ReportErrorSummary(scariness.GetDescription(), &stack);
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000145 Report(
146 "HINT: if you don't care about these errors you may set "
147 "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
148}
149
Filipe Cabecinhas5f862c22016-09-13 20:47:37 +0000150void ErrorMallocUsableSizeNotOwned::Print() {
151 Decorator d;
152 Printf("%s", d.Warning());
153 Report(
154 "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
155 "pointer which is not owned: %p\n",
156 addr_description.Address());
Vitaly Buka36266b62017-09-11 20:55:49 +0000157 Printf("%s", d.Default());
Filipe Cabecinhas5f862c22016-09-13 20:47:37 +0000158 stack->Print();
159 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000160 ReportErrorSummary(scariness.GetDescription(), stack);
Filipe Cabecinhas5f862c22016-09-13 20:47:37 +0000161}
162
Filipe Cabecinhasb0de43a2016-09-13 20:47:42 +0000163void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
164 Decorator d;
165 Printf("%s", d.Warning());
166 Report(
167 "ERROR: AddressSanitizer: attempting to call "
168 "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
169 addr_description.Address());
Vitaly Buka36266b62017-09-11 20:55:49 +0000170 Printf("%s", d.Default());
Filipe Cabecinhasb0de43a2016-09-13 20:47:42 +0000171 stack->Print();
172 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000173 ReportErrorSummary(scariness.GetDescription(), stack);
Filipe Cabecinhasb0de43a2016-09-13 20:47:42 +0000174}
175
Filipe Cabecinhas7a196b92016-09-14 07:37:14 +0000176void ErrorStringFunctionMemoryRangesOverlap::Print() {
177 Decorator d;
178 char bug_type[100];
179 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
180 Printf("%s", d.Warning());
181 Report(
182 "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
183 "overlap\n",
184 bug_type, addr1_description.Address(),
185 addr1_description.Address() + length1, addr2_description.Address(),
186 addr2_description.Address() + length2);
Vitaly Buka36266b62017-09-11 20:55:49 +0000187 Printf("%s", d.Default());
Filipe Cabecinhas7a196b92016-09-14 07:37:14 +0000188 scariness.Print();
189 stack->Print();
190 addr1_description.Print();
191 addr2_description.Print();
192 ReportErrorSummary(bug_type, stack);
193}
194
Filipe Cabecinhas36229e92016-09-14 07:37:20 +0000195void ErrorStringFunctionSizeOverflow::Print() {
196 Decorator d;
197 Printf("%s", d.Warning());
Kuba Mracek48090f52016-11-28 21:18:15 +0000198 Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
199 scariness.GetDescription(), size);
Vitaly Buka36266b62017-09-11 20:55:49 +0000200 Printf("%s", d.Default());
Filipe Cabecinhas36229e92016-09-14 07:37:20 +0000201 scariness.Print();
202 stack->Print();
203 addr_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000204 ReportErrorSummary(scariness.GetDescription(), stack);
Filipe Cabecinhas36229e92016-09-14 07:37:20 +0000205}
206
Filipe Cabecinhasb50a5b32016-09-15 08:10:48 +0000207void ErrorBadParamsToAnnotateContiguousContainer::Print() {
208 Report(
209 "ERROR: AddressSanitizer: bad parameters to "
210 "__sanitizer_annotate_contiguous_container:\n"
211 " beg : %p\n"
212 " end : %p\n"
213 " old_mid : %p\n"
214 " new_mid : %p\n",
215 beg, end, old_mid, new_mid);
216 uptr granularity = SHADOW_GRANULARITY;
217 if (!IsAligned(beg, granularity))
218 Report("ERROR: beg is not aligned by %d\n", granularity);
219 stack->Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000220 ReportErrorSummary(scariness.GetDescription(), stack);
Filipe Cabecinhasb50a5b32016-09-15 08:10:48 +0000221}
222
Filipe Cabecinhas719db0c2016-09-15 08:10:52 +0000223void ErrorODRViolation::Print() {
224 Decorator d;
225 Printf("%s", d.Warning());
Kuba Mracek48090f52016-11-28 21:18:15 +0000226 Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
227 global1.beg);
Vitaly Buka36266b62017-09-11 20:55:49 +0000228 Printf("%s", d.Default());
Filipe Cabecinhas719db0c2016-09-15 08:10:52 +0000229 InternalScopedString g1_loc(256), g2_loc(256);
230 PrintGlobalLocation(&g1_loc, global1);
231 PrintGlobalLocation(&g2_loc, global2);
232 Printf(" [1] size=%zd '%s' %s\n", global1.size,
233 MaybeDemangleGlobalName(global1.name), g1_loc.data());
234 Printf(" [2] size=%zd '%s' %s\n", global2.size,
235 MaybeDemangleGlobalName(global2.name), g2_loc.data());
236 if (stack_id1 && stack_id2) {
237 Printf("These globals were registered at these points:\n");
238 Printf(" [1]:\n");
239 StackDepotGet(stack_id1).Print();
240 Printf(" [2]:\n");
241 StackDepotGet(stack_id2).Print();
242 }
243 Report(
244 "HINT: if you don't care about these errors you may set "
245 "ASAN_OPTIONS=detect_odr_violation=0\n");
246 InternalScopedString error_msg(256);
Kuba Mracek48090f52016-11-28 21:18:15 +0000247 error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
Filipe Cabecinhas719db0c2016-09-15 08:10:52 +0000248 MaybeDemangleGlobalName(global1.name), g1_loc.data());
249 ReportErrorSummary(error_msg.data());
250}
251
Filipe Cabecinhas1b3742e2016-09-15 08:10:56 +0000252void ErrorInvalidPointerPair::Print() {
Filipe Cabecinhas1b3742e2016-09-15 08:10:56 +0000253 Decorator d;
254 Printf("%s", d.Warning());
Kuba Mracek48090f52016-11-28 21:18:15 +0000255 Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
Filipe Cabecinhas490f96c2016-09-21 19:21:01 +0000256 addr1_description.Address(), addr2_description.Address());
Vitaly Buka36266b62017-09-11 20:55:49 +0000257 Printf("%s", d.Default());
Filipe Cabecinhas1b3742e2016-09-15 08:10:56 +0000258 GET_STACK_TRACE_FATAL(pc, bp);
259 stack.Print();
Filipe Cabecinhas490f96c2016-09-21 19:21:01 +0000260 addr1_description.Print();
261 addr2_description.Print();
Kuba Mracek48090f52016-11-28 21:18:15 +0000262 ReportErrorSummary(scariness.GetDescription(), &stack);
Filipe Cabecinhas1b3742e2016-09-15 08:10:56 +0000263}
264
Filipe Cabecinhasa8b5f5e2016-09-21 20:18:18 +0000265static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
266 return s[-1] > 127 && s[1] > 127;
267}
268
269ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
270 bool is_write_, uptr access_size_)
271 : ErrorBase(tid),
272 addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
273 pc(pc_),
274 bp(bp_),
275 sp(sp_),
276 access_size(access_size_),
277 is_write(is_write_),
278 shadow_val(0) {
279 scariness.Clear();
280 if (access_size) {
281 if (access_size <= 9) {
282 char desr[] = "?-byte";
283 desr[0] = '0' + access_size;
284 scariness.Scare(access_size + access_size / 2, desr);
285 } else if (access_size >= 10) {
286 scariness.Scare(15, "multi-byte");
287 }
288 is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");
289
290 // Determine the error type.
291 bug_descr = "unknown-crash";
292 if (AddrIsInMem(addr)) {
293 u8 *shadow_addr = (u8 *)MemToShadow(addr);
294 // If we are accessing 16 bytes, look at the second shadow byte.
295 if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) shadow_addr++;
296 // If we are in the partial right redzone, look at the next shadow byte.
297 if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;
298 bool far_from_bounds = false;
299 shadow_val = *shadow_addr;
300 int bug_type_score = 0;
301 // For use-after-frees reads are almost as bad as writes.
302 int read_after_free_bonus = 0;
303 switch (shadow_val) {
304 case kAsanHeapLeftRedzoneMagic:
305 case kAsanArrayCookieMagic:
306 bug_descr = "heap-buffer-overflow";
307 bug_type_score = 10;
308 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
309 break;
310 case kAsanHeapFreeMagic:
311 bug_descr = "heap-use-after-free";
312 bug_type_score = 20;
313 if (!is_write) read_after_free_bonus = 18;
314 break;
315 case kAsanStackLeftRedzoneMagic:
316 bug_descr = "stack-buffer-underflow";
317 bug_type_score = 25;
318 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
319 break;
320 case kAsanInitializationOrderMagic:
321 bug_descr = "initialization-order-fiasco";
322 bug_type_score = 1;
323 break;
324 case kAsanStackMidRedzoneMagic:
325 case kAsanStackRightRedzoneMagic:
326 bug_descr = "stack-buffer-overflow";
327 bug_type_score = 25;
328 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
329 break;
330 case kAsanStackAfterReturnMagic:
331 bug_descr = "stack-use-after-return";
332 bug_type_score = 30;
333 if (!is_write) read_after_free_bonus = 18;
334 break;
335 case kAsanUserPoisonedMemoryMagic:
336 bug_descr = "use-after-poison";
337 bug_type_score = 20;
338 break;
339 case kAsanContiguousContainerOOBMagic:
340 bug_descr = "container-overflow";
341 bug_type_score = 10;
342 break;
343 case kAsanStackUseAfterScopeMagic:
344 bug_descr = "stack-use-after-scope";
345 bug_type_score = 10;
346 break;
347 case kAsanGlobalRedzoneMagic:
348 bug_descr = "global-buffer-overflow";
349 bug_type_score = 10;
350 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
351 break;
352 case kAsanIntraObjectRedzone:
353 bug_descr = "intra-object-overflow";
354 bug_type_score = 10;
355 break;
356 case kAsanAllocaLeftMagic:
357 case kAsanAllocaRightMagic:
358 bug_descr = "dynamic-stack-buffer-overflow";
359 bug_type_score = 25;
360 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
361 break;
362 }
363 scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
364 if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
365 }
366 }
367}
368
369static void PrintContainerOverflowHint() {
370 Printf("HINT: if you don't care about these errors you may set "
371 "ASAN_OPTIONS=detect_container_overflow=0.\n"
372 "If you suspect a false positive see also: "
373 "https://github.com/google/sanitizers/wiki/"
374 "AddressSanitizerContainerOverflow.\n");
375}
376
377static void PrintShadowByte(InternalScopedString *str, const char *before,
378 u8 byte, const char *after = "\n") {
379 PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
380}
381
382static void PrintLegend(InternalScopedString *str) {
383 str->append(
384 "Shadow byte legend (one shadow byte represents %d "
385 "application bytes):\n",
386 (int)SHADOW_GRANULARITY);
387 PrintShadowByte(str, " Addressable: ", 0);
388 str->append(" Partially addressable: ");
389 for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " ");
390 str->append("\n");
391 PrintShadowByte(str, " Heap left redzone: ",
392 kAsanHeapLeftRedzoneMagic);
393 PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic);
394 PrintShadowByte(str, " Stack left redzone: ",
395 kAsanStackLeftRedzoneMagic);
396 PrintShadowByte(str, " Stack mid redzone: ",
397 kAsanStackMidRedzoneMagic);
398 PrintShadowByte(str, " Stack right redzone: ",
399 kAsanStackRightRedzoneMagic);
400 PrintShadowByte(str, " Stack after return: ",
401 kAsanStackAfterReturnMagic);
402 PrintShadowByte(str, " Stack use after scope: ",
403 kAsanStackUseAfterScopeMagic);
404 PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic);
405 PrintShadowByte(str, " Global init order: ",
406 kAsanInitializationOrderMagic);
407 PrintShadowByte(str, " Poisoned by user: ",
408 kAsanUserPoisonedMemoryMagic);
409 PrintShadowByte(str, " Container overflow: ",
410 kAsanContiguousContainerOOBMagic);
411 PrintShadowByte(str, " Array cookie: ",
412 kAsanArrayCookieMagic);
413 PrintShadowByte(str, " Intra object redzone: ",
414 kAsanIntraObjectRedzone);
415 PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic);
416 PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic);
417 PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic);
418}
419
420static void PrintShadowBytes(InternalScopedString *str, const char *before,
421 u8 *bytes, u8 *guilty, uptr n) {
422 Decorator d;
423 if (before) str->append("%s%p:", before, bytes);
424 for (uptr i = 0; i < n; i++) {
425 u8 *p = bytes + i;
426 const char *before =
427 p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
428 const char *after = p == guilty ? "]" : "";
429 PrintShadowByte(str, before, *p, after);
430 }
431 str->append("\n");
432}
433
434static void PrintShadowMemoryForAddress(uptr addr) {
435 if (!AddrIsInMem(addr)) return;
436 uptr shadow_addr = MemToShadow(addr);
437 const uptr n_bytes_per_row = 16;
438 uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
439 InternalScopedString str(4096 * 8);
440 str.append("Shadow bytes around the buggy address:\n");
441 for (int i = -5; i <= 5; i++) {
Reid Kleckner03d02a02017-10-25 16:54:12 +0000442 uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;
443 // Skip rows that would be outside the shadow range. This can happen when
444 // the user address is near the bottom, top, or shadow gap of the address
445 // space.
446 if (!AddrIsInShadow(row_shadow_addr)) continue;
Filipe Cabecinhasa8b5f5e2016-09-21 20:18:18 +0000447 const char *prefix = (i == 0) ? "=>" : " ";
Reid Kleckner03d02a02017-10-25 16:54:12 +0000448 PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,
449 n_bytes_per_row);
Filipe Cabecinhasa8b5f5e2016-09-21 20:18:18 +0000450 }
451 if (flags()->print_legend) PrintLegend(&str);
452 Printf("%s", str.data());
453}
454
455void ErrorGeneric::Print() {
456 Decorator d;
457 Printf("%s", d.Warning());
458 uptr addr = addr_description.Address();
459 Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
460 bug_descr, (void *)addr, pc, bp, sp);
Vitaly Buka36266b62017-09-11 20:55:49 +0000461 Printf("%s", d.Default());
Filipe Cabecinhasa8b5f5e2016-09-21 20:18:18 +0000462
463 char tname[128];
464 Printf("%s%s of size %zu at %p thread T%d%s%s\n", d.Access(),
465 access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
466 (void *)addr, tid,
Vitaly Buka36266b62017-09-11 20:55:49 +0000467 ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.Default());
Filipe Cabecinhasa8b5f5e2016-09-21 20:18:18 +0000468
469 scariness.Print();
470 GET_STACK_TRACE_FATAL(pc, bp);
471 stack.Print();
472
473 // Pass bug_descr because we have a special case for
474 // initialization-order-fiasco
475 addr_description.Print(bug_descr);
476 if (shadow_val == kAsanContiguousContainerOOBMagic)
477 PrintContainerOverflowHint();
478 ReportErrorSummary(bug_descr, &stack);
479 PrintShadowMemoryForAddress(addr);
480}
481
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +0000482} // namespace __asan