case SIGBUS:
case SIGFPE:
case SIGILL:
- 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<lldb::addr_t>(info->si_addr));
+ const auto reason = GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, *info);
+
+ if (reason == CrashReason::eSyncTagCheckFault) {
+ AnnotateSyncTagCheckFault(info);
+ }
+
break;
}
}
}
-void NativeThreadLinux::AnnotateSyncTagCheckFault(lldb::addr_t fault_addr) {
+void NativeThreadLinux::AnnotateSyncTagCheckFault(const siginfo_t *info) {
int32_t allocation_tag_type = 0;
switch (GetProcess().GetArchitecture().GetMachine()) {
// aarch64_32 deliberately not here because there's no 32 bit MTE
m_stop_description.pop_back();
std::stringstream ss;
+ lldb::addr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr);
std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr);
#include <sstream>
-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 << ")";
}
#endif
-static CrashReason GetCrashReasonForSIGSEGV(int code) {
- switch (code) {
+static CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
+ assert(info.si_signo == SIGSEGV);
+
+ switch (info.si_code) {
#ifdef SI_KERNEL
case SI_KERNEL:
// Some platforms will occasionally send nonstandard spurious SI_KERNEL
return CrashReason::eInvalidCrashReason;
}
-static CrashReason GetCrashReasonForSIGILL(int code) {
- switch (code) {
+static 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::eInvalidCrashReason;
}
-static CrashReason GetCrashReasonForSIGFPE(int code) {
- switch (code) {
+static 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::eInvalidCrashReason;
}
-static CrashReason GetCrashReasonForSIGBUS(int code) {
- switch (code) {
+static 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::eInvalidCrashReason;
}
-static std::string GetCrashReasonString(CrashReason reason,
- lldb::addr_t fault_addr) {
+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<uintptr_t>(info.si_lower),
+ reinterpret_cast<uintptr_t>(info.si_upper),
+ reinterpret_cast<uintptr_t>(info.si_addr));
+ return str;
+ }
+#endif
+
+ return GetCrashReasonString(reason,
+ reinterpret_cast<uintptr_t>(info.si_addr));
+}
+
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
std::string str;
switch (reason) {
return str;
}
-static CrashReason GetCrashReason(int signo, int code) {
- switch (signo) {
+CrashReason GetCrashReason(const siginfo_t &info) {
+ switch (info.si_signo) {
case SIGSEGV:
- return GetCrashReasonForSIGSEGV(code);
+ return GetCrashReasonForSIGSEGV(info);
case SIGBUS:
- return GetCrashReasonForSIGBUS(code);
+ return GetCrashReasonForSIGBUS(info);
case SIGFPE:
- return GetCrashReasonForSIGFPE(code);
+ return GetCrashReasonForSIGFPE(info);
case SIGILL:
- return GetCrashReasonForSIGILL(code);
+ return GetCrashReasonForSIGILL(info);
}
assert(false && "unexpected signal");
return CrashReason::eInvalidCrashReason;
}
-
-static std::string GetCrashReasonString(int signo, int code, lldb::addr_t addr,
- std::optional<lldb::addr_t> lower,
- std::optional<lldb::addr_t> upper) {
- CrashReason reason = GetCrashReason(signo, code);
-
- if (lower && upper) {
- std::string str;
- if (reason == CrashReason::eBoundViolation) {
- str = "signal SIGSEGV";
- AppendBounds(str, reinterpret_cast<uintptr_t>(*lower),
- reinterpret_cast<uintptr_t>(*upper),
- reinterpret_cast<uintptr_t>(addr));
- return str;
- }
- }
-
- return GetCrashReasonString(reason, addr);
-}
-
-std::string GetCrashReasonString(const siginfo_t &info) {
-#if defined(si_lower) && defined(si_upper)
- std::optional<lldb::addr_t> lower =
- reinterpret_cast<lldb::addr_t>(info.si_lower);
- std::optional<lldb::addr_t> upper =
- reinterpret_cast<lldb::addr_t>(info.si_upper);
-#else
- std::optional<lldb::addr_t> lower;
- std::optional<lldb::addr_t> upper;
-#endif
- return GetCrashReasonString(info.si_signo, info.si_code,
- reinterpret_cast<uintptr_t>(info.si_addr), lower,
- upper);
-}