[lldb] Enable "frame diagnose" on linux (#123217)
.. by changing the signal stop reason format 🤦 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.
This commit is contained in:
parent
3ea2b546a8
commit
0236cb6895
@ -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 << ")";
|
||||
|
@ -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();
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
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
|
||||
|
@ -215,7 +215,7 @@ class AArch64LinuxMTEMemoryTagCoreFileTestCase(TestBase):
|
||||
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)"
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -51,8 +51,8 @@ class AArch64LinuxMTEMemoryTagFaultsTestCase(TestBase):
|
||||
"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\)"
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -202,7 +202,7 @@ class AArch64LinuxNonAddressBitMemoryAccessTestCase(TestBase):
|
||||
"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)",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
---------------------------------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user