[Lldb-commits] [lldb] 85bc498 - [LLDB] Show sub type of signals when debugging a core file
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Tue Mar 21 02:10:16 PDT 2023
Author: David Spickett
Date: 2023-03-21T09:10:09Z
New Revision: 85bc498826d4dac4b64f7b02659f6ec52f11c223
URL: https://github.com/llvm/llvm-project/commit/85bc498826d4dac4b64f7b02659f6ec52f11c223
DIFF: https://github.com/llvm/llvm-project/commit/85bc498826d4dac4b64f7b02659f6ec52f11c223.diff
LOG: [LLDB] Show sub type of signals when debugging a core file
Previously we only looked at the si_signo field, so you got:
```
(lldb) bt
* thread #1, name = 'a.out.mte', stop reason = signal SIGSEGV
* frame #0: 0x00000000004007f4
```
This patch adds si_code so we can show:
```
(lldb) bt
* thread #1, name = 'a.out.mte', stop reason = signal SIGSEGV: sync tag check fault
* frame #0: 0x00000000004007f4
```
The order of errno and code was incorrect in ElfLinuxSigInfo::Parse.
It was the order that a "swapped" siginfo arch would use, which for Linux,
is only MIPS. We removed MIPS Linux support some time ago.
See:
https://github.com/torvalds/linux/blob/fe15c26ee26efa11741a7b632e9f23b01aca4cc6/include/uapi/asm-generic/siginfo.h#L121
A test is added using memory tagging faults. Which were the original
motivation for the changes.
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D146045
Added:
Modified:
lldb/include/lldb/Target/StopInfo.h
lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
lldb/source/Target/StopInfo.cpp
lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
llvm/docs/ReleaseNotes.rst
Removed:
################################################################################
diff --git a/lldb/include/lldb/Target/StopInfo.h b/lldb/include/lldb/Target/StopInfo.h
index 9527a6ea553e3..8d6284e37dacf 100644
--- a/lldb/include/lldb/Target/StopInfo.h
+++ b/lldb/include/lldb/Target/StopInfo.h
@@ -115,7 +115,8 @@ class StopInfo : public std::enable_shared_from_this<StopInfo> {
static lldb::StopInfoSP
CreateStopReasonWithSignal(Thread &thread, int signo,
- const char *description = nullptr);
+ const char *description = nullptr,
+ std::optional<int> code = std::nullopt);
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread);
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 2771d1d20cf0c..a0f391b9b26ca 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -922,6 +922,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
if (status.Fail())
return status.ToError();
thread_data.signo = siginfo.si_signo;
+ thread_data.code = siginfo.si_code;
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 bb190104cf2fb..0191562d72230 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -46,7 +46,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_gpregset_data(td.gpregset), m_notes(td.notes) {}
+ m_signo(td.signo), m_code(td.code), m_gpregset_data(td.gpregset),
+ m_notes(td.notes) {}
ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
@@ -221,11 +222,12 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
bool ThreadElfCore::CalculateStopInfo() {
ProcessSP process_sp(GetProcess());
- if (process_sp) {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
- return true;
- }
- return false;
+ if (!process_sp)
+ return false;
+
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *this, m_signo, /*description=*/nullptr, m_code));
+ return true;
}
// Parse PRSTATUS from NOTE entry
@@ -409,8 +411,8 @@ Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
// 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);
+ si_code = data.GetU32(&offset);
return error;
}
diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
index 8d973bb840d25..2f3ed2a017790 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -128,6 +128,7 @@ struct ThreadData {
std::vector<lldb_private::CoreNote> notes;
lldb::tid_t tid;
int signo = 0;
+ int code = 0;
int prstatus_sig = 0;
std::string name;
};
@@ -166,6 +167,7 @@ class ThreadElfCore : public lldb_private::Thread {
lldb::RegisterContextSP m_thread_reg_ctx_sp;
int m_signo;
+ int m_code;
lldb_private::DataExtractor m_gpregset_data;
std::vector<lldb_private::CoreNote> m_notes;
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index ebc355c90d0ab..a98fc28c7338d 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -1044,8 +1044,9 @@ class StopInfoWatchpoint : public StopInfo {
class StopInfoUnixSignal : public StopInfo {
public:
- StopInfoUnixSignal(Thread &thread, int signo, const char *description)
- : StopInfo(thread, signo) {
+ StopInfoUnixSignal(Thread &thread, int signo, const char *description,
+ std::optional<int> code)
+ : StopInfo(thread, signo), m_code(code) {
SetDescription(description);
}
@@ -1100,19 +1101,26 @@ class StopInfoUnixSignal : public StopInfo {
if (m_description.empty()) {
ThreadSP thread_sp(m_thread_wp.lock());
if (thread_sp) {
+ UnixSignalsSP unix_signals = thread_sp->GetProcess()->GetUnixSignals();
StreamString strm;
- const char *signal_name =
- thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(
- m_value);
- if (signal_name)
- strm.Printf("signal %s", signal_name);
+ strm << "signal ";
+
+ std::string signal_name =
+ unix_signals->GetSignalDescription(m_value, m_code);
+ if (signal_name.size())
+ strm << signal_name;
else
- strm.Printf("signal %" PRIi64, m_value);
+ strm.Printf("%" PRIi64, m_value);
+
m_description = std::string(strm.GetString());
}
}
return m_description.c_str();
}
+
+private:
+ // In siginfo_t terms, if m_value is si_signo, m_code is si_code.
+ std::optional<int> m_code;
};
// StopInfoTrace
@@ -1371,9 +1379,10 @@ StopInfo::CreateStopReasonWithWatchpointID(Thread &thread, break_id_t watch_id,
}
StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo,
- const char *description) {
+ const char *description,
+ std::optional<int> code) {
thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo);
- return StopInfoSP(new StopInfoUnixSignal(thread, signo, description));
+ return StopInfoSP(new StopInfoUnixSignal(thread, signo, description, code));
}
StopInfoSP StopInfo::CreateStopReasonToTrace(Thread &thread) {
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
index a174616cd89d8..e742dd06b3f12 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
+++ b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
@@ -166,3 +166,14 @@ def test_mte_commands_no_mte(self):
# the MTE core file which does support it but does not allow writing tags.
self.expect("memory tag write 0 1",
substrs=["error: Process does not support memory tagging"], error=True)
+
+ @skipIfLLVMTargetMissing("AArch64")
+ def test_mte_tag_fault_reason(self):
+ """ Test that we correctly report the fault reason. """
+ self.runCmd("target create --core core.mte")
+
+ # There is no fault address shown here because core files do not include
+ # si_addr.
+ self.expect("bt", substrs=[
+ "* thread #1, name = 'a.out.mte', stop reason = signal SIGSEGV: "
+ "sync tag check fault"])
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 9d7b1dbd79ef1..d87d20704f166 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -221,6 +221,9 @@ Changes to LLDB
omit defaulted template parameters. The full template parameter list can still be
viewed with ``expr --raw-output``/``frame var --raw-output``. (`D141828 <https://reviews.llvm.org/D141828>`_)
+* LLDB is now able to show the subtype of signals found in a core file. For example
+ memory tagging specific segfaults such as ``SIGSEGV: sync tag check fault``.
+
Changes to Sanitizers
---------------------
More information about the lldb-commits
mailing list