diff options
Diffstat (limited to 'source/Plugins/Process/POSIX/CrashReason.cpp')
-rw-r--r-- | source/Plugins/Process/POSIX/CrashReason.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp new file mode 100644 index 0000000..4dd91a6 --- /dev/null +++ b/source/Plugins/Process/POSIX/CrashReason.cpp @@ -0,0 +1,315 @@ +//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CrashReason.h" + +#include <sstream> + +namespace { + +void +AppendFaultAddr (std::string& str, lldb::addr_t addr) +{ + std::stringstream ss; + ss << " (fault address: 0x" << std::hex << addr << ")"; + str += ss.str(); +} + +CrashReason +GetCrashReasonForSIGSEGV(const siginfo_t& info) +{ + assert(info.si_signo == SIGSEGV); + + switch (info.si_code) + { + case SI_KERNEL: + // Linux will occasionally send spurious SI_KERNEL codes. + // (this is poorly documented in sigaction) + // One way to get this is via unaligned SIMD loads. + return CrashReason::eInvalidAddress; // for lack of anything better + case SEGV_MAPERR: + return CrashReason::eInvalidAddress; + case SEGV_ACCERR: + return CrashReason::ePrivilegedAddress; + } + + assert(false && "unexpected si_code for SIGSEGV"); + return CrashReason::eInvalidCrashReason; +} + +CrashReason +GetCrashReasonForSIGILL(const siginfo_t& info) +{ + assert(info.si_signo == SIGILL); + + switch (info.si_code) + { + case ILL_ILLOPC: + return CrashReason::eIllegalOpcode; + case ILL_ILLOPN: + return CrashReason::eIllegalOperand; + case ILL_ILLADR: + return CrashReason::eIllegalAddressingMode; + case ILL_ILLTRP: + return CrashReason::eIllegalTrap; + case ILL_PRVOPC: + return CrashReason::ePrivilegedOpcode; + case ILL_PRVREG: + return CrashReason::ePrivilegedRegister; + case ILL_COPROC: + return CrashReason::eCoprocessorError; + case ILL_BADSTK: + return CrashReason::eInternalStackError; + } + + assert(false && "unexpected si_code for SIGILL"); + return CrashReason::eInvalidCrashReason; +} + +CrashReason +GetCrashReasonForSIGFPE(const siginfo_t& info) +{ + assert(info.si_signo == SIGFPE); + + switch (info.si_code) + { + case FPE_INTDIV: + return CrashReason::eIntegerDivideByZero; + case FPE_INTOVF: + return CrashReason::eIntegerOverflow; + case FPE_FLTDIV: + return CrashReason::eFloatDivideByZero; + case FPE_FLTOVF: + return CrashReason::eFloatOverflow; + case FPE_FLTUND: + return CrashReason::eFloatUnderflow; + case FPE_FLTRES: + return CrashReason::eFloatInexactResult; + case FPE_FLTINV: + return CrashReason::eFloatInvalidOperation; + case FPE_FLTSUB: + return CrashReason::eFloatSubscriptRange; + } + + assert(false && "unexpected si_code for SIGFPE"); + return CrashReason::eInvalidCrashReason; +} + +CrashReason +GetCrashReasonForSIGBUS(const siginfo_t& info) +{ + assert(info.si_signo == SIGBUS); + + switch (info.si_code) + { + case BUS_ADRALN: + return CrashReason::eIllegalAlignment; + case BUS_ADRERR: + return CrashReason::eIllegalAddress; + case BUS_OBJERR: + return CrashReason::eHardwareError; + } + + assert(false && "unexpected si_code for SIGBUS"); + return CrashReason::eInvalidCrashReason; +} + +} + +std::string +GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr) +{ + std::string str; + + switch (reason) + { + default: + assert(false && "invalid CrashReason"); + break; + + case CrashReason::eInvalidAddress: + str = "invalid address"; + AppendFaultAddr (str, fault_addr); + break; + case CrashReason::ePrivilegedAddress: + str = "address access protected"; + AppendFaultAddr (str, fault_addr); + break; + case CrashReason::eIllegalOpcode: + str = "illegal instruction"; + break; + case CrashReason::eIllegalOperand: + str = "illegal instruction operand"; + break; + case CrashReason::eIllegalAddressingMode: + str = "illegal addressing mode"; + break; + case CrashReason::eIllegalTrap: + str = "illegal trap"; + break; + case CrashReason::ePrivilegedOpcode: + str = "privileged instruction"; + break; + case CrashReason::ePrivilegedRegister: + str = "privileged register"; + break; + case CrashReason::eCoprocessorError: + str = "coprocessor error"; + break; + case CrashReason::eInternalStackError: + str = "internal stack error"; + break; + case CrashReason::eIllegalAlignment: + str = "illegal alignment"; + break; + case CrashReason::eIllegalAddress: + str = "illegal address"; + break; + case CrashReason::eHardwareError: + str = "hardware error"; + break; + case CrashReason::eIntegerDivideByZero: + str = "integer divide by zero"; + break; + case CrashReason::eIntegerOverflow: + str = "integer overflow"; + break; + case CrashReason::eFloatDivideByZero: + str = "floating point divide by zero"; + break; + case CrashReason::eFloatOverflow: + str = "floating point overflow"; + break; + case CrashReason::eFloatUnderflow: + str = "floating point underflow"; + break; + case CrashReason::eFloatInexactResult: + str = "inexact floating point result"; + break; + case CrashReason::eFloatInvalidOperation: + str = "invalid floating point operation"; + break; + case CrashReason::eFloatSubscriptRange: + str = "invalid floating point subscript range"; + break; + } + + return str; +} + +const char * +CrashReasonAsString (CrashReason reason) +{ +#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION + // Just return the code in ascii for integration builds. + chcar str[8]; + sprintf(str, "%d", reason); +#else + const char *str = nullptr; + + switch (reason) + { + case CrashReason::eInvalidCrashReason: + str = "eInvalidCrashReason"; + break; + + // SIGSEGV crash reasons. + case CrashReason::eInvalidAddress: + str = "eInvalidAddress"; + break; + case CrashReason::ePrivilegedAddress: + str = "ePrivilegedAddress"; + break; + + // SIGILL crash reasons. + case CrashReason::eIllegalOpcode: + str = "eIllegalOpcode"; + break; + case CrashReason::eIllegalOperand: + str = "eIllegalOperand"; + break; + case CrashReason::eIllegalAddressingMode: + str = "eIllegalAddressingMode"; + break; + case CrashReason::eIllegalTrap: + str = "eIllegalTrap"; + break; + case CrashReason::ePrivilegedOpcode: + str = "ePrivilegedOpcode"; + break; + case CrashReason::ePrivilegedRegister: + str = "ePrivilegedRegister"; + break; + case CrashReason::eCoprocessorError: + str = "eCoprocessorError"; + break; + case CrashReason::eInternalStackError: + str = "eInternalStackError"; + break; + + // SIGBUS crash reasons: + case CrashReason::eIllegalAlignment: + str = "eIllegalAlignment"; + break; + case CrashReason::eIllegalAddress: + str = "eIllegalAddress"; + break; + case CrashReason::eHardwareError: + str = "eHardwareError"; + break; + + // SIGFPE crash reasons: + case CrashReason::eIntegerDivideByZero: + str = "eIntegerDivideByZero"; + break; + case CrashReason::eIntegerOverflow: + str = "eIntegerOverflow"; + break; + case CrashReason::eFloatDivideByZero: + str = "eFloatDivideByZero"; + break; + case CrashReason::eFloatOverflow: + str = "eFloatOverflow"; + break; + case CrashReason::eFloatUnderflow: + str = "eFloatUnderflow"; + break; + case CrashReason::eFloatInexactResult: + str = "eFloatInexactResult"; + break; + case CrashReason::eFloatInvalidOperation: + str = "eFloatInvalidOperation"; + break; + case CrashReason::eFloatSubscriptRange: + str = "eFloatSubscriptRange"; + break; + } +#endif + + return str; +} + +CrashReason +GetCrashReason(const siginfo_t& info) +{ + switch(info.si_signo) + { + case SIGSEGV: + return GetCrashReasonForSIGSEGV(info); + case SIGBUS: + return GetCrashReasonForSIGBUS(info); + case SIGFPE: + return GetCrashReasonForSIGFPE(info); + case SIGILL: + return GetCrashReasonForSIGILL(info); + } + + assert(false && "unexpected signal"); + return CrashReason::eInvalidCrashReason; +} |