blob: 18bbaefec639df1fb55f3b4b070b7812098ce5c3 [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"
21
22namespace __asan {
23
24void ErrorStackOverflow::Print() {
25 Decorator d;
26 Printf("%s", d.Warning());
27 Report(
28 "ERROR: AddressSanitizer: stack-overflow on address %p"
29 " (pc %p bp %p sp %p T%d)\n",
30 (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
31 Printf("%s", d.EndWarning());
32 scariness.Print();
33 BufferedStackTrace stack;
34 GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
35 common_flags()->fast_unwind_on_fatal);
36 stack.Print();
37 ReportErrorSummary("stack-overflow", &stack);
38}
39
Filipe Cabecinhas1989be72016-09-08 12:58:15 +000040static void MaybeDumpInstructionBytes(uptr pc) {
41 if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) return;
42 InternalScopedString str(1024);
43 str.append("First 16 instruction bytes at pc: ");
44 if (IsAccessibleMemoryRange(pc, 16)) {
45 for (int i = 0; i < 16; ++i) {
46 PrintMemoryByte(&str, "", ((u8 *)pc)[i], /*in_shadow*/ false, " ");
47 }
48 str.append("\n");
49 } else {
50 str.append("unaccessible\n");
51 }
52 Report("%s", str.data());
53}
54
55void ErrorDeadlySignal::Print() {
56 Decorator d;
57 Printf("%s", d.Warning());
58 const char *description = DescribeSignalOrException(signo);
59 Report(
60 "ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p "
61 "T%d)\n",
62 description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
63 Printf("%s", d.EndWarning());
64 if (pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n");
65 if (is_memory_access) {
66 const char *access_type =
67 write_flag == SignalContext::WRITE
68 ? "WRITE"
69 : (write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
70 Report("The signal is caused by a %s memory access.\n", access_type);
71 if (addr < GetPageSizeCached())
72 Report("Hint: address points to the zero page.\n");
73 }
74 scariness.Print();
75 BufferedStackTrace stack;
76 GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
77 common_flags()->fast_unwind_on_fatal);
78 stack.Print();
79 MaybeDumpInstructionBytes(pc);
80 Printf("AddressSanitizer can not provide additional info.\n");
81 ReportErrorSummary(description, &stack);
82}
83
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000084void ErrorDoubleFree::Print() {
85 Decorator d;
86 Printf("%s", d.Warning());
87 char tname[128];
88 Report(
89 "ERROR: AddressSanitizer: attempting double-free on %p in "
90 "thread T%d%s:\n",
91 addr_description.addr, tid,
92 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
93 Printf("%s", d.EndWarning());
Filipe Cabecinhas453b5552016-08-31 09:39:47 +000094 scariness.Print();
Filipe Cabecinhasb16672d2016-08-31 07:38:09 +000095 GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
96 second_free_stack->top_frame_bp);
97 stack.Print();
98 addr_description.Print();
99 ReportErrorSummary("double-free", &stack);
100}
101
Filipe Cabecinhas25ad7b52016-09-07 14:20:54 +0000102void ErrorNewDeleteSizeMismatch::Print() {
103 Decorator d;
104 Printf("%s", d.Warning());
105 char tname[128];
106 Report(
107 "ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
108 "T%d%s:\n",
109 addr_description.addr, tid,
110 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
111 Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
112 Printf(
113 " size of the allocated type: %zd bytes;\n"
114 " size of the deallocated type: %zd bytes.\n",
115 addr_description.chunk_access.chunk_size, delete_size);
116 CHECK_GT(free_stack->size, 0);
117 scariness.Print();
118 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
119 stack.Print();
120 addr_description.Print();
121 ReportErrorSummary("new-delete-type-mismatch", &stack);
122 Report(
123 "HINT: if you don't care about these errors you may set "
124 "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
125}
126
Filipe Cabecinhas6fb54622016-09-13 20:47:29 +0000127void ErrorFreeNotMalloced::Print() {
128 Decorator d;
129 Printf("%s", d.Warning());
130 char tname[128];
131 Report(
132 "ERROR: AddressSanitizer: attempting free on address "
133 "which was not malloc()-ed: %p in thread T%d%s\n",
134 addr_description.Address(), tid,
135 ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
136 Printf("%s", d.EndWarning());
137 CHECK_GT(free_stack->size, 0);
138 scariness.Print();
139 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
140 stack.Print();
141 addr_description.Print();
142 ReportErrorSummary("bad-free", &stack);
143}
144
Filipe Cabecinhas92c5b5d2016-09-13 20:47:33 +0000145void ErrorAllocTypeMismatch::Print() {
146 static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
147 "operator new []"};
148 static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
149 "operator delete []"};
150 CHECK_NE(alloc_type, dealloc_type);
151 Decorator d;
152 Printf("%s", d.Warning());
153 Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n",
154 alloc_names[alloc_type], dealloc_names[dealloc_type],
155 addr_description.addr);
156 Printf("%s", d.EndWarning());
157 CHECK_GT(dealloc_stack->size, 0);
158 scariness.Print();
159 GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
160 stack.Print();
161 addr_description.Print();
162 ReportErrorSummary("alloc-dealloc-mismatch", &stack);
163 Report(
164 "HINT: if you don't care about these errors you may set "
165 "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
166}
167
Filipe Cabecinhas5f862c22016-09-13 20:47:37 +0000168void ErrorMallocUsableSizeNotOwned::Print() {
169 Decorator d;
170 Printf("%s", d.Warning());
171 Report(
172 "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
173 "pointer which is not owned: %p\n",
174 addr_description.Address());
175 Printf("%s", d.EndWarning());
176 stack->Print();
177 addr_description.Print();
178 ReportErrorSummary("bad-malloc_usable_size", stack);
179}
180
Filipe Cabecinhasb0de43a2016-09-13 20:47:42 +0000181void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
182 Decorator d;
183 Printf("%s", d.Warning());
184 Report(
185 "ERROR: AddressSanitizer: attempting to call "
186 "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
187 addr_description.Address());
188 Printf("%s", d.EndWarning());
189 stack->Print();
190 addr_description.Print();
191 ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack);
192}
193
Filipe Cabecinhas7a196b92016-09-14 07:37:14 +0000194void ErrorStringFunctionMemoryRangesOverlap::Print() {
195 Decorator d;
196 char bug_type[100];
197 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
198 Printf("%s", d.Warning());
199 Report(
200 "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
201 "overlap\n",
202 bug_type, addr1_description.Address(),
203 addr1_description.Address() + length1, addr2_description.Address(),
204 addr2_description.Address() + length2);
205 Printf("%s", d.EndWarning());
206 scariness.Print();
207 stack->Print();
208 addr1_description.Print();
209 addr2_description.Print();
210 ReportErrorSummary(bug_type, stack);
211}
212
Filipe Cabecinhas36229e92016-09-14 07:37:20 +0000213void ErrorStringFunctionSizeOverflow::Print() {
214 Decorator d;
215 Printf("%s", d.Warning());
216 const char *bug_type = "negative-size-param";
217 Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
218 Printf("%s", d.EndWarning());
219 scariness.Print();
220 stack->Print();
221 addr_description.Print();
222 ReportErrorSummary(bug_type, stack);
223}
224
Filipe Cabecinhasb50a5b32016-09-15 08:10:48 +0000225void ErrorBadParamsToAnnotateContiguousContainer::Print() {
226 Report(
227 "ERROR: AddressSanitizer: bad parameters to "
228 "__sanitizer_annotate_contiguous_container:\n"
229 " beg : %p\n"
230 " end : %p\n"
231 " old_mid : %p\n"
232 " new_mid : %p\n",
233 beg, end, old_mid, new_mid);
234 uptr granularity = SHADOW_GRANULARITY;
235 if (!IsAligned(beg, granularity))
236 Report("ERROR: beg is not aligned by %d\n", granularity);
237 stack->Print();
238 ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
239}
240
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +0000241} // namespace __asan