1 //===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CrashReason.h"
11 #include "llvm/Support/raw_ostream.h"
17 void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
19 ss << " (fault address: 0x" << std::hex << addr << ")";
23 #if defined(si_lower) && defined(si_upper)
24 void AppendBounds(std::string &str, lldb::addr_t lower_bound,
25 lldb::addr_t upper_bound, lldb::addr_t addr) {
26 llvm::raw_string_ostream stream(str);
27 if ((unsigned long)addr < lower_bound)
28 stream << ": lower bound violation ";
30 stream << ": upper bound violation ";
31 stream << "(fault address: 0x";
32 stream.write_hex(addr);
33 stream << ", lower bound: 0x";
34 stream.write_hex(lower_bound);
35 stream << ", upper bound: 0x";
36 stream.write_hex(upper_bound);
42 CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
43 assert(info.si_signo == SIGSEGV);
45 switch (info.si_code) {
48 // Some platforms will occasionally send nonstandard spurious SI_KERNEL
49 // codes. One way to get this is via unaligned SIMD loads.
50 return CrashReason::eInvalidAddress; // for lack of anything better
53 return CrashReason::eInvalidAddress;
55 return CrashReason::ePrivilegedAddress;
60 return CrashReason::eBoundViolation;
63 return CrashReason::eInvalidCrashReason;
66 CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
67 assert(info.si_signo == SIGILL);
69 switch (info.si_code) {
71 return CrashReason::eIllegalOpcode;
73 return CrashReason::eIllegalOperand;
75 return CrashReason::eIllegalAddressingMode;
77 return CrashReason::eIllegalTrap;
79 return CrashReason::ePrivilegedOpcode;
81 return CrashReason::ePrivilegedRegister;
83 return CrashReason::eCoprocessorError;
85 return CrashReason::eInternalStackError;
88 return CrashReason::eInvalidCrashReason;
91 CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
92 assert(info.si_signo == SIGFPE);
94 switch (info.si_code) {
96 return CrashReason::eIntegerDivideByZero;
98 return CrashReason::eIntegerOverflow;
100 return CrashReason::eFloatDivideByZero;
102 return CrashReason::eFloatOverflow;
104 return CrashReason::eFloatUnderflow;
106 return CrashReason::eFloatInexactResult;
108 return CrashReason::eFloatInvalidOperation;
110 return CrashReason::eFloatSubscriptRange;
113 return CrashReason::eInvalidCrashReason;
116 CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
117 assert(info.si_signo == SIGBUS);
119 switch (info.si_code) {
121 return CrashReason::eIllegalAlignment;
123 return CrashReason::eIllegalAddress;
125 return CrashReason::eHardwareError;
128 return CrashReason::eInvalidCrashReason;
132 std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
135 // make sure that siginfo_t has the bound fields available.
136 #if defined(si_lower) && defined(si_upper)
137 if (reason == CrashReason::eBoundViolation) {
138 str = "signal SIGSEGV";
139 AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower),
140 reinterpret_cast<lldb::addr_t>(info.si_upper),
141 reinterpret_cast<lldb::addr_t>(info.si_addr));
146 return GetCrashReasonString(reason,
147 reinterpret_cast<lldb::addr_t>(info.si_addr));
150 std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
155 str = "unknown crash reason";
158 case CrashReason::eInvalidAddress:
159 str = "signal SIGSEGV: invalid address";
160 AppendFaultAddr(str, fault_addr);
162 case CrashReason::ePrivilegedAddress:
163 str = "signal SIGSEGV: address access protected";
164 AppendFaultAddr(str, fault_addr);
166 case CrashReason::eBoundViolation:
167 str = "signal SIGSEGV: bound violation";
169 case CrashReason::eIllegalOpcode:
170 str = "signal SIGILL: illegal instruction";
172 case CrashReason::eIllegalOperand:
173 str = "signal SIGILL: illegal instruction operand";
175 case CrashReason::eIllegalAddressingMode:
176 str = "signal SIGILL: illegal addressing mode";
178 case CrashReason::eIllegalTrap:
179 str = "signal SIGILL: illegal trap";
181 case CrashReason::ePrivilegedOpcode:
182 str = "signal SIGILL: privileged instruction";
184 case CrashReason::ePrivilegedRegister:
185 str = "signal SIGILL: privileged register";
187 case CrashReason::eCoprocessorError:
188 str = "signal SIGILL: coprocessor error";
190 case CrashReason::eInternalStackError:
191 str = "signal SIGILL: internal stack error";
193 case CrashReason::eIllegalAlignment:
194 str = "signal SIGBUS: illegal alignment";
196 case CrashReason::eIllegalAddress:
197 str = "signal SIGBUS: illegal address";
199 case CrashReason::eHardwareError:
200 str = "signal SIGBUS: hardware error";
202 case CrashReason::eIntegerDivideByZero:
203 str = "signal SIGFPE: integer divide by zero";
205 case CrashReason::eIntegerOverflow:
206 str = "signal SIGFPE: integer overflow";
208 case CrashReason::eFloatDivideByZero:
209 str = "signal SIGFPE: floating point divide by zero";
211 case CrashReason::eFloatOverflow:
212 str = "signal SIGFPE: floating point overflow";
214 case CrashReason::eFloatUnderflow:
215 str = "signal SIGFPE: floating point underflow";
217 case CrashReason::eFloatInexactResult:
218 str = "signal SIGFPE: inexact floating point result";
220 case CrashReason::eFloatInvalidOperation:
221 str = "signal SIGFPE: invalid floating point operation";
223 case CrashReason::eFloatSubscriptRange:
224 str = "signal SIGFPE: invalid floating point subscript range";
231 const char *CrashReasonAsString(CrashReason reason) {
232 #ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
233 // Just return the code in ascii for integration builds.
235 sprintf(str, "%d", reason);
237 const char *str = nullptr;
240 case CrashReason::eInvalidCrashReason:
241 str = "eInvalidCrashReason";
244 // SIGSEGV crash reasons.
245 case CrashReason::eInvalidAddress:
246 str = "eInvalidAddress";
248 case CrashReason::ePrivilegedAddress:
249 str = "ePrivilegedAddress";
251 case CrashReason::eBoundViolation:
252 str = "eBoundViolation";
255 // SIGILL crash reasons.
256 case CrashReason::eIllegalOpcode:
257 str = "eIllegalOpcode";
259 case CrashReason::eIllegalOperand:
260 str = "eIllegalOperand";
262 case CrashReason::eIllegalAddressingMode:
263 str = "eIllegalAddressingMode";
265 case CrashReason::eIllegalTrap:
266 str = "eIllegalTrap";
268 case CrashReason::ePrivilegedOpcode:
269 str = "ePrivilegedOpcode";
271 case CrashReason::ePrivilegedRegister:
272 str = "ePrivilegedRegister";
274 case CrashReason::eCoprocessorError:
275 str = "eCoprocessorError";
277 case CrashReason::eInternalStackError:
278 str = "eInternalStackError";
281 // SIGBUS crash reasons:
282 case CrashReason::eIllegalAlignment:
283 str = "eIllegalAlignment";
285 case CrashReason::eIllegalAddress:
286 str = "eIllegalAddress";
288 case CrashReason::eHardwareError:
289 str = "eHardwareError";
292 // SIGFPE crash reasons:
293 case CrashReason::eIntegerDivideByZero:
294 str = "eIntegerDivideByZero";
296 case CrashReason::eIntegerOverflow:
297 str = "eIntegerOverflow";
299 case CrashReason::eFloatDivideByZero:
300 str = "eFloatDivideByZero";
302 case CrashReason::eFloatOverflow:
303 str = "eFloatOverflow";
305 case CrashReason::eFloatUnderflow:
306 str = "eFloatUnderflow";
308 case CrashReason::eFloatInexactResult:
309 str = "eFloatInexactResult";
311 case CrashReason::eFloatInvalidOperation:
312 str = "eFloatInvalidOperation";
314 case CrashReason::eFloatSubscriptRange:
315 str = "eFloatSubscriptRange";
323 CrashReason GetCrashReason(const siginfo_t &info) {
324 switch (info.si_signo) {
326 return GetCrashReasonForSIGSEGV(info);
328 return GetCrashReasonForSIGBUS(info);
330 return GetCrashReasonForSIGFPE(info);
332 return GetCrashReasonForSIGILL(info);
335 assert(false && "unexpected signal");
336 return CrashReason::eInvalidCrashReason;