annotate libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 //===-- sanitizer_symbolizer_report.cpp -----------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 /// This file is shared between AddressSanitizer and other sanitizer run-time
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 /// libraries and implements symbolized reports related functions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "sanitizer_common.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "sanitizer_file.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "sanitizer_flags.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "sanitizer_procmaps.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "sanitizer_report_decorator.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "sanitizer_stacktrace.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "sanitizer_stacktrace_printer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "sanitizer_symbolizer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #if SANITIZER_POSIX
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 # include "sanitizer_posix.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 # include <sys/mman.h>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 namespace __sanitizer {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #if !SANITIZER_GO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 void ReportErrorSummary(const char *error_type, const AddressInfo &info,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 const char *alt_tool_name) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 if (!common_flags()->print_summary) return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 InternalScopedString buff(kMaxSummaryLength);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 buff.append("%s ", error_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 common_flags()->strip_path_prefix);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 ReportErrorSummary(buff.data(), alt_tool_name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 #if !SANITIZER_FUCHSIA
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 bool ReportFile::SupportsColors() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 SpinMutexLock l(mu);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 ReopenIfNecessary();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 return SupportsColoredOutput(fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 static INLINE bool ReportSupportsColors() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 return report_file.SupportsColors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 #else // SANITIZER_FUCHSIA
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 // Fuchsia's logs always go through post-processing that handles colorization.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 static INLINE bool ReportSupportsColors() { return true; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 #endif // !SANITIZER_FUCHSIA
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 bool ColorizeReports() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 // printing on Windows.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 if (SANITIZER_WINDOWS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 const char *flag = common_flags()->color;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 return internal_strcmp(flag, "always") == 0 ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 (internal_strcmp(flag, "auto") == 0 && ReportSupportsColors());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 void ReportErrorSummary(const char *error_type, const StackTrace *stack,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 const char *alt_tool_name) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 #if !SANITIZER_GO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 if (!common_flags()->print_summary)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 if (stack->size == 0) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 ReportErrorSummary(error_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 // Currently, we include the first stack frame into the report summary.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 ReportErrorSummary(error_type, frame->info, alt_tool_name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 frame->ClearAll();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 void ReportMmapWriteExec(int prot) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 #if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 ScopedErrorReportLock l;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 SanitizerCommonDecorator d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 InternalMmapVector<BufferedStackTrace> stack_buffer(1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 BufferedStackTrace *stack = stack_buffer.data();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 stack->Reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 uptr top = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 uptr bottom = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 GET_CALLER_PC_BP_SP;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 (void)sp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 bool fast = common_flags()->fast_unwind_on_fatal;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 if (StackTrace::WillUseFastUnwind(fast)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 GetThreadStackTopAndBottom(false, &top, &bottom);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 } else {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 stack->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 Printf("%s", d.Warning());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 Printf("%s", d.Default());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 stack->Print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 ReportErrorSummary("w-and-x-usage", stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 #if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_GO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 void StartReportDeadlySignal() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 // Write the first message using fd=2, just in case.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 // It may actually fail to write in case stderr is closed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 CatastrophicErrorWrite(SanitizerToolName, internal_strlen(SanitizerToolName));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 static const char kDeadlySignal[] = ":DEADLYSIGNAL\n";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 CatastrophicErrorWrite(kDeadlySignal, sizeof(kDeadlySignal) - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 static void MaybeReportNonExecRegion(uptr pc) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 MemoryMappedSegment segment;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 while (proc_maps.Next(&segment)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 if (pc >= segment.start && pc < segment.end && !segment.IsExecutable())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 static void PrintMemoryByte(InternalScopedString *str, const char *before,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 u8 byte) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 SanitizerCommonDecorator d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 str->append("%s%s%x%x%s ", before, d.MemoryByte(), byte >> 4, byte & 15,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 d.Default());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 static void MaybeDumpInstructionBytes(uptr pc) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 InternalScopedString str(1024);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 str.append("First 16 instruction bytes at pc: ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 if (IsAccessibleMemoryRange(pc, 16)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 for (int i = 0; i < 16; ++i) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 PrintMemoryByte(&str, "", ((u8 *)pc)[i]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 str.append("\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 } else {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 str.append("unaccessible\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 Report("%s", str.data());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 static void MaybeDumpRegisters(void *context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 if (!common_flags()->dump_registers) return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 SignalContext::DumpAllRegisters(context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 UnwindSignalStackCallbackType unwind,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 const void *unwind_context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 SanitizerCommonDecorator d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 Printf("%s", d.Warning());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 static const char kDescription[] = "stack-overflow";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 (void *)sig.bp, (void *)sig.sp, tid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 Printf("%s", d.Default());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 InternalMmapVector<BufferedStackTrace> stack_buffer(1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 BufferedStackTrace *stack = stack_buffer.data();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 stack->Reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 unwind(sig, unwind_context, stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 stack->Print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 ReportErrorSummary(kDescription, stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 UnwindSignalStackCallbackType unwind,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 const void *unwind_context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 SanitizerCommonDecorator d;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 Printf("%s", d.Warning());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 const char *description = sig.Describe();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 if (sig.is_memory_access && !sig.is_true_faulting_addr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 Report("ERROR: %s: %s on unknown address (pc %p bp %p sp %p T%d)\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 SanitizerToolName, description, (void *)sig.pc, (void *)sig.bp,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 (void *)sig.sp, tid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 (void *)sig.bp, (void *)sig.sp, tid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 Printf("%s", d.Default());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 if (sig.pc < GetPageSizeCached())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 Report("Hint: pc points to the zero page.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 if (sig.is_memory_access) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 const char *access_type =
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 sig.write_flag == SignalContext::WRITE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 ? "WRITE"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 Report("The signal is caused by a %s memory access.\n", access_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 if (!sig.is_true_faulting_addr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 Report("Hint: this fault was caused by a dereference of a high value "
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 "address (see register values below). Dissassemble the provided "
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 "pc to learn which register was used.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 else if (sig.addr < GetPageSizeCached())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 Report("Hint: address points to the zero page.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 MaybeReportNonExecRegion(sig.pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 InternalMmapVector<BufferedStackTrace> stack_buffer(1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 BufferedStackTrace *stack = stack_buffer.data();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 stack->Reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 unwind(sig, unwind_context, stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 stack->Print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 MaybeDumpInstructionBytes(sig.pc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 MaybeDumpRegisters(sig.context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 Printf("%s can not provide additional info.\n", SanitizerToolName);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 ReportErrorSummary(description, stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 void ReportDeadlySignal(const SignalContext &sig, u32 tid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 UnwindSignalStackCallbackType unwind,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 const void *unwind_context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 if (sig.IsStackOverflow())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 ReportStackOverflowImpl(sig, tid, unwind, unwind_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 ReportDeadlySignalImpl(sig, tid, unwind, unwind_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 UnwindSignalStackCallbackType unwind,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 const void *unwind_context) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 StartReportDeadlySignal();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 ScopedErrorReportLock rl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 SignalContext sig(siginfo, context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 ReportDeadlySignal(sig, tid, unwind, unwind_context);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 Report("ABORTING\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 Die();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 #endif // !SANITIZER_FUCHSIA && !SANITIZER_GO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 static atomic_uintptr_t reporting_thread = {0};
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 static StaticSpinMutex CommonSanitizerReportMutex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 ScopedErrorReportLock::ScopedErrorReportLock() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 uptr current = GetThreadSelf();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 for (;;) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 uptr expected = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 if (atomic_compare_exchange_strong(&reporting_thread, &expected, current,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 memory_order_relaxed)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 // We've claimed reporting_thread so proceed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 CommonSanitizerReportMutex.Lock();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 if (expected == current) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 // This is either asynch signal or nested error during error reporting.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 // Fail simple to avoid deadlocks in Report().
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 // Can't use Report() here because of potential deadlocks in nested
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 // signal handlers.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 CatastrophicErrorWrite(SanitizerToolName,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 internal_strlen(SanitizerToolName));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 static const char msg[] = ": nested bug in the same thread, aborting.\n";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 CatastrophicErrorWrite(msg, sizeof(msg) - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 internal__exit(common_flags()->exitcode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 internal_sched_yield();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 ScopedErrorReportLock::~ScopedErrorReportLock() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 CommonSanitizerReportMutex.Unlock();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 atomic_store_relaxed(&reporting_thread, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 void ScopedErrorReportLock::CheckLocked() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 CommonSanitizerReportMutex.CheckLocked();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 } // namespace __sanitizer