diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp --- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -90,8 +90,7 @@ case SIGBUS: case SIGFPE: case SIGILL: - const auto reason = GetCrashReason(*info); - m_stop_description = GetCrashReasonString(reason, *info); + m_stop_description = GetCrashReasonString(*info); break; } } diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h --- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h @@ -110,7 +110,7 @@ /// Extend m_stop_description with logical and allocation tag values. /// If there is an error along the way just add the information we were able /// to get. - void AnnotateSyncTagCheckFault(const siginfo_t *info); + void AnnotateSyncTagCheckFault(lldb::addr_t fault_addr); // Member Variables lldb::StateType m_state; diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp --- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -294,19 +294,19 @@ case SIGBUS: case SIGFPE: case SIGILL: - const auto reason = GetCrashReason(*info); - m_stop_description = GetCrashReasonString(reason, *info); - - if (reason == CrashReason::eSyncTagCheckFault) { - AnnotateSyncTagCheckFault(info); - } - + m_stop_description = GetCrashReasonString(*info); +#ifndef SEGV_MTESERR +#define SEGV_MTESERR 9 +#endif + if (info->si_signo == SIGSEGV && info->si_code == SEGV_MTESERR) + AnnotateSyncTagCheckFault( + reinterpret_cast(info->si_addr)); break; } } } -void NativeThreadLinux::AnnotateSyncTagCheckFault(const siginfo_t *info) { +void NativeThreadLinux::AnnotateSyncTagCheckFault(lldb::addr_t fault_addr) { int32_t allocation_tag_type = 0; switch (GetProcess().GetArchitecture().GetMachine()) { // aarch64_32 deliberately not here because there's no 32 bit MTE @@ -331,7 +331,6 @@ m_stop_description.pop_back(); std::stringstream ss; - lldb::addr_t fault_addr = reinterpret_cast(info->si_addr); std::unique_ptr manager(std::move(details->manager)); ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr); diff --git a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp --- a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -90,8 +90,7 @@ case SIGBUS: case SIGFPE: case SIGILL: - const auto reason = GetCrashReason(*info); - m_stop_description = GetCrashReasonString(reason, *info); + m_stop_description = GetCrashReasonString(*info); break; } } diff --git a/lldb/source/Plugins/Process/POSIX/CrashReason.h b/lldb/source/Plugins/Process/POSIX/CrashReason.h --- a/lldb/source/Plugins/Process/POSIX/CrashReason.h +++ b/lldb/source/Plugins/Process/POSIX/CrashReason.h @@ -15,45 +15,6 @@ #include -enum class CrashReason { - eInvalidCrashReason, - - // SIGSEGV crash reasons. - eInvalidAddress, - ePrivilegedAddress, - eBoundViolation, - eAsyncTagCheckFault, - eSyncTagCheckFault, - - // SIGILL crash reasons. - eIllegalOpcode, - eIllegalOperand, - eIllegalAddressingMode, - eIllegalTrap, - ePrivilegedOpcode, - ePrivilegedRegister, - eCoprocessorError, - eInternalStackError, - - // SIGBUS crash reasons, - eIllegalAlignment, - eIllegalAddress, - eHardwareError, - - // SIGFPE crash reasons, - eIntegerDivideByZero, - eIntegerOverflow, - eFloatDivideByZero, - eFloatOverflow, - eFloatUnderflow, - eFloatInexactResult, - eFloatInvalidOperation, - eFloatSubscriptRange -}; - -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr); -std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info); - -CrashReason GetCrashReason(const siginfo_t &info); +std::string GetCrashReasonString(const siginfo_t &info); #endif // #ifndef liblldb_CrashReason_H_ diff --git a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp --- a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp @@ -12,6 +12,42 @@ #include +enum class CrashReason { + eInvalidCrashReason, + + // SIGSEGV crash reasons. + eInvalidAddress, + ePrivilegedAddress, + eBoundViolation, + eAsyncTagCheckFault, + eSyncTagCheckFault, + + // SIGILL crash reasons. + eIllegalOpcode, + eIllegalOperand, + eIllegalAddressingMode, + eIllegalTrap, + ePrivilegedOpcode, + ePrivilegedRegister, + eCoprocessorError, + eInternalStackError, + + // SIGBUS crash reasons, + eIllegalAlignment, + eIllegalAddress, + eHardwareError, + + // SIGFPE crash reasons, + eIntegerDivideByZero, + eIntegerOverflow, + eFloatDivideByZero, + eFloatOverflow, + eFloatUnderflow, + eFloatInexactResult, + eFloatInvalidOperation, + eFloatSubscriptRange +}; + static void AppendFaultAddr(std::string &str, lldb::addr_t addr) { std::stringstream ss; ss << " (fault address: 0x" << std::hex << addr << ")"; @@ -37,10 +73,8 @@ } #endif -static CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) { - assert(info.si_signo == SIGSEGV); - - switch (info.si_code) { +static CrashReason GetCrashReasonForSIGSEGV(int code) { + switch (code) { #ifdef SI_KERNEL case SI_KERNEL: // Some platforms will occasionally send nonstandard spurious SI_KERNEL @@ -73,10 +107,8 @@ return CrashReason::eInvalidCrashReason; } -static CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) { - assert(info.si_signo == SIGILL); - - switch (info.si_code) { +static CrashReason GetCrashReasonForSIGILL(int code) { + switch (code) { case ILL_ILLOPC: return CrashReason::eIllegalOpcode; case ILL_ILLOPN: @@ -98,10 +130,8 @@ return CrashReason::eInvalidCrashReason; } -static CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) { - assert(info.si_signo == SIGFPE); - - switch (info.si_code) { +static CrashReason GetCrashReasonForSIGFPE(int code) { + switch (code) { case FPE_INTDIV: return CrashReason::eIntegerDivideByZero; case FPE_INTOVF: @@ -123,10 +153,8 @@ return CrashReason::eInvalidCrashReason; } -static CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) { - assert(info.si_signo == SIGBUS); - - switch (info.si_code) { +static CrashReason GetCrashReasonForSIGBUS(int code) { + switch (code) { case BUS_ADRALN: return CrashReason::eIllegalAlignment; case BUS_ADRERR: @@ -138,25 +166,8 @@ return CrashReason::eInvalidCrashReason; } -std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) { - std::string str; - -// make sure that siginfo_t has the bound fields available. -#if defined(si_lower) && defined(si_upper) - if (reason == CrashReason::eBoundViolation) { - str = "signal SIGSEGV"; - AppendBounds(str, reinterpret_cast(info.si_lower), - reinterpret_cast(info.si_upper), - reinterpret_cast(info.si_addr)); - return str; - } -#endif - - return GetCrashReasonString(reason, - reinterpret_cast(info.si_addr)); -} - -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { +static std::string GetCrashReasonString(CrashReason reason, + lldb::addr_t fault_addr) { std::string str; switch (reason) { @@ -244,18 +255,52 @@ return str; } -CrashReason GetCrashReason(const siginfo_t &info) { - switch (info.si_signo) { +static CrashReason GetCrashReason(int signo, int code) { + switch (signo) { case SIGSEGV: - return GetCrashReasonForSIGSEGV(info); + return GetCrashReasonForSIGSEGV(code); case SIGBUS: - return GetCrashReasonForSIGBUS(info); + return GetCrashReasonForSIGBUS(code); case SIGFPE: - return GetCrashReasonForSIGFPE(info); + return GetCrashReasonForSIGFPE(code); case SIGILL: - return GetCrashReasonForSIGILL(info); + return GetCrashReasonForSIGILL(code); } assert(false && "unexpected signal"); return CrashReason::eInvalidCrashReason; } + +static std::string GetCrashReasonString(int signo, int code, lldb::addr_t addr, + std::optional lower, + std::optional upper) { + CrashReason reason = GetCrashReason(signo, code); + + if (lower && upper) { + std::string str; + if (reason == CrashReason::eBoundViolation) { + str = "signal SIGSEGV"; + AppendBounds(str, reinterpret_cast(*lower), + reinterpret_cast(*upper), + reinterpret_cast(addr)); + return str; + } + } + + return GetCrashReasonString(reason, addr); +} + +std::string GetCrashReasonString(const siginfo_t &info) { +#if defined(si_lower) && defined(si_upper) + std::optional lower = + reinterpret_cast(info.si_lower); + std::optional upper = + reinterpret_cast(info.si_upper); +#else + std::optional lower; + std::optional upper; +#endif + return GetCrashReasonString(info.si_signo, info.si_code, + reinterpret_cast(info.si_addr), lower, + upper); +}