LLDB  mainline
CrashReason.cpp
Go to the documentation of this file.
1 //===-- CrashReason.cpp ---------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "CrashReason.h"
10 
11 #include "llvm/Support/raw_ostream.h"
12 
13 #include <sstream>
14 
15 namespace {
16 
17 void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
18  std::stringstream ss;
19  ss << " (fault address: 0x" << std::hex << addr << ")";
20  str += ss.str();
21 }
22 
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 ";
29  else
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);
37  stream << ")";
38  stream.flush();
39 }
40 #endif
41 
42 CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
43  assert(info.si_signo == SIGSEGV);
44 
45  switch (info.si_code) {
46 #ifdef SI_KERNEL
47  case SI_KERNEL:
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
51 #endif
52  case SEGV_MAPERR:
54  case SEGV_ACCERR:
56 #ifndef SEGV_BNDERR
57 #define SEGV_BNDERR 3
58 #endif
59  case SEGV_BNDERR:
61 #ifdef __linux__
62 #ifndef SEGV_MTEAERR
63 #define SEGV_MTEAERR 8
64 #endif
65  case SEGV_MTEAERR:
67 #ifndef SEGV_MTESERR
68 #define SEGV_MTESERR 9
69 #endif
70  case SEGV_MTESERR:
72 #endif // __linux__
73  }
74 
76 }
77 
78 CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
79  assert(info.si_signo == SIGILL);
80 
81  switch (info.si_code) {
82  case ILL_ILLOPC:
84  case ILL_ILLOPN:
86  case ILL_ILLADR:
88  case ILL_ILLTRP:
90  case ILL_PRVOPC:
92  case ILL_PRVREG:
94  case ILL_COPROC:
96  case ILL_BADSTK:
98  }
99 
101 }
102 
103 CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
104  assert(info.si_signo == SIGFPE);
105 
106  switch (info.si_code) {
107  case FPE_INTDIV:
109  case FPE_INTOVF:
111  case FPE_FLTDIV:
113  case FPE_FLTOVF:
115  case FPE_FLTUND:
117  case FPE_FLTRES:
119  case FPE_FLTINV:
121  case FPE_FLTSUB:
123  }
124 
126 }
127 
128 CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
129  assert(info.si_signo == SIGBUS);
130 
131  switch (info.si_code) {
132  case BUS_ADRALN:
134  case BUS_ADRERR:
136  case BUS_OBJERR:
138  }
139 
141 }
142 }
143 
144 std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
145  std::string str;
146 
147 // make sure that siginfo_t has the bound fields available.
148 #if defined(si_lower) && defined(si_upper)
149  if (reason == CrashReason::eBoundViolation) {
150  str = "signal SIGSEGV";
151  AppendBounds(str, reinterpret_cast<uintptr_t>(info.si_lower),
152  reinterpret_cast<uintptr_t>(info.si_upper),
153  reinterpret_cast<uintptr_t>(info.si_addr));
154  return str;
155  }
156 #endif
157 
158  return GetCrashReasonString(reason,
159  reinterpret_cast<uintptr_t>(info.si_addr));
160 }
161 
163  std::string str;
164 
165  switch (reason) {
166  default:
167  str = "unknown crash reason";
168  break;
169 
171  str = "signal SIGSEGV: invalid address";
172  AppendFaultAddr(str, fault_addr);
173  break;
175  str = "signal SIGSEGV: address access protected";
176  AppendFaultAddr(str, fault_addr);
177  break;
179  str = "signal SIGSEGV: bound violation";
180  break;
182  str = "signal SIGSEGV: async tag check fault";
183  break;
185  str = "signal SIGSEGV: sync tag check fault";
186  AppendFaultAddr(str, fault_addr);
187  break;
189  str = "signal SIGILL: illegal instruction";
190  break;
192  str = "signal SIGILL: illegal instruction operand";
193  break;
195  str = "signal SIGILL: illegal addressing mode";
196  break;
198  str = "signal SIGILL: illegal trap";
199  break;
201  str = "signal SIGILL: privileged instruction";
202  break;
204  str = "signal SIGILL: privileged register";
205  break;
207  str = "signal SIGILL: coprocessor error";
208  break;
210  str = "signal SIGILL: internal stack error";
211  break;
213  str = "signal SIGBUS: illegal alignment";
214  break;
216  str = "signal SIGBUS: illegal address";
217  break;
219  str = "signal SIGBUS: hardware error";
220  break;
222  str = "signal SIGFPE: integer divide by zero";
223  break;
225  str = "signal SIGFPE: integer overflow";
226  break;
228  str = "signal SIGFPE: floating point divide by zero";
229  break;
231  str = "signal SIGFPE: floating point overflow";
232  break;
234  str = "signal SIGFPE: floating point underflow";
235  break;
237  str = "signal SIGFPE: inexact floating point result";
238  break;
240  str = "signal SIGFPE: invalid floating point operation";
241  break;
243  str = "signal SIGFPE: invalid floating point subscript range";
244  break;
245  }
246 
247  return str;
248 }
249 
250 const char *CrashReasonAsString(CrashReason reason) {
251  const char *str = nullptr;
252 
253  switch (reason) {
255  str = "eInvalidCrashReason";
256  break;
257 
258  // SIGSEGV crash reasons.
260  str = "eInvalidAddress";
261  break;
263  str = "ePrivilegedAddress";
264  break;
266  str = "eBoundViolation";
267  break;
269  str = "eAsyncTagCheckFault";
270  break;
272  str = "eSyncTagCheckFault";
273  break;
274 
275  // SIGILL crash reasons.
277  str = "eIllegalOpcode";
278  break;
280  str = "eIllegalOperand";
281  break;
283  str = "eIllegalAddressingMode";
284  break;
286  str = "eIllegalTrap";
287  break;
289  str = "ePrivilegedOpcode";
290  break;
292  str = "ePrivilegedRegister";
293  break;
295  str = "eCoprocessorError";
296  break;
298  str = "eInternalStackError";
299  break;
300 
301  // SIGBUS crash reasons:
303  str = "eIllegalAlignment";
304  break;
306  str = "eIllegalAddress";
307  break;
309  str = "eHardwareError";
310  break;
311 
312  // SIGFPE crash reasons:
314  str = "eIntegerDivideByZero";
315  break;
317  str = "eIntegerOverflow";
318  break;
320  str = "eFloatDivideByZero";
321  break;
323  str = "eFloatOverflow";
324  break;
326  str = "eFloatUnderflow";
327  break;
329  str = "eFloatInexactResult";
330  break;
332  str = "eFloatInvalidOperation";
333  break;
335  str = "eFloatSubscriptRange";
336  break;
337  }
338  return str;
339 }
340 
341 CrashReason GetCrashReason(const siginfo_t &info) {
342  switch (info.si_signo) {
343  case SIGSEGV:
344  return GetCrashReasonForSIGSEGV(info);
345  case SIGBUS:
346  return GetCrashReasonForSIGBUS(info);
347  case SIGFPE:
348  return GetCrashReasonForSIGFPE(info);
349  case SIGILL:
350  return GetCrashReasonForSIGILL(info);
351  }
352 
353  assert(false && "unexpected signal");
355 }
CrashReason::eAsyncTagCheckFault
@ eAsyncTagCheckFault
CrashReason::eCoprocessorError
@ eCoprocessorError
CrashReason::eIllegalOperand
@ eIllegalOperand
CrashReason::eIntegerOverflow
@ eIntegerOverflow
CrashReason::ePrivilegedAddress
@ ePrivilegedAddress
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
CrashReason::eIllegalTrap
@ eIllegalTrap
CrashReason::eIllegalAlignment
@ eIllegalAlignment
CrashReason::eIllegalOpcode
@ eIllegalOpcode
CrashReason::eInvalidCrashReason
@ eInvalidCrashReason
CrashReason::eFloatUnderflow
@ eFloatUnderflow
CrashReason::eSyncTagCheckFault
@ eSyncTagCheckFault
CrashReason::eInvalidAddress
@ eInvalidAddress
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
CrashReason::eFloatInexactResult
@ eFloatInexactResult
CrashReason::ePrivilegedRegister
@ ePrivilegedRegister
CrashReason::eHardwareError
@ eHardwareError
GetCrashReasonString
std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info)
Definition: CrashReason.cpp:144
CrashReason::ePrivilegedOpcode
@ ePrivilegedOpcode
SEGV_BNDERR
#define SEGV_BNDERR
CrashReason::eFloatSubscriptRange
@ eFloatSubscriptRange
CrashReason::eFloatDivideByZero
@ eFloatDivideByZero
CrashReason::eBoundViolation
@ eBoundViolation
CrashReason::eIllegalAddressingMode
@ eIllegalAddressingMode
CrashReason::eInternalStackError
@ eInternalStackError
CrashReason
CrashReason
Definition: CrashReason.h:18
CrashReason::eFloatInvalidOperation
@ eFloatInvalidOperation
CrashReasonAsString
const char * CrashReasonAsString(CrashReason reason)
Definition: CrashReason.cpp:250
CrashReason::eIntegerDivideByZero
@ eIntegerDivideByZero
CrashReason::eIllegalAddress
@ eIllegalAddress
CrashReason::eFloatOverflow
@ eFloatOverflow
CrashReason.h
GetCrashReason
CrashReason GetCrashReason(const siginfo_t &info)
Definition: CrashReason.cpp:341