blob: 78d734e2125bc5505f98b995854ae832659625c1 [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 Cabecinhasb0de43a2016-09-13 20:47:42 +0000180void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
181 Decorator d;
182 Printf("%s", d.Warning());
183 Report(
184 "ERROR: AddressSanitizer: attempting to call "
185 "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
186 addr_description.Address());
187 Printf("%s", d.EndWarning());
188 stack->Print();
189 addr_description.Print();
190 ReportErrorSummary("bad-__sanitizer_get_allocated_size", stack);
191}
192
Filipe Cabecinhas7a196b92016-09-14 07:37:14 +0000193void ErrorStringFunctionMemoryRangesOverlap::Print() {
194 Decorator d;
195 char bug_type[100];
196 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
197 Printf("%s", d.Warning());
198 Report(
199 "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
200 "overlap\n",
201 bug_type, addr1_description.Address(),
202 addr1_description.Address() + length1, addr2_description.Address(),
203 addr2_description.Address() + length2);
204 Printf("%s", d.EndWarning());
205 scariness.Print();
206 stack->Print();
207 addr1_description.Print();
208 addr2_description.Print();
209 ReportErrorSummary(bug_type, stack);
210}
211
Filipe Cabecinhasfddfdca2016-08-30 17:08:55 +0000212} // namespace __asan