hhellyer updated this revision to Diff 78163.
hhellyer added a comment.
Update with fixes from review comments.
I've run clang-format, fixed the use of iterators and added const qualifiers.
I removed the use of the SIGSTOP constant and use GetUnixSignals instead.
I've also moved that block down a few lines until after SetUnixSignals has been
called.
I will update the patch with the test cases shortly.
https://reviews.llvm.org/D26676
Files:
source/Plugins/Process/elf-core/ProcessElfCore.cpp
source/Plugins/Process/elf-core/ThreadElfCore.cpp
source/Plugins/Process/elf-core/ThreadElfCore.h
Index: source/Plugins/Process/elf-core/ThreadElfCore.h
===================================================================
--- source/Plugins/Process/elf-core/ThreadElfCore.h
+++ source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -82,6 +82,38 @@
static_assert(sizeof(ELFLinuxPrStatus) == 112,
"sizeof ELFLinuxPrStatus is not correct!");
+struct ELFLinuxSigInfo {
+ int32_t si_signo;
+ int32_t si_code;
+ int32_t si_errno;
+
+ ELFLinuxSigInfo();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(const lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxSigInfo);
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 12;
+ default:
+ return 0;
+ }
+ }
+};
+
+static_assert(sizeof(ELFLinuxSigInfo) == 12,
+ "sizeof ELFLinuxSigInfo is not correct!");
+
// PRPSINFO structure's size differs based on architecture.
// This is the layout in the x86-64 arch case.
// In the i386 case we parse it manually and fill it again
@@ -133,7 +165,8 @@
lldb_private::DataExtractor fpregset;
lldb_private::DataExtractor vregset;
lldb::tid_t tid;
- int signo;
+ int signo = 0;
+ int prstatus_sig = 0;
std::string name;
};
Index: source/Plugins/Process/elf-core/ThreadElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -320,3 +320,45 @@
return error;
}
+
+//----------------------------------------------------------------
+// Parse SIGINFO from NOTE entry
+//----------------------------------------------------------------
+ELFLinuxSigInfo::ELFLinuxSigInfo() {
+ memset(this, 0, sizeof(ELFLinuxSigInfo));
+}
+
+Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
+}
Index: source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -214,6 +214,29 @@
SetUnixSignals(UnixSignals::Create(GetArchitecture()));
+ // Ensure we found at least one thread that was stopped on a signal.
+ bool siginfo_signal_found = false;
+ bool prstatus_signal_found = false;
+ // Check we found a signal in a SIGINFO note.
+ for (const auto &thread_data: m_thread_data) {
+ if (thread_data.signo != 0)
+ siginfo_signal_found = true;
+ if (thread_data.prstatus_sig != 0)
+ prstatus_signal_found = true;
+ }
+ if (siginfo_signal_found == false) {
+ // If we don't have signal from SIGINFO use the signal from each threads
+ // PRSTATUS note.
+ if (prstatus_signal_found == true) {
+ for (const auto &thread_data: m_thread_data)
+ thread_data.signo = thread_data.prstatus_sig;
+ } else if (m_thread_data.size() > 0) {
+ // If all else fails force the first thread to be SIGSTOP
+ m_thread_data.begin()->signo =
+ GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
+ }
+ }
+
// Core files are useless without the main executable. See if we can locate
// the main
// executable using data we found in the core file notes.
@@ -400,7 +423,8 @@
NT_TASKSTRUCT,
NT_PLATFORM,
NT_AUXV,
- NT_FILE = 0x46494c45
+ NT_FILE = 0x46494c45,
+ NT_SIGINFO = 0x53494749
};
namespace FREEBSD {
@@ -484,6 +508,7 @@
ArchSpec arch = GetArchitecture();
ELFLinuxPrPsInfo prpsinfo;
ELFLinuxPrStatus prstatus;
+ ELFLinuxSigInfo siginfo;
size_t header_size;
size_t len;
Error error;
@@ -545,7 +570,7 @@
error = prstatus.Parse(note_data, arch);
if (error.Fail())
return error;
- thread_data->signo = prstatus.pr_cursig;
+ thread_data->prstatus_sig = prstatus.pr_cursig;
thread_data->tid = prstatus.pr_pid;
header_size = ELFLinuxPrStatus::GetSize(arch);
len = note_data.GetByteSize() - header_size;
@@ -583,6 +608,12 @@
m_nt_file_entries[i].path.SetCString(path);
}
} break;
+ case NT_SIGINFO: {
+ error = siginfo.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->signo = siginfo.si_signo;
+ } break;
default:
break;
}
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits