[LLDB][ProcessELFCore] Add Description to ProcessELFCore/ELFThread stop reasons by Jlalond · Pull Request #110065 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-lldb
Author: Jacob Lalonde (Jlalond)
Changes
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 --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 notes) { return status.ToError(); thread_data.signo = siginfo.si_signo; thread_data.code = siginfo.si_code;
} 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 @@thread_data.description = siginfo.GetDescription(); break;
#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));
return true; }*this, m_signo, m_sig_description.c_str(), m_code));
@@ -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;