1 //===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CrashReason.h"
12 #include "llvm/Support/raw_ostream.h"
18 void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
20 ss << " (fault address: 0x" << std::hex << addr << ")";
24 #if defined(si_lower) && defined(si_upper)
25 void AppendBounds(std::string &str, lldb::addr_t lower_bound,
26 lldb::addr_t upper_bound, lldb::addr_t addr) {
27 llvm::raw_string_ostream stream(str);
28 if ((unsigned long)addr < lower_bound)
29 stream << ": lower bound violation ";
31 stream << ": upper bound violation ";
32 stream << "(fault address: 0x";
33 stream.write_hex(addr);
34 stream << ", lower bound: 0x";
35 stream.write_hex(lower_bound);
36 stream << ", upper bound: 0x";
37 stream.write_hex(upper_bound);
43 CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
44 assert(info.si_signo == SIGSEGV);
46 switch (info.si_code) {
49 // Some platforms will occasionally send nonstandard spurious SI_KERNEL
51 // One way to get this is via unaligned SIMD loads.
52 return CrashReason::eInvalidAddress; // for lack of anything better
55 return CrashReason::eInvalidAddress;
57 return CrashReason::ePrivilegedAddress;
62 return CrashReason::eBoundViolation;
65 assert(false && "unexpected si_code for SIGSEGV");
66 return CrashReason::eInvalidCrashReason;
69 CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
70 assert(info.si_signo == SIGILL);
72 switch (info.si_code) {
74 return CrashReason::eIllegalOpcode;
76 return CrashReason::eIllegalOperand;
78 return CrashReason::eIllegalAddressingMode;
80 return CrashReason::eIllegalTrap;
82 return CrashReason::ePrivilegedOpcode;
84 return CrashReason::ePrivilegedRegister;
86 return CrashReason::eCoprocessorError;
88 return CrashReason::eInternalStackError;
91 assert(false && "unexpected si_code for SIGILL");
92 return CrashReason::eInvalidCrashReason;
95 CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
96 assert(info.si_signo == SIGFPE);
98 switch (info.si_code) {
100 return CrashReason::eIntegerDivideByZero;
102 return CrashReason::eIntegerOverflow;
104 return CrashReason::eFloatDivideByZero;
106 return CrashReason::eFloatOverflow;
108 return CrashReason::eFloatUnderflow;
110 return CrashReason::eFloatInexactResult;
112 return CrashReason::eFloatInvalidOperation;
114 return CrashReason::eFloatSubscriptRange;
117 assert(false && "unexpected si_code for SIGFPE");
118 return CrashReason::eInvalidCrashReason;
121 CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
122 assert(info.si_signo == SIGBUS);
124 switch (info.si_code) {
126 return CrashReason::eIllegalAlignment;
128 return CrashReason::eIllegalAddress;
130 return CrashReason::eHardwareError;
133 assert(false && "unexpected si_code for SIGBUS");
134 return CrashReason::eInvalidCrashReason;
138 std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
141 // make sure that siginfo_t has the bound fields available.
142 #if defined(si_lower) && defined(si_upper)
143 if (reason == CrashReason::eBoundViolation) {
144 str = "signal SIGSEGV";
145 AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower),
146 reinterpret_cast<lldb::addr_t>(info.si_upper),
147 reinterpret_cast<lldb::addr_t>(info.si_addr));
152 return GetCrashReasonString(reason,
153 reinterpret_cast<lldb::addr_t>(info.si_addr));
156 std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
161 assert(false && "invalid CrashReason");
164 case CrashReason::eInvalidAddress:
165 str = "signal SIGSEGV: invalid address";
166 AppendFaultAddr(str, fault_addr);
168 case CrashReason::ePrivilegedAddress:
169 str = "signal SIGSEGV: address access protected";
170 AppendFaultAddr(str, fault_addr);
172 case CrashReason::eBoundViolation:
173 str = "signal SIGSEGV: bound violation";
175 case CrashReason::eIllegalOpcode:
176 str = "signal SIGILL: illegal instruction";
178 case CrashReason::eIllegalOperand:
179 str = "signal SIGILL: illegal instruction operand";
181 case CrashReason::eIllegalAddressingMode:
182 str = "signal SIGILL: illegal addressing mode";
184 case CrashReason::eIllegalTrap:
185 str = "signal SIGILL: illegal trap";
187 case CrashReason::ePrivilegedOpcode:
188 str = "signal SIGILL: privileged instruction";
190 case CrashReason::ePrivilegedRegister:
191 str = "signal SIGILL: privileged register";
193 case CrashReason::eCoprocessorError:
194 str = "signal SIGILL: coprocessor error";
196 case CrashReason::eInternalStackError:
197 str = "signal SIGILL: internal stack error";
199 case CrashReason::eIllegalAlignment:
200 str = "signal SIGBUS: illegal alignment";
202 case CrashReason::eIllegalAddress:
203 str = "signal SIGBUS: illegal address";
205 case CrashReason::eHardwareError:
206 str = "signal SIGBUS: hardware error";
208 case CrashReason::eIntegerDivideByZero:
209 str = "signal SIGFPE: integer divide by zero";
211 case CrashReason::eIntegerOverflow:
212 str = "signal SIGFPE: integer overflow";
214 case CrashReason::eFloatDivideByZero:
215 str = "signal SIGFPE: floating point divide by zero";
217 case CrashReason::eFloatOverflow:
218 str = "signal SIGFPE: floating point overflow";
220 case CrashReason::eFloatUnderflow:
221 str = "signal SIGFPE: floating point underflow";
223 case CrashReason::eFloatInexactResult:
224 str = "signal SIGFPE: inexact floating point result";
226 case CrashReason::eFloatInvalidOperation:
227 str = "signal SIGFPE: invalid floating point operation";
229 case CrashReason::eFloatSubscriptRange:
230 str = "signal SIGFPE: invalid floating point subscript range";
237 const char *CrashReasonAsString(CrashReason reason) {
238 #ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
239 // Just return the code in ascii for integration builds.
241 sprintf(str, "%d", reason);
243 const char *str = nullptr;
246 case CrashReason::eInvalidCrashReason:
247 str = "eInvalidCrashReason";
250 // SIGSEGV crash reasons.
251 case CrashReason::eInvalidAddress:
252 str = "eInvalidAddress";
254 case CrashReason::ePrivilegedAddress:
255 str = "ePrivilegedAddress";
257 case CrashReason::eBoundViolation:
258 str = "eBoundViolation";
261 // SIGILL crash reasons.
262 case CrashReason::eIllegalOpcode:
263 str = "eIllegalOpcode";
265 case CrashReason::eIllegalOperand:
266 str = "eIllegalOperand";
268 case CrashReason::eIllegalAddressingMode:
269 str = "eIllegalAddressingMode";
271 case CrashReason::eIllegalTrap:
272 str = "eIllegalTrap";
274 case CrashReason::ePrivilegedOpcode:
275 str = "ePrivilegedOpcode";
277 case CrashReason::ePrivilegedRegister:
278 str = "ePrivilegedRegister";
280 case CrashReason::eCoprocessorError:
281 str = "eCoprocessorError";
283 case CrashReason::eInternalStackError:
284 str = "eInternalStackError";
287 // SIGBUS crash reasons:
288 case CrashReason::eIllegalAlignment:
289 str = "eIllegalAlignment";
291 case CrashReason::eIllegalAddress:
292 str = "eIllegalAddress";
294 case CrashReason::eHardwareError:
295 str = "eHardwareError";
298 // SIGFPE crash reasons:
299 case CrashReason::eIntegerDivideByZero:
300 str = "eIntegerDivideByZero";
302 case CrashReason::eIntegerOverflow:
303 str = "eIntegerOverflow";
305 case CrashReason::eFloatDivideByZero:
306 str = "eFloatDivideByZero";
308 case CrashReason::eFloatOverflow:
309 str = "eFloatOverflow";
311 case CrashReason::eFloatUnderflow:
312 str = "eFloatUnderflow";
314 case CrashReason::eFloatInexactResult:
315 str = "eFloatInexactResult";
317 case CrashReason::eFloatInvalidOperation:
318 str = "eFloatInvalidOperation";
320 case CrashReason::eFloatSubscriptRange:
321 str = "eFloatSubscriptRange";
329 CrashReason GetCrashReason(const siginfo_t &info) {
330 switch (info.si_signo) {
332 return GetCrashReasonForSIGSEGV(info);
334 return GetCrashReasonForSIGBUS(info);
336 return GetCrashReasonForSIGFPE(info);
338 return GetCrashReasonForSIGILL(info);
341 assert(false && "unexpected signal");
342 return CrashReason::eInvalidCrashReason;