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