[Lldb-commits] [lldb] 0107513 - [lldb] Implement CrashReason using UnixSignals

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Mar 20 04:39:39 PDT 2023


Author: David Spickett
Date: 2023-03-20T11:39:32Z
New Revision: 0107513fe79da7670e37c29c0862794a2213a89c

URL: https://github.com/llvm/llvm-project/commit/0107513fe79da7670e37c29c0862794a2213a89c
DIFF: https://github.com/llvm/llvm-project/commit/0107513fe79da7670e37c29c0862794a2213a89c.diff

LOG: [lldb] Implement CrashReason using UnixSignals

By adding signal codes to UnixSignals and adding a new function
where you can get a string with optional address and bounds.

Added signal codes to the Linux, FreeBSD and NetBSD signal sets.
I've checked the numbers against the relevant sources.

Each signal code has a code number, description and printing options.
By default you just get the descripton, you can opt into adding either
a fault address or bounds information.

Bounds signals we'll use the description, unless we have the bounds
values in which case we say whether it is an upper or lower bound
issue.

GetCrashReasonString remains in CrashReason because we need it to
be compiled only for platforms with siginfo_t. Ideally it would
move into NativeProcessProtocol, but that is also used
by NativeRegisterContextWindows, where there would be no siginfo_t.

Reviewed By: JDevlieghere

Differential Revision: https://reviews.llvm.org/D146044

Added: 
    

Modified: 
    lldb/include/lldb/Target/UnixSignals.h
    lldb/source/Plugins/Process/POSIX/CrashReason.cpp
    lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
    lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
    lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
    lldb/source/Target/UnixSignals.cpp
    lldb/unittests/Signals/UnixSignalsTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/UnixSignals.h b/lldb/include/lldb/Target/UnixSignals.h
index ff9f1ac9be196..ac47a2769b927 100644
--- a/lldb/include/lldb/Target/UnixSignals.h
+++ b/lldb/include/lldb/Target/UnixSignals.h
@@ -32,6 +32,13 @@ class UnixSignals {
 
   const char *GetSignalAsCString(int32_t signo) const;
 
+  std::string
+  GetSignalDescription(int32_t signo,
+                       std::optional<int32_t> code = std::nullopt,
+                       std::optional<lldb::addr_t> addr = std::nullopt,
+                       std::optional<lldb::addr_t> lower = std::nullopt,
+                       std::optional<lldb::addr_t> upper = std::nullopt) const;
+
   bool SignalIsValid(int32_t signo) const;
 
   int32_t GetSignalNumberFromName(const char *name) const;
@@ -82,6 +89,12 @@ class UnixSignals {
                  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 +124,16 @@ class UnixSignals {
 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<int32_t, SignalCode> 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
index 2ae7f8390575d..d93b7cd0ce562 100644
--- a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -8,283 +8,7 @@
 
 #include "CrashReason.h"
 
-#include "llvm/Support/raw_ostream.h"
-
-#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 << ")";
-  str += ss.str();
-}
-
-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();
-}
-
-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<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, *lower, *upper, 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)
@@ -296,7 +20,12 @@ std::string GetCrashReasonString(const siginfo_t &info) {
   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);
+
+  std::string description =
+      lldb_private::UnixSignals::CreateForHost()->GetSignalDescription(
+          info.si_signo, info.si_code,
+          reinterpret_cast<uintptr_t>(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
index 0a4bdc72b364e..c2997e0249219 100644
--- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -15,72 +15,107 @@ FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); }
 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
index d4b0f4039da95..fee7b89ef8371 100644
--- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -20,14 +20,48 @@ void LinuxSignals::Reset() {
   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
index ffdfd19b4efe2..84a664c05558c 100644
--- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
@@ -14,40 +14,72 @@ NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); }
 
 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
index 02354be44cfe8..d754537cc4cf4 100644
--- 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 <optional>
+#include <sstream>
 
 using namespace lldb_private;
 using namespace llvm;
@@ -112,6 +113,16 @@ void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress,
   ++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 @@ const char *UnixSignals::GetSignalAsCString(int signo) const {
     return pos->second.m_name.GetCString();
 }
 
+std::string
+UnixSignals::GetSignalDescription(int32_t signo, std::optional<int32_t> code,
+                                  std::optional<lldb::addr_t> addr,
+                                  std::optional<lldb::addr_t> lower,
+                                  std::optional<lldb::addr_t> 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<int, SignalCode>::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
index e4c4634862449..2ae1b4ee5138f 100644
--- a/lldb/unittests/Signals/UnixSignalsTest.cpp
+++ b/lldb/unittests/Signals/UnixSignalsTest.cpp
@@ -23,6 +23,10 @@ class TestSignals : public UnixSignals {
     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 @@ TEST(UnixSignalsTest, GetInfo) {
   EXPECT_EQ(name, signals.GetSignalAsCString(signo));
 }
 
+TEST(UnixSignalsTest, GetAsCString) {
+  TestSignals signals;
+
+  ASSERT_EQ(nullptr, signals.GetSignalAsCString(100));
+  std::string name = signals.GetSignalAsCString(16);
+  ASSERT_EQ("SIG16", name);
+}
+
+TEST(UnixSignalsTest, GetAsString) {
+  TestSignals signals;
+
+  ASSERT_EQ("", signals.GetSignalDescription(100, std::nullopt));
+  ASSERT_EQ("SIG16", signals.GetSignalDescription(16, std::nullopt));
+  ASSERT_EQ("", signals.GetSignalDescription(100, 100));
+  ASSERT_EQ("SIG16", signals.GetSignalDescription(16, 100));
+  ASSERT_EQ("SIG16: a specific type of SIG16",
+            signals.GetSignalDescription(16, 1));
+
+  // Unknown code, won't use the address.
+  ASSERT_EQ("SIG16", signals.GetSignalDescription(16, 100, 0xCAFEF00D));
+  // Known code, that shouldn't print fault address.
+  ASSERT_EQ("SIG16: a specific type of SIG16",
+            signals.GetSignalDescription(16, 1, 0xCAFEF00D));
+  // Known code that should.
+  ASSERT_EQ("SIG16: SIG16 with a fault address (fault address: 0xcafef00d)",
+            signals.GetSignalDescription(16, 2, 0xCAFEF00D));
+  // No address given just print the code description.
+  ASSERT_EQ("SIG16: SIG16 with a fault address",
+            signals.GetSignalDescription(16, 2));
+
+  const char *expected = "SIG16: bounds violation";
+  // Must pass all needed info to get full output.
+  ASSERT_EQ(expected, signals.GetSignalDescription(16, 3));
+  ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d));
+  ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d, 0x1234));
+
+  ASSERT_EQ("SIG16: upper bound violation (fault address: 0x5679, lower bound: "
+            "0x1234, upper bound: 0x5678)",
+            signals.GetSignalDescription(16, 3, 0x5679, 0x1234, 0x5678));
+  ASSERT_EQ("SIG16: lower bound violation (fault address: 0x1233, lower bound: "
+            "0x1234, upper bound: 0x5678)",
+            signals.GetSignalDescription(16, 3, 0x1233, 0x1234, 0x5678));
+}
+
 TEST(UnixSignalsTest, VersionChange) {
   TestSignals signals;
 


        


More information about the lldb-commits mailing list