1 //===-- CrashReason.cpp -----------------------------------------*- 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 #include "CrashReason.h" 11 12 #include <sstream> 13 14 namespace { 15 16 void AppendFaultAddr(std::string &str, lldb::addr_t addr) { 17 std::stringstream ss; 18 ss << " (fault address: 0x" << std::hex << addr << ")"; 19 str += ss.str(); 20 } 21 22 CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) { 23 assert(info.si_signo == SIGSEGV); 24 25 switch (info.si_code) { 26 #ifdef SI_KERNEL 27 case SI_KERNEL: 28 // Some platforms will occasionally send nonstandard spurious SI_KERNEL 29 // codes. 30 // One way to get this is via unaligned SIMD loads. 31 return CrashReason::eInvalidAddress; // for lack of anything better 32 #endif 33 case SEGV_MAPERR: 34 return CrashReason::eInvalidAddress; 35 case SEGV_ACCERR: 36 return CrashReason::ePrivilegedAddress; 37 } 38 39 assert(false && "unexpected si_code for SIGSEGV"); 40 return CrashReason::eInvalidCrashReason; 41 } 42 43 CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) { 44 assert(info.si_signo == SIGILL); 45 46 switch (info.si_code) { 47 case ILL_ILLOPC: 48 return CrashReason::eIllegalOpcode; 49 case ILL_ILLOPN: 50 return CrashReason::eIllegalOperand; 51 case ILL_ILLADR: 52 return CrashReason::eIllegalAddressingMode; 53 case ILL_ILLTRP: 54 return CrashReason::eIllegalTrap; 55 case ILL_PRVOPC: 56 return CrashReason::ePrivilegedOpcode; 57 case ILL_PRVREG: 58 return CrashReason::ePrivilegedRegister; 59 case ILL_COPROC: 60 return CrashReason::eCoprocessorError; 61 case ILL_BADSTK: 62 return CrashReason::eInternalStackError; 63 } 64 65 assert(false && "unexpected si_code for SIGILL"); 66 return CrashReason::eInvalidCrashReason; 67 } 68 69 CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) { 70 assert(info.si_signo == SIGFPE); 71 72 switch (info.si_code) { 73 case FPE_INTDIV: 74 return CrashReason::eIntegerDivideByZero; 75 case FPE_INTOVF: 76 return CrashReason::eIntegerOverflow; 77 case FPE_FLTDIV: 78 return CrashReason::eFloatDivideByZero; 79 case FPE_FLTOVF: 80 return CrashReason::eFloatOverflow; 81 case FPE_FLTUND: 82 return CrashReason::eFloatUnderflow; 83 case FPE_FLTRES: 84 return CrashReason::eFloatInexactResult; 85 case FPE_FLTINV: 86 return CrashReason::eFloatInvalidOperation; 87 case FPE_FLTSUB: 88 return CrashReason::eFloatSubscriptRange; 89 } 90 91 assert(false && "unexpected si_code for SIGFPE"); 92 return CrashReason::eInvalidCrashReason; 93 } 94 95 CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) { 96 assert(info.si_signo == SIGBUS); 97 98 switch (info.si_code) { 99 case BUS_ADRALN: 100 return CrashReason::eIllegalAlignment; 101 case BUS_ADRERR: 102 return CrashReason::eIllegalAddress; 103 case BUS_OBJERR: 104 return CrashReason::eHardwareError; 105 } 106 107 assert(false && "unexpected si_code for SIGBUS"); 108 return CrashReason::eInvalidCrashReason; 109 } 110 } 111 112 std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { 113 std::string str; 114 115 switch (reason) { 116 default: 117 assert(false && "invalid CrashReason"); 118 break; 119 120 case CrashReason::eInvalidAddress: 121 str = "signal SIGSEGV: invalid address"; 122 AppendFaultAddr(str, fault_addr); 123 break; 124 case CrashReason::ePrivilegedAddress: 125 str = "signal SIGSEGV: address access protected"; 126 AppendFaultAddr(str, fault_addr); 127 break; 128 case CrashReason::eIllegalOpcode: 129 str = "signal SIGILL: illegal instruction"; 130 break; 131 case CrashReason::eIllegalOperand: 132 str = "signal SIGILL: illegal instruction operand"; 133 break; 134 case CrashReason::eIllegalAddressingMode: 135 str = "signal SIGILL: illegal addressing mode"; 136 break; 137 case CrashReason::eIllegalTrap: 138 str = "signal SIGILL: illegal trap"; 139 break; 140 case CrashReason::ePrivilegedOpcode: 141 str = "signal SIGILL: privileged instruction"; 142 break; 143 case CrashReason::ePrivilegedRegister: 144 str = "signal SIGILL: privileged register"; 145 break; 146 case CrashReason::eCoprocessorError: 147 str = "signal SIGILL: coprocessor error"; 148 break; 149 case CrashReason::eInternalStackError: 150 str = "signal SIGILL: internal stack error"; 151 break; 152 case CrashReason::eIllegalAlignment: 153 str = "signal SIGBUS: illegal alignment"; 154 break; 155 case CrashReason::eIllegalAddress: 156 str = "signal SIGBUS: illegal address"; 157 break; 158 case CrashReason::eHardwareError: 159 str = "signal SIGBUS: hardware error"; 160 break; 161 case CrashReason::eIntegerDivideByZero: 162 str = "signal SIGFPE: integer divide by zero"; 163 break; 164 case CrashReason::eIntegerOverflow: 165 str = "signal SIGFPE: integer overflow"; 166 break; 167 case CrashReason::eFloatDivideByZero: 168 str = "signal SIGFPE: floating point divide by zero"; 169 break; 170 case CrashReason::eFloatOverflow: 171 str = "signal SIGFPE: floating point overflow"; 172 break; 173 case CrashReason::eFloatUnderflow: 174 str = "signal SIGFPE: floating point underflow"; 175 break; 176 case CrashReason::eFloatInexactResult: 177 str = "signal SIGFPE: inexact floating point result"; 178 break; 179 case CrashReason::eFloatInvalidOperation: 180 str = "signal SIGFPE: invalid floating point operation"; 181 break; 182 case CrashReason::eFloatSubscriptRange: 183 str = "signal SIGFPE: invalid floating point subscript range"; 184 break; 185 } 186 187 return str; 188 } 189 190 const char *CrashReasonAsString(CrashReason reason) { 191 #ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION 192 // Just return the code in ascii for integration builds. 193 chcar str[8]; 194 sprintf(str, "%d", reason); 195 #else 196 const char *str = nullptr; 197 198 switch (reason) { 199 case CrashReason::eInvalidCrashReason: 200 str = "eInvalidCrashReason"; 201 break; 202 203 // SIGSEGV crash reasons. 204 case CrashReason::eInvalidAddress: 205 str = "eInvalidAddress"; 206 break; 207 case CrashReason::ePrivilegedAddress: 208 str = "ePrivilegedAddress"; 209 break; 210 211 // SIGILL crash reasons. 212 case CrashReason::eIllegalOpcode: 213 str = "eIllegalOpcode"; 214 break; 215 case CrashReason::eIllegalOperand: 216 str = "eIllegalOperand"; 217 break; 218 case CrashReason::eIllegalAddressingMode: 219 str = "eIllegalAddressingMode"; 220 break; 221 case CrashReason::eIllegalTrap: 222 str = "eIllegalTrap"; 223 break; 224 case CrashReason::ePrivilegedOpcode: 225 str = "ePrivilegedOpcode"; 226 break; 227 case CrashReason::ePrivilegedRegister: 228 str = "ePrivilegedRegister"; 229 break; 230 case CrashReason::eCoprocessorError: 231 str = "eCoprocessorError"; 232 break; 233 case CrashReason::eInternalStackError: 234 str = "eInternalStackError"; 235 break; 236 237 // SIGBUS crash reasons: 238 case CrashReason::eIllegalAlignment: 239 str = "eIllegalAlignment"; 240 break; 241 case CrashReason::eIllegalAddress: 242 str = "eIllegalAddress"; 243 break; 244 case CrashReason::eHardwareError: 245 str = "eHardwareError"; 246 break; 247 248 // SIGFPE crash reasons: 249 case CrashReason::eIntegerDivideByZero: 250 str = "eIntegerDivideByZero"; 251 break; 252 case CrashReason::eIntegerOverflow: 253 str = "eIntegerOverflow"; 254 break; 255 case CrashReason::eFloatDivideByZero: 256 str = "eFloatDivideByZero"; 257 break; 258 case CrashReason::eFloatOverflow: 259 str = "eFloatOverflow"; 260 break; 261 case CrashReason::eFloatUnderflow: 262 str = "eFloatUnderflow"; 263 break; 264 case CrashReason::eFloatInexactResult: 265 str = "eFloatInexactResult"; 266 break; 267 case CrashReason::eFloatInvalidOperation: 268 str = "eFloatInvalidOperation"; 269 break; 270 case CrashReason::eFloatSubscriptRange: 271 str = "eFloatSubscriptRange"; 272 break; 273 } 274 #endif 275 276 return str; 277 } 278 279 CrashReason GetCrashReason(const siginfo_t &info) { 280 switch (info.si_signo) { 281 case SIGSEGV: 282 return GetCrashReasonForSIGSEGV(info); 283 case SIGBUS: 284 return GetCrashReasonForSIGBUS(info); 285 case SIGFPE: 286 return GetCrashReasonForSIGFPE(info); 287 case SIGILL: 288 return GetCrashReasonForSIGILL(info); 289 } 290 291 assert(false && "unexpected signal"); 292 return CrashReason::eInvalidCrashReason; 293 } 294