blob: 6aeb5083a36cb8b8c71ad308dc923b7e6a859a72 [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 Cabecinhas1989be72016-09-08 12:58:15 +000018#include "asan_report.h"
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +000019#include "asan_stack.h"
20
21namespace __asan {
22
23void ErrorStackOverflow::Print() {
24 Decorator d;
25 Printf("%s", d.Warning());
26 Report(
27 "ERROR: AddressSanitizer: stack-overflow on address %p"
28 " (pc %p bp %p sp %p T%d)\n",
29 (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
30 Printf("%s", d.EndWarning());
31 scariness.Print();
32 BufferedStackTrace stack;
33 GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
34 common_flags()->fast_unwind_on_fatal);
35 stack.Print();
36 ReportErrorSummary("stack-overflow", &stack);
37}
38
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000039static void MaybeDumpInstructionBytes(uptr pc) {
40 if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) return;
41 InternalScopedString str(1024);
42 str.append("First 16 instruction bytes at pc: ");
43 if (IsAccessibleMemoryRange(pc, 16)) {
44 for (int i = 0; i < 16; ++i) {
45 PrintMemoryByte(&str, "", ((u8 *)pc)[i], /*in_shadow*/ false, " ");
46 }
47 str.append("\n");
48 } else {
49 str.append("unaccessible\n");
50 }
51 Report("%s", str.data());
52}
53
54void ErrorDeadlySignal::Print() {
55 Decorator d;
56 Printf("%s", d.Warning());
57 const char *description = DescribeSignalOrException(signo);
58 Report(
59 "ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p "
60 "T%d)\n",
61 description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
62 Printf("%s", d.EndWarning());
63 if (pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n");
64 if (is_memory_access) {
65 const char *access_type =
66 write_flag == SignalContext::WRITE
67 ? "WRITE"
68 : (write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
69 Report("The signal is caused by a %s memory access.\n", access_type);
70 if (addr < GetPageSizeCached())
71 Report("Hint: address points to the zero page.\n");
72 }
73 scariness.Print();
74 BufferedStackTrace stack;
75 GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
76 common_flags()->fast_unwind_on_fatal);
77 stack.Print();
78 MaybeDumpInstructionBytes(pc);
79 Printf("AddressSanitizer can not provide additional info.\n");
80 ReportErrorSummary(description, &stack);
81}
82
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000083void ErrorDoubleFree::Print() {
84 Decorator d;
85 Printf("%s", d.Warning());
86 char tname[128];
87 Report(
88 "ERROR: AddressSanitizer: attempting double-free on %p in "
89 "thread T%d%s:\n",
90 addr_description.addr, tid,
91 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
92 Printf("%s", d.EndWarning());
Filipe Cabecinhas453b5552016-08-31 09:39:47 +000093 scariness.Print();
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000094 GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
95 second_free_stack->top_frame_bp);
96 stack.Print();
97 addr_description.Print();
98 ReportErrorSummary("double-free", &stack);
99}
100
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +0000101void ErrorNewDeleteSizeMismatch::Print() {
102 Decorator d;
103 Printf("%s", d.Warning());
104 char tname[128];
105 Report(
106 "ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
107 "T%d%s:\n",
108 addr_description.addr, tid,
109 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
110 Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
111 Printf(
112 " size of the allocated type: %zd bytes;\n"
113 " size of the deallocated type: %zd bytes.\n",
114 addr_description.chunk_access.chunk_size, delete_size);
115 CHECK_GT(free_stack->size, 0);
116 scariness.Print();
117 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
118 stack.Print();
119 addr_description.Print();
120 ReportErrorSummary("new-delete-type-mismatch", &stack);
121 Report(
122 "HINT: if you don't care about these errors you may set "
123 "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
124}
125
Filipe Cabecinhas6fb54622016-09-13 20:47:29 +0000126void ErrorFreeNotMalloced::Print() {
127 Decorator d;
128 Printf("%s", d.Warning());
129 char tname[128];
130 Report(
131 "ERROR: AddressSanitizer: attempting free on address "
132 "which was not malloc()-ed: %p in thread T%d%s\n",
133 addr_description.Address(), tid,
134 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
135 Printf("%s", d.EndWarning());
136 CHECK_GT(free_stack->size, 0);
137 scariness.Print();
138 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
139 stack.Print();
140 addr_description.Print();
141 ReportErrorSummary("bad-free", &stack);
142}
143
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000144void ErrorAllocTypeMismatch::Print() {
145 static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
146 "operator new []"};
147 static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
148 "operator delete []"};
149 CHECK_NE(alloc_type, dealloc_type);
150 Decorator d;
151 Printf("%s", d.Warning());
152 Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n",
153 alloc_names[alloc_type], dealloc_names[dealloc_type],
154 addr_description.addr);
155 Printf("%s", d.EndWarning());
156 CHECK_GT(dealloc_stack->size, 0);
157 scariness.Print();
158 GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
159 stack.Print();
160 addr_description.Print();
161 ReportErrorSummary("alloc-dealloc-mismatch", &stack);
162 Report(
163 "HINT: if you don't care about these errors you may set "
164 "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
165}
166
Filipe Cabecinhas5f862c22016-09-13 20:47:37 +0000167void ErrorMallocUsableSizeNotOwned::Print() {
168 Decorator d;
169 Printf("%s", d.Warning());
170 Report(
171 "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
172 "pointer which is not owned: %p\n",
173 addr_description.Address());
174 Printf("%s", d.EndWarning());
175 stack->Print();
176 addr_description.Print();
177 ReportErrorSummary("bad-malloc_usable_size", stack);
178}
179
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +0000180} // namespace __asan