[Lldb-commits] [lldb] 0236cb6 - [lldb] Enable "frame diagnose" on linux (#123217)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Jan 23 04:04:41 PST 2025
Author: Pavel Labath
Date: 2025-01-23T13:04:36+01:00
New Revision: 0236cb689550ed2dac406443c652efb723cb2602
URL: https://github.com/llvm/llvm-project/commit/0236cb689550ed2dac406443c652efb723cb2602
DIFF: https://github.com/llvm/llvm-project/commit/0236cb689550ed2dac406443c652efb723cb2602.diff
LOG: [lldb] Enable "frame diagnose" on linux (#123217)
.. by changing the signal stop reason format :facepalm:
The reason this did not work is because the code in
`StopInfo::GetCrashingDereference` was looking for the string "address="
to extract the address of the crash. Macos stop reason strings have the
form
```
EXC_BAD_ACCESS (code=1, address=0xdead)
```
while on linux they look like:
```
signal SIGSEGV: address not mapped to object (fault address: 0xdead)
```
Extracting the address from a string sounds like a bad idea, but I
suppose there's some value in using a consistent format across
platforms, so this patch changes the signal format to use the equals
sign as well. All of the diagnose tests pass except one, which appears
to fail due to something similar #115453 (disassembler reports
unrelocated call targets).
I've left the tests disabled on windows, as the stop reason reporting
code works very differently there, and I suspect it won't work out of
the box. If I'm wrong -- the XFAIL will let us know.
Added:
Modified:
lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
lldb/source/Target/UnixSignals.cpp
lldb/test/API/commands/frame/diagnose/array/TestArray.py
lldb/test/API/commands/frame/diagnose/bad-reference/TestBadReference.py
lldb/test/API/commands/frame/diagnose/complicated-expression/TestComplicatedExpression.py
lldb/test/API/commands/frame/diagnose/dereference-argument/TestDiagnoseDereferenceArgument.py
lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
lldb/test/API/commands/frame/diagnose/dereference-this/TestDiagnoseDereferenceThis.py
lldb/test/API/commands/frame/diagnose/inheritance/TestDiagnoseInheritance.py
lldb/test/API/commands/frame/diagnose/local-variable/TestLocalVariable.py
lldb/test/API/commands/frame/diagnose/virtual-method-call/TestDiagnoseDereferenceVirtualMethodCall.py
lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py
lldb/test/Shell/Register/Core/x86-32-linux-multithread.test
lldb/test/Shell/Register/Core/x86-64-linux-multithread.test
lldb/unittests/Signals/UnixSignalsTest.cpp
llvm/docs/ReleaseNotes.md
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index de047ee214c11e4..a6d6a78357fe5c1 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -326,14 +326,14 @@ void NativeThreadLinux::AnnotateSyncTagCheckFault(lldb::addr_t fault_addr) {
}
// We assume that the stop description is currently:
- // signal SIGSEGV: sync tag check fault (fault address: <addr>)
+ // signal SIGSEGV: sync tag check fault (fault address=<addr>)
// Remove the closing )
m_stop_description.pop_back();
std::stringstream ss;
std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
- ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr);
+ ss << " logical tag=0x" << std::hex << manager->GetLogicalTag(fault_addr);
std::vector<uint8_t> allocation_tag_data;
// The fault address may not be granule aligned. ReadMemoryTags will granule
@@ -347,7 +347,7 @@ void NativeThreadLinux::AnnotateSyncTagCheckFault(lldb::addr_t fault_addr) {
llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
manager->UnpackTagsData(allocation_tag_data, 1);
if (allocation_tag) {
- ss << " allocation tag: 0x" << std::hex << allocation_tag->front() << ")";
+ ss << " allocation tag=0x" << std::hex << allocation_tag->front() << ")";
} else {
llvm::consumeError(allocation_tag.takeError());
ss << ")";
diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp
index bee3a63818259ed..da661003925c79a 100644
--- a/lldb/source/Target/UnixSignals.cpp
+++ b/lldb/source/Target/UnixSignals.cpp
@@ -163,7 +163,7 @@ UnixSignals::GetSignalDescription(int32_t signo, std::optional<int32_t> code,
break;
case SignalCodePrintOption::Address:
if (addr)
- strm << " (fault address: 0x" << std::hex << *addr << ")";
+ strm << " (fault address=0x" << std::hex << *addr << ")";
break;
case SignalCodePrintOption::Bounds:
if (lower && upper && addr) {
@@ -172,9 +172,9 @@ UnixSignals::GetSignalDescription(int32_t signo, std::optional<int32_t> code,
else
strm << "upper bound violation ";
- strm << "(fault address: 0x" << std::hex << *addr;
- strm << ", lower bound: 0x" << std::hex << *lower;
- strm << ", upper bound: 0x" << std::hex << *upper;
+ strm << "(fault address=0x" << std::hex << *addr;
+ strm << ", lower bound=0x" << std::hex << *lower;
+ strm << ", upper bound=0x" << std::hex << *upper;
strm << ")";
} else
strm << sc.m_description.str();
diff --git a/lldb/test/API/commands/frame/diagnose/array/TestArray.py b/lldb/test/API/commands/frame/diagnose/array/TestArray.py
index 5de6f7b0aaa1c4e..307e2cbca302281 100644
--- a/lldb/test/API/commands/frame/diagnose/array/TestArray.py
+++ b/lldb/test/API/commands/frame/diagnose/array/TestArray.py
@@ -10,7 +10,7 @@
class TestArray(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/bad-reference/TestBadReference.py b/lldb/test/API/commands/frame/diagnose/bad-reference/TestBadReference.py
index 7a9498cab137663..8ded5e2ff55c214 100644
--- a/lldb/test/API/commands/frame/diagnose/bad-reference/TestBadReference.py
+++ b/lldb/test/API/commands/frame/diagnose/bad-reference/TestBadReference.py
@@ -10,7 +10,7 @@
class TestBadReference(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/complicated-expression/TestComplicatedExpression.py b/lldb/test/API/commands/frame/diagnose/complicated-expression/TestComplicatedExpression.py
index eb1b556f0c408d3..8ee254a28cb5454 100644
--- a/lldb/test/API/commands/frame/diagnose/complicated-expression/TestComplicatedExpression.py
+++ b/lldb/test/API/commands/frame/diagnose/complicated-expression/TestComplicatedExpression.py
@@ -10,7 +10,7 @@
class TestDiagnoseDereferenceArgument(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/dereference-argument/TestDiagnoseDereferenceArgument.py b/lldb/test/API/commands/frame/diagnose/dereference-argument/TestDiagnoseDereferenceArgument.py
index 4e8673543438790..960dd99ff7f78b8 100644
--- a/lldb/test/API/commands/frame/diagnose/dereference-argument/TestDiagnoseDereferenceArgument.py
+++ b/lldb/test/API/commands/frame/diagnose/dereference-argument/TestDiagnoseDereferenceArgument.py
@@ -10,7 +10,7 @@
class TestDiagnoseDereferenceArgument(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
index 4d9b036f5102cb6..d0f6ebefa334ad3 100644
--- a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
+++ b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
@@ -10,7 +10,7 @@
class TestDiagnoseDereferenceFunctionReturn(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=no_match(lldbplatformutil.getDarwinOSTriples()))
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/dereference-this/TestDiagnoseDereferenceThis.py b/lldb/test/API/commands/frame/diagnose/dereference-this/TestDiagnoseDereferenceThis.py
index fccba5ca116a9a7..7a4d3fb2acb5c64 100644
--- a/lldb/test/API/commands/frame/diagnose/dereference-this/TestDiagnoseDereferenceThis.py
+++ b/lldb/test/API/commands/frame/diagnose/dereference-this/TestDiagnoseDereferenceThis.py
@@ -10,7 +10,7 @@
class TestDiagnoseDereferenceThis(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/inheritance/TestDiagnoseInheritance.py b/lldb/test/API/commands/frame/diagnose/inheritance/TestDiagnoseInheritance.py
index 01245ff7608e1bc..71a24002a06274b 100644
--- a/lldb/test/API/commands/frame/diagnose/inheritance/TestDiagnoseInheritance.py
+++ b/lldb/test/API/commands/frame/diagnose/inheritance/TestDiagnoseInheritance.py
@@ -10,7 +10,7 @@
class TestDiagnoseInheritance(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/local-variable/TestLocalVariable.py b/lldb/test/API/commands/frame/diagnose/local-variable/TestLocalVariable.py
index 9361d80367e1280..2db054bec991905 100644
--- a/lldb/test/API/commands/frame/diagnose/local-variable/TestLocalVariable.py
+++ b/lldb/test/API/commands/frame/diagnose/local-variable/TestLocalVariable.py
@@ -10,7 +10,7 @@
class TestLocalVariable(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
diff --git a/lldb/test/API/commands/frame/diagnose/virtual-method-call/TestDiagnoseDereferenceVirtualMethodCall.py b/lldb/test/API/commands/frame/diagnose/virtual-method-call/TestDiagnoseDereferenceVirtualMethodCall.py
index 7a58203d8f2ed52..ef99b72f52afde0 100644
--- a/lldb/test/API/commands/frame/diagnose/virtual-method-call/TestDiagnoseDereferenceVirtualMethodCall.py
+++ b/lldb/test/API/commands/frame/diagnose/virtual-method-call/TestDiagnoseDereferenceVirtualMethodCall.py
@@ -10,7 +10,7 @@
class TestDiagnoseVirtualMethodCall(TestBase):
- @skipUnlessDarwin
+ @expectedFailureAll(oslist=["windows"])
@skipIf(
archs=no_match(["x86_64"])
) # <rdar://problem/33842388> frame diagnose doesn't work for armv7 or arm64
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 779050edb054a42..6309648819026ac 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
+++ b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
@@ -215,7 +215,7 @@ def test_mte_tag_fault_reason(self):
self.expect(
"bt",
substrs=[
- "* thread #1, name = 'a.out.mte', stop reason = SIGSEGV: sync tag check fault (fault address: 0xffff82c74010)"
+ "* thread #1, name = 'a.out.mte', stop reason = SIGSEGV: sync tag check fault (fault address=0xffff82c74010)"
],
)
diff --git a/lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py b/lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
index 420aae482348886..2d6470505cf7c49 100644
--- a/lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
+++ b/lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
@@ -51,8 +51,8 @@ def test_mte_tag_fault_sync(self):
"continue",
patterns=[
"\* thread #1, name = 'a.out', stop reason = signal SIGSEGV: "
- "sync tag check fault \(fault address: 0x9[0-9A-Fa-f]+11\ "
- "logical tag: 0x9 allocation tag: 0xa\)"
+ "sync tag check fault \(fault address=0x9[0-9A-Fa-f]+11\ "
+ "logical tag=0x9 allocation tag=0xa\)"
],
)
diff --git a/lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py b/lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py
index 668fca11903660e..f27780358570bbf 100644
--- a/lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py
+++ b/lldb/test/API/linux/aarch64/non_address_bit_memory_access/TestAArch64LinuxNonAddressBitMemoryAccess.py
@@ -202,7 +202,7 @@ def test_non_address_bit_memory_corefile(self):
"thread list",
substrs=[
"stopped",
- "stop reason = SIGSEGV: address not mapped to object (fault address: 0x0)",
+ "stop reason = SIGSEGV: address not mapped to object (fault address=0x0)",
],
)
diff --git a/lldb/test/Shell/Register/Core/x86-32-linux-multithread.test b/lldb/test/Shell/Register/Core/x86-32-linux-multithread.test
index eb0cf8708263cb2..972e10844a5aade 100644
--- a/lldb/test/Shell/Register/Core/x86-32-linux-multithread.test
+++ b/lldb/test/Shell/Register/Core/x86-32-linux-multithread.test
@@ -1,7 +1,7 @@
# RUN: %lldb -b -s %s -c %p/Inputs/x86-32-linux-multithread.core | FileCheck %s
thread list
-# CHECK: * thread #1: tid = 330633, 0x080492d2, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address: 0x0)
+# CHECK: * thread #1: tid = 330633, 0x080492d2, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address=0x0)
# CHECK-NEXT: thread #2: tid = 330634, 0x080492dd, stop reason = signal 0
# CHECK-NEXT: thread #3: tid = 330635, 0x080492dd, stop reason = signal 0
# CHECK-NEXT: thread #4: tid = 330632, 0xf7f59549, stop reason = signal 0
diff --git a/lldb/test/Shell/Register/Core/x86-64-linux-multithread.test b/lldb/test/Shell/Register/Core/x86-64-linux-multithread.test
index a94a4de1c8080b5..5bea84813b44fed 100644
--- a/lldb/test/Shell/Register/Core/x86-64-linux-multithread.test
+++ b/lldb/test/Shell/Register/Core/x86-64-linux-multithread.test
@@ -1,7 +1,7 @@
# RUN: %lldb -b -s %s -c %p/Inputs/x86-64-linux-multithread.core | FileCheck %s
thread list
-# CHECK: * thread #1: tid = 329384, 0x0000000000401262, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address: 0x0)
+# CHECK: * thread #1: tid = 329384, 0x0000000000401262, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address=0x0)
# CHECK-NEXT: thread #2: tid = 329385, 0x000000000040126d, stop reason = signal 0
# CHECK-NEXT: thread #3: tid = 329386, 0x000000000040126d, stop reason = signal 0
# CHECK-NEXT: thread #4: tid = 329383, 0x00007fcf5582f762, stop reason = signal 0
diff --git a/lldb/unittests/Signals/UnixSignalsTest.cpp b/lldb/unittests/Signals/UnixSignalsTest.cpp
index acd392869225013..9a7d9afc2b1859d 100644
--- a/lldb/unittests/Signals/UnixSignalsTest.cpp
+++ b/lldb/unittests/Signals/UnixSignalsTest.cpp
@@ -119,7 +119,7 @@ TEST(UnixSignalsTest, GetAsString) {
ASSERT_EQ("SIG16: a specific type of SIG16",
signals.GetSignalDescription(16, 1, 0xCAFEF00D));
// Known code that should.
- ASSERT_EQ("SIG16: SIG16 with a fault address (fault address: 0xcafef00d)",
+ ASSERT_EQ("SIG16: SIG16 with a fault address (fault address=0xcafef00d)",
signals.GetSignalDescription(16, 2, 0xCAFEF00D));
// No address given just print the code description.
ASSERT_EQ("SIG16: SIG16 with a fault address",
@@ -131,11 +131,11 @@ TEST(UnixSignalsTest, GetAsString) {
ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d));
ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d, 0x1234));
- ASSERT_EQ("SIG16: upper bound violation (fault address: 0x5679, lower bound: "
- "0x1234, upper bound: 0x5678)",
+ ASSERT_EQ("SIG16: upper bound violation (fault address=0x5679, lower bound="
+ "0x1234, upper bound=0x5678)",
signals.GetSignalDescription(16, 3, 0x5679, 0x1234, 0x5678));
- ASSERT_EQ("SIG16: lower bound violation (fault address: 0x1233, lower bound: "
- "0x1234, upper bound: 0x5678)",
+ ASSERT_EQ("SIG16: lower bound violation (fault address=0x1233, lower bound="
+ "0x1234, upper bound=0x5678)",
signals.GetSignalDescription(16, 3, 0x1233, 0x1234, 0x5678));
}
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index eb6e9c9b75beb57..05d902641d0933b 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -532,7 +532,7 @@ Changes to LLDB
New:
```
- * thread #1: tid = 329384, 0x0000000000401262, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address: 0x0)
+ * thread #1: tid = 329384, 0x0000000000401262, name = 'a.out', stop reason = SIGSEGV: address not mapped to object (fault address=0x0)
0x7f1e3193e0a7 <+23>: ja 0x7f1e3193e100 ; <+112>
```
@@ -555,6 +555,24 @@ Changes to LLDB
* Incorrect floating-point register dwarf number for LoongArch is [fixed](https://github.com/llvm/llvm-project/pull/120391).
+* The `frame diagnose` now works on ELF-based systems. After a crash, LLDB will
+ try to determine the likely cause of the signal, matching Darwin behavior.
+ This feature requires using a new `lldb-server` version and (like Darwin) only
+ works on x86 binaries.
+
+ ```
+ * thread #1, name = 'a.out', stop reason = signal SIGSEGV: address not mapped to object (fault address=0x4)
+ frame #0: 0x00005555555551aa a.out`GetSum(f=0x0000555555558018) at main.c:21:37
+ 18 }
+ 19
+ 20 int GetSum(struct Foo *f) {
+ -> 21 return SumTwoIntegers(f->a, f->b->d ? 0 : 1);
+ 22 }
+ 23
+ 24 int main() {
+ Likely cause: f->b->d accessed 0x4
+ ```
+
Changes to BOLT
---------------------------------
More information about the lldb-commits
mailing list