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