[Lldb-commits] [lldb] [LLDB][ProcessELFCore] Add Description to ProcessELFCore/ELFThread stop reasons (PR #110065)

via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 25 17:47:18 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jacob Lalonde (Jlalond)

<details>
<summary>Changes</summary>

This fixes a functionality gap with GDB, where GDB will properly decode the stop reason and give the address for SIGSEGV. I also added descriptions to all stop reasons, following the same code path that the Native Linux Thread uses.

---
Full diff: https://github.com/llvm/llvm-project/pull/110065.diff


3 Files Affected:

- (modified) lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp (+1) 
- (modified) lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp (+35-5) 
- (modified) lldb/source/Plugins/Process/elf-core/ThreadElfCore.h (+15-3) 


``````````diff
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 7955594bf5d94c..468a3b8934e741 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -931,6 +931,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
         return status.ToError();
       thread_data.signo = siginfo.si_signo;
       thread_data.code = siginfo.si_code;
+      thread_data.description = siginfo.GetDescription();
       break;
     }
     case ELF::NT_FILE: {
diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 52b96052bdbeca..e9ae5211c28a53 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -9,6 +9,7 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/UnixSignals.h"
 #include "lldb/Target/Unwind.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
@@ -49,8 +50,8 @@ using namespace lldb_private;
 // Construct a Thread object with given data
 ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
     : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
-      m_signo(td.signo), m_code(td.code), m_gpregset_data(td.gpregset),
-      m_notes(td.notes) {}
+      m_signo(td.signo), m_code(td.code), m_sig_description(td.description),
+      m_gpregset_data(td.gpregset), m_notes(td.notes) {}
 
 ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
 
@@ -241,7 +242,7 @@ bool ThreadElfCore::CalculateStopInfo() {
     return false;
 
   SetStopInfo(StopInfo::CreateStopReasonWithSignal(
-      *this, m_signo, /*description=*/nullptr, m_code));
+      *this, m_signo, m_sig_description.c_str(), m_code));
   return true;
 }
 
@@ -543,7 +544,8 @@ size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
 
 Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
   Status error;
-  if (GetSize(arch) > data.GetByteSize()) {
+  uint64_t size = GetSize(arch);
+  if (size > data.GetByteSize()) {
     error = Status::FromErrorStringWithFormat(
         "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
         GetSize(arch), data.GetByteSize());
@@ -556,6 +558,34 @@ Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
   si_signo = data.GetU32(&offset);
   si_errno = data.GetU32(&offset);
   si_code = data.GetU32(&offset);
+  // 64b ELF have a 4 byte pad.
+  if (data.GetAddressByteSize() == 8)
+    offset += 4;
+  switch (si_signo) {
+  case SIGFPE:
+  case SIGILL:
+  case SIGSEGV:
+  case SIGBUS:
+  case SIGTRAP:
+    addr = (void *)data.GetAddress(&offset);
+    addr_lsb = data.GetU16(&offset);
+    return error;
+  default:
+    return error;
+  }
+}
 
-  return error;
+std::string ELFLinuxSigInfo::GetDescription() {
+  switch (si_signo) {
+  case SIGFPE:
+  case SIGILL:
+  case SIGSEGV:
+  case SIGBUS:
+  case SIGTRAP:
+    return lldb_private::UnixSignals::CreateForHost()->GetSignalDescription(
+        si_signo, si_code, reinterpret_cast<uintptr_t>(addr));
+  default:
+    return lldb_private::UnixSignals::CreateForHost()->GetSignalDescription(
+        si_signo, si_code);
+  }
 }
diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
index 3fa0b8b0eedb0b..3c6c02f73efae8 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -75,16 +75,25 @@ struct ELFLinuxPrStatus {
 static_assert(sizeof(ELFLinuxPrStatus) == 112,
               "sizeof ELFLinuxPrStatus is not correct!");
 
+union ELFSigval {
+  int sival_int;
+  void *sival_ptr;
+};
+
 struct ELFLinuxSigInfo {
-  int32_t si_signo;
-  int32_t si_code;
+  int32_t si_signo; // Order matters for the first 3.
   int32_t si_errno;
+  int32_t si_code;
+  void *addr;       /* faulting insn/memory ref. */
+  int32_t addr_lsb; /* Valid LSB of the reported address.  */
 
   ELFLinuxSigInfo();
 
   lldb_private::Status Parse(const lldb_private::DataExtractor &data,
                              const lldb_private::ArchSpec &arch);
 
+  std::string GetDescription();
+
   // Return the bytesize of the structure
   // 64 bit - just sizeof
   // 32 bit - hardcoded because we are reusing the struct, but some of the
@@ -93,7 +102,7 @@ struct ELFLinuxSigInfo {
   static size_t GetSize(const lldb_private::ArchSpec &arch);
 };
 
-static_assert(sizeof(ELFLinuxSigInfo) == 12,
+static_assert(sizeof(ELFLinuxSigInfo) == 32,
               "sizeof ELFLinuxSigInfo is not correct!");
 
 // PRPSINFO structure's size differs based on architecture.
@@ -144,7 +153,9 @@ struct ThreadData {
   lldb::tid_t tid;
   int signo = 0;
   int code = 0;
+  void *sigaddr = nullptr;
   int prstatus_sig = 0;
+  std::string description;
   std::string name;
 };
 
@@ -183,6 +194,7 @@ class ThreadElfCore : public lldb_private::Thread {
 
   int m_signo;
   int m_code;
+  std::string m_sig_description;
 
   lldb_private::DataExtractor m_gpregset_data;
   std::vector<lldb_private::CoreNote> m_notes;

``````````

</details>


https://github.com/llvm/llvm-project/pull/110065


More information about the lldb-commits mailing list