[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