diff --git a/lldb/include/lldb/Target/UnixSignals.h b/lldb/include/lldb/Target/UnixSignals.h --- a/lldb/include/lldb/Target/UnixSignals.h +++ b/lldb/include/lldb/Target/UnixSignals.h @@ -32,6 +32,12 @@ const char *GetSignalAsCString(int32_t signo) const; + std::string + GetSignalAsString(int32_t signo, std::optional code = std::nullopt, + std::optional addr = std::nullopt, + std::optional lower = std::nullopt, + std::optional upper = std::nullopt) const; + bool SignalIsValid(int32_t signo) const; int32_t GetSignalNumberFromName(const char *name) const; @@ -82,6 +88,12 @@ bool default_stop, bool default_notify, const char *description, const char *alias = nullptr); + enum SignalCodePrintOption { None, Address, Bounds }; + + void AddSignalCode( + int signo, int code, const char *description, + SignalCodePrintOption print_option = SignalCodePrintOption::None); + void RemoveSignal(int signo); /// Track how many times signals are hit as stop reasons. @@ -111,10 +123,16 @@ protected: // Classes that inherit from UnixSignals can see and modify these + struct SignalCode { + ConstString m_description; + SignalCodePrintOption m_print_option; + }; + struct Signal { ConstString m_name; ConstString m_alias; std::string m_description; + std::map m_codes; uint32_t m_hit_count = 0; bool m_suppress : 1, m_stop : 1, m_notify : 1; bool m_default_suppress : 1, m_default_stop : 1, m_default_notify : 1; 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 @@ -8,287 +8,7 @@ #include "CrashReason.h" -#include "llvm/Support/raw_ostream.h" - -#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 << ")"; - str += ss.str(); -} - -#if defined(si_lower) && defined(si_upper) -static void AppendBounds(std::string &str, lldb::addr_t lower_bound, - lldb::addr_t upper_bound, lldb::addr_t addr) { - llvm::raw_string_ostream stream(str); - if ((unsigned long)addr < lower_bound) - stream << ": lower bound violation "; - else - stream << ": upper bound violation "; - stream << "(fault address: 0x"; - stream.write_hex(addr); - stream << ", lower bound: 0x"; - stream.write_hex(lower_bound); - stream << ", upper bound: 0x"; - stream.write_hex(upper_bound); - stream << ")"; - stream.flush(); -} -#endif - -static CrashReason GetCrashReasonForSIGSEGV(int code) { - switch (code) { -#ifdef SI_KERNEL - case SI_KERNEL: - // Some platforms will occasionally send nonstandard spurious SI_KERNEL - // codes. One way to get this is via unaligned SIMD loads. - return CrashReason::eInvalidAddress; // for lack of anything better -#endif - case SEGV_MAPERR: - return CrashReason::eInvalidAddress; - case SEGV_ACCERR: - return CrashReason::ePrivilegedAddress; -#ifndef SEGV_BNDERR -#define SEGV_BNDERR 3 -#endif - case SEGV_BNDERR: - return CrashReason::eBoundViolation; -#ifdef __linux__ -#ifndef SEGV_MTEAERR -#define SEGV_MTEAERR 8 -#endif - case SEGV_MTEAERR: - return CrashReason::eAsyncTagCheckFault; -#ifndef SEGV_MTESERR -#define SEGV_MTESERR 9 -#endif - case SEGV_MTESERR: - return CrashReason::eSyncTagCheckFault; -#endif // __linux__ - } - - return CrashReason::eInvalidCrashReason; -} - -static CrashReason GetCrashReasonForSIGILL(int code) { - switch (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; - } - - return CrashReason::eInvalidCrashReason; -} - -static CrashReason GetCrashReasonForSIGFPE(int code) { - switch (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; - } - - return CrashReason::eInvalidCrashReason; -} - -static CrashReason GetCrashReasonForSIGBUS(int code) { - switch (code) { - case BUS_ADRALN: - return CrashReason::eIllegalAlignment; - case BUS_ADRERR: - return CrashReason::eIllegalAddress; - case BUS_OBJERR: - return CrashReason::eHardwareError; - } - - return CrashReason::eInvalidCrashReason; -} - -static std::string GetCrashReasonString(CrashReason reason, - lldb::addr_t fault_addr) { - std::string str; - - switch (reason) { - default: - str = "unknown crash reason"; - break; - - case CrashReason::eInvalidAddress: - str = "signal SIGSEGV: invalid address"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::ePrivilegedAddress: - str = "signal SIGSEGV: address access protected"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::eBoundViolation: - str = "signal SIGSEGV: bound violation"; - break; - case CrashReason::eAsyncTagCheckFault: - str = "signal SIGSEGV: async tag check fault"; - break; - case CrashReason::eSyncTagCheckFault: - str = "signal SIGSEGV: sync tag check fault"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::eIllegalOpcode: - str = "signal SIGILL: illegal instruction"; - break; - case CrashReason::eIllegalOperand: - str = "signal SIGILL: illegal instruction operand"; - break; - case CrashReason::eIllegalAddressingMode: - str = "signal SIGILL: illegal addressing mode"; - break; - case CrashReason::eIllegalTrap: - str = "signal SIGILL: illegal trap"; - break; - case CrashReason::ePrivilegedOpcode: - str = "signal SIGILL: privileged instruction"; - break; - case CrashReason::ePrivilegedRegister: - str = "signal SIGILL: privileged register"; - break; - case CrashReason::eCoprocessorError: - str = "signal SIGILL: coprocessor error"; - break; - case CrashReason::eInternalStackError: - str = "signal SIGILL: internal stack error"; - break; - case CrashReason::eIllegalAlignment: - str = "signal SIGBUS: illegal alignment"; - break; - case CrashReason::eIllegalAddress: - str = "signal SIGBUS: illegal address"; - break; - case CrashReason::eHardwareError: - str = "signal SIGBUS: hardware error"; - break; - case CrashReason::eIntegerDivideByZero: - str = "signal SIGFPE: integer divide by zero"; - break; - case CrashReason::eIntegerOverflow: - str = "signal SIGFPE: integer overflow"; - break; - case CrashReason::eFloatDivideByZero: - str = "signal SIGFPE: floating point divide by zero"; - break; - case CrashReason::eFloatOverflow: - str = "signal SIGFPE: floating point overflow"; - break; - case CrashReason::eFloatUnderflow: - str = "signal SIGFPE: floating point underflow"; - break; - case CrashReason::eFloatInexactResult: - str = "signal SIGFPE: inexact floating point result"; - break; - case CrashReason::eFloatInvalidOperation: - str = "signal SIGFPE: invalid floating point operation"; - break; - case CrashReason::eFloatSubscriptRange: - str = "signal SIGFPE: invalid floating point subscript range"; - break; - } - - return str; -} - -static CrashReason GetCrashReason(int signo, int code) { - switch (signo) { - case SIGSEGV: - return GetCrashReasonForSIGSEGV(code); - case SIGBUS: - return GetCrashReasonForSIGBUS(code); - case SIGFPE: - return GetCrashReasonForSIGFPE(code); - case SIGILL: - 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); -} +#include "lldb/Target/UnixSignals.h" std::string GetCrashReasonString(const siginfo_t &info) { #if defined(si_lower) && defined(si_upper) @@ -300,7 +20,12 @@ std::optional lower; std::optional upper; #endif - return GetCrashReasonString(info.si_signo, info.si_code, - reinterpret_cast(info.si_addr), lower, - upper); + + std::string description = + lldb_private::UnixSignals::CreateForHost()->GetSignalAsString( + info.si_signo, info.si_code, + reinterpret_cast(info.si_addr), lower, upper); + assert(description.size() && "unexpected signal"); + + return "signal " + description; } diff --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp --- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -15,72 +15,107 @@ void FreeBSDSignals::Reset() { UnixSignals::Reset(); - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== - // =================================================== - AddSignal(32, "SIGTHR", false, false, false, "thread interrupt"); - AddSignal(33, "SIGLIBRT", false, false, false, - "reserved by real-time library"); - AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16"); - AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17"); - AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18"); - AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19"); - AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20"); - AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21"); - AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22"); - AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23"); - AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24"); - AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25"); - AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26"); - AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27"); - AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28"); - AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29"); - AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30"); - AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31"); - AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32"); - AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33"); - AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34"); - AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35"); - AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36"); - AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37"); - AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38"); - AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39"); - AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40"); - AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41"); - AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42"); - AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43"); - AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44"); - AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45"); - AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46"); - AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47"); - AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48"); - AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49"); - AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50"); - AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51"); - AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52"); - AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53"); - AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54"); - AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55"); - AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56"); - AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57"); - AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58"); - AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59"); - AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60"); - AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61"); + // clang-format off + // SIGILL + AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); + AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); + AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); + AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); + AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); + AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); + AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); + AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + + // SIGFPE + AddSignalCode(8, 1 /*FPE_INTOVF*/, "integer overflow"); + AddSignalCode(8, 2 /*FPE_INTDIV*/, "integer divide by zero"); + AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); + AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); + AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); + AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); + AddSignalCode(8, 7 /*FPE_FLTINV*/, "invalid floating point operation"); + AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); + AddSignalCode(8, 9 /*FPE_FLTIDO*/, "input denormal operation"); + + // SIGBUS + AddSignalCode(10, 1 /*BUS_ADRALN*/, "invalid address alignment"); + AddSignalCode(10, 2 /*BUS_ADRERR*/, "nonexistent physical address"); + AddSignalCode(10, 3 /*BUS_OBJERR*/, "object-specific hardware error"); + AddSignalCode(10, 100 /*BUS_OOMERR*/, "no memory"); + + // SIGSEGV + AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", + SignalCodePrintOption::Address); + AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + AddSignalCode(11, 100 /*SEGV_PKUERR*/, "PKU violation", + SignalCodePrintOption::Address); + + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGTHR", false, false, false, "thread interrupt"); + AddSignal(33, "SIGLIBRT", false, false, false, "reserved by real-time library"); + AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16"); + AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17"); + AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18"); + AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19"); + AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20"); + AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21"); + AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22"); + AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23"); + AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24"); + AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25"); + AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26"); + AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27"); + AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28"); + AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29"); + AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30"); + AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31"); + AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32"); + AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33"); + AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34"); + AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35"); + AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36"); + AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37"); + AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38"); + AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39"); + AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40"); + AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41"); + AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42"); + AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43"); + AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44"); + AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45"); + AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46"); + AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47"); + AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48"); + AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49"); + AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50"); + AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51"); + AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52"); + AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53"); + AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54"); + AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55"); + AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56"); + AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57"); + AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58"); + AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59"); + AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60"); + AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61"); + // clang-format on } diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -20,14 +20,48 @@ AddSignal(1, "SIGHUP", false, true, true, "hangup"); AddSignal(2, "SIGINT", true, true, true, "interrupt"); AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); + AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); + AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); + AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); + AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); + AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); + AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); + AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGBUS", false, true, true, "bus error"); + AddSignalCode(7, 1 /*BUS_ADRALN*/, "illegal alignment"); + AddSignalCode(7, 2 /*BUS_ADRERR*/, "illegal address"); + AddSignalCode(7, 3 /*BUS_OBJERR*/, "hardware error"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignalCode(8, 1 /*FPE_INTDIV*/, "integer divide by zero"); + AddSignalCode(8, 2 /*FPE_INTOVF*/, "integer overflow"); + AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); + AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); + AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); + AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); + AddSignalCode(8, 7 /*FPE_FLTINV*/, "floating point invalid operation"); + AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", SignalCodePrintOption::Address); + AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", SignalCodePrintOption::Address); + AddSignalCode(11, 3 /*SEGV_BNDERR*/, "failed address bounds checks", SignalCodePrintOption::Bounds); + AddSignalCode(11, 8 /*SEGV_MTEAERR*/, "async tag check fault"); + AddSignalCode(11, 9 /*SEGV_MTESERR*/, "sync tag check fault", SignalCodePrintOption::Address); + // Some platforms will occasionally send nonstandard spurious SI_KERNEL + // codes. One way to get this is via unaligned SIMD loads. Treat it as invalid address. + AddSignalCode(11, 0x80 /*SI_KERNEL*/, "invalid address", SignalCodePrintOption::Address); + AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2"); AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); AddSignal(14, "SIGALRM", false, false, false, "alarm"); diff --git a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp --- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -14,40 +14,72 @@ void NetBSDSignals::Reset() { UnixSignals::Reset(); + + // clang-format off + // SIGILL + AddSignalCode(4, 1 /*ILL_ILLOPC*/, "illegal opcode"); + AddSignalCode(4, 2 /*ILL_ILLOPN*/, "illegal operand"); + AddSignalCode(4, 3 /*ILL_ILLADR*/, "illegal addressing mode"); + AddSignalCode(4, 4 /*ILL_ILLTRP*/, "illegal trap"); + AddSignalCode(4, 5 /*ILL_PRVOPC*/, "privileged opcode"); + AddSignalCode(4, 6 /*ILL_PRVREG*/, "privileged register"); + AddSignalCode(4, 7 /*ILL_COPROC*/, "coprocessor error"); + AddSignalCode(4, 8 /*ILL_BADSTK*/, "internal stack error"); + + // SIGFPE + AddSignalCode(8, 1 /*FPE_INTDIV*/, "integer divide by zero"); + AddSignalCode(8, 2 /*FPE_INTOVF*/, "integer overflow"); + AddSignalCode(8, 3 /*FPE_FLTDIV*/, "floating point divide by zero"); + AddSignalCode(8, 4 /*FPE_FLTOVF*/, "floating point overflow"); + AddSignalCode(8, 5 /*FPE_FLTUND*/, "floating point underflow"); + AddSignalCode(8, 6 /*FPE_FLTRES*/, "floating point inexact result"); + AddSignalCode(8, 7 /*FPE_FLTINV*/, "invalid floating point operation"); + AddSignalCode(8, 8 /*FPE_FLTSUB*/, "subscript out of range"); + + // SIGBUS + AddSignalCode(10, 1 /*BUS_ADRALN*/, "invalid address alignment"); + AddSignalCode(10, 2 /*BUS_ADRERR*/, "non-existent physical address"); + AddSignalCode(10, 3 /*BUS_OBJERR*/, "object specific hardware error"); + + // SIGSEGV + AddSignalCode(11, 1 /*SEGV_MAPERR*/, "address not mapped to object", + SignalCodePrintOption::Address); + AddSignalCode(11, 2 /*SEGV_ACCERR*/, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== - // =================================================== - AddSignal(32, "SIGPWR", false, true, true, - "power fail/restart (not reset when caught)"); - AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); - AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); - AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); - AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); - AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); - AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); - AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); - AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); - AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); - AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); - AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); - AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); - AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); - AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); - AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGPWR", false, true, true, "power fail/restart (not reset when caught)"); + AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); + AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format on } diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp --- a/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Utility/ArchSpec.h" #include +#include using namespace lldb_private; using namespace llvm; @@ -112,6 +113,16 @@ ++m_version; } +void UnixSignals::AddSignalCode(int signo, int code, const char *description, + SignalCodePrintOption print_option) { + collection::iterator signal = m_signals.find(signo); + assert(signal != m_signals.end() && + "Tried to add code to signal that does not exist."); + signal->second.m_codes.insert( + std::pair{code, SignalCode{ConstString(description), print_option}}); + ++m_version; +} + void UnixSignals::RemoveSignal(int signo) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) @@ -127,6 +138,58 @@ return pos->second.m_name.GetCString(); } +std::string +UnixSignals::GetSignalAsString(int32_t signo, std::optional code, + std::optional addr, + std::optional lower, + std::optional upper) const { + std::string str; + + collection::const_iterator pos = m_signals.find(signo); + if (pos != m_signals.end()) { + str = pos->second.m_name.GetCString(); + + if (code) { + std::map::const_iterator cpos = + pos->second.m_codes.find(*code); + if (cpos != pos->second.m_codes.end()) { + const SignalCode &sc = cpos->second; + str += ": "; + if (sc.m_print_option != SignalCodePrintOption::Bounds) + str += sc.m_description.GetCString(); + + std::stringstream strm; + switch (sc.m_print_option) { + case SignalCodePrintOption::None: + break; + case SignalCodePrintOption::Address: + if (addr) + strm << " (fault address: 0x" << std::hex << *addr << ")"; + break; + case SignalCodePrintOption::Bounds: + if (lower && upper && addr) { + if ((unsigned long)(*addr) < *lower) + strm << "lower bound violation "; + else + strm << "upper bound violation "; + + strm << "(fault address: 0x" << std::hex << *addr; + strm << ", lower bound: 0x" << std::hex << *lower; + strm << ", upper bound: 0x" << std::hex << *upper; + strm << ")"; + } else + strm << sc.m_description.GetCString(); + + break; + } + str += strm.str(); + } + } + } + + return str; +} + bool UnixSignals::SignalIsValid(int32_t signo) const { return m_signals.find(signo) != m_signals.end(); } diff --git a/lldb/unittests/Signals/UnixSignalsTest.cpp b/lldb/unittests/Signals/UnixSignalsTest.cpp --- a/lldb/unittests/Signals/UnixSignalsTest.cpp +++ b/lldb/unittests/Signals/UnixSignalsTest.cpp @@ -23,6 +23,10 @@ AddSignal(4, "SIG4", true, false, true, "DESC4"); AddSignal(8, "SIG8", true, true, true, "DESC8"); AddSignal(16, "SIG16", true, false, false, "DESC16"); + AddSignalCode(16, 1, "a specific type of SIG16"); + AddSignalCode(16, 2, "SIG16 with a fault address", + SignalCodePrintOption::Address); + AddSignalCode(16, 3, "bounds violation", SignalCodePrintOption::Bounds); } }; @@ -93,6 +97,50 @@ EXPECT_EQ(name, signals.GetSignalAsCString(signo)); } +TEST(UnixSignalsTest, GetAsCString) { + TestSignals signals; + + EXPECT_EQ(nullptr, signals.GetSignalAsCString(100)); + std::string name = signals.GetSignalAsCString(16); + EXPECT_EQ("SIG16", name); +} + +TEST(UnixSignalsTest, GetAsString) { + TestSignals signals; + + EXPECT_EQ("", signals.GetSignalAsString(100, std::nullopt)); + EXPECT_EQ("SIG16", signals.GetSignalAsString(16, std::nullopt)); + EXPECT_EQ("", signals.GetSignalAsString(100, 100)); + EXPECT_EQ("SIG16", signals.GetSignalAsString(16, 100)); + EXPECT_EQ("SIG16: a specific type of SIG16", + signals.GetSignalAsString(16, 1)); + + // Unknown code, won't use the address. + EXPECT_EQ("SIG16", signals.GetSignalAsString(16, 100, 0xCAFEF00D)); + // Known code, that shouldn't print fault address. + EXPECT_EQ("SIG16: a specific type of SIG16", + signals.GetSignalAsString(16, 1, 0xCAFEF00D)); + // Known code that should. + EXPECT_EQ("SIG16: SIG16 with a fault address (fault address: 0xcafef00d)", + signals.GetSignalAsString(16, 2, 0xCAFEF00D)); + // No address given just print the code description. + EXPECT_EQ("SIG16: SIG16 with a fault address", + signals.GetSignalAsString(16, 2)); + + const char *expected = "SIG16: bounds violation"; + // Must pass all needed info to get full output. + EXPECT_EQ(expected, signals.GetSignalAsString(16, 3)); + EXPECT_EQ(expected, signals.GetSignalAsString(16, 3, 0xcafef00d)); + EXPECT_EQ(expected, signals.GetSignalAsString(16, 3, 0xcafef00d, 0x1234)); + + EXPECT_EQ("SIG16: upper bound violation (fault address: 0x5679, lower bound: " + "0x1234, upper bound: 0x5678)", + signals.GetSignalAsString(16, 3, 0x5679, 0x1234, 0x5678)); + EXPECT_EQ("SIG16: lower bound violation (fault address: 0x1233, lower bound: " + "0x1234, upper bound: 0x5678)", + signals.GetSignalAsString(16, 3, 0x1233, 0x1234, 0x5678)); +} + TEST(UnixSignalsTest, VersionChange) { TestSignals signals;