Skip to content

Commit e8fbf55

Browse files
DavidSpickettAlexisPerry
authored andcommitted
[lldb] Don't call AddRemoteRegisters if the target XML did not include any registers (llvm#96907)
Fixes llvm#92541 When e69a3d1 added fallback register layouts, it assumed that the choices were target XML with registers, or no target XML at all. In the linked issue, a user has a debug stub that does have target XML, but it's missing register information. This caused us to finalize the register information using an empty set of registers got from target XML, then fail an assert when we attempted to add the fallback set. Since we think we've already completed the register information. This change adds a check to prevent that first call and expands the existing tests to check each architecture without target XML and with target XML missing register information.
1 parent d0811f1 commit e8fbf55

File tree

2 files changed

+74
-14
lines changed

2 files changed

+74
-14
lines changed

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4879,7 +4879,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
48794879
m_registers_enum_types.clear();
48804880
std::vector<DynamicRegisterInfo::Register> registers;
48814881
if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml",
4882-
registers))
4882+
registers) &&
4883+
// Target XML is not required to include register information.
4884+
!registers.empty())
48834885
AddRemoteRegisters(registers, arch_to_use);
48844886

48854887
return m_register_info_sp->GetNumRegisters() > 0;

lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py renamed to lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXMLRegisters.py

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Check that lldb falls back to default register layouts when the remote provides
3-
no target XML.
3+
no target XML or does not include registers in the target XML.
44
55
GPRS are passed to the responder to create register data to send back to lldb.
66
Registers in SUPPL are virtual registers based on those general ones. The tests
@@ -14,6 +14,8 @@
1414
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
1515

1616
import binascii
17+
from textwrap import dedent
18+
1719

1820
class MyResponder(MockGDBServerResponder):
1921
@staticmethod
@@ -22,8 +24,10 @@ def filecheck_to_blob(fc):
2224
val = l.split("0x")[1]
2325
yield binascii.b2a_hex(bytes(reversed(binascii.a2b_hex(val)))).decode()
2426

25-
def __init__(self, reg_data, halt_reason):
27+
def __init__(self, architecture, has_target_xml, reg_data, halt_reason):
2628
super().__init__()
29+
self.architecture = architecture
30+
self.has_target_xml = has_target_xml
2731
self.reg_data = "".join(self.filecheck_to_blob(reg_data))
2832
self.halt_reason = halt_reason
2933

@@ -36,13 +40,24 @@ def readRegisters(self):
3640
def haltReason(self):
3741
return self.halt_reason
3842

43+
def qXferRead(self, obj, annex, offset, length):
44+
if self.has_target_xml and annex == "target.xml":
45+
return (
46+
dedent(
47+
f"""\
48+
<?xml version="1.0"?>
49+
<target version="1.0">
50+
<architecture>{self.architecture}</architecture>
51+
</target>"""
52+
),
53+
False,
54+
)
55+
56+
return None, False
3957

40-
class TestGDBServerTargetXML(GDBRemoteTestBase):
41-
@skipIfRemote
42-
@skipIfLLVMTargetMissing("X86")
43-
def test_x86_64_regs(self):
44-
"""Test grabbing various x86_64 registers from gdbserver."""
4558

59+
class TestGDBServerTargetXML(GDBRemoteTestBase):
60+
def check_x86_64_regs(self, has_target_xml):
4661
GPRS = """
4762
CHECK-AMD64-DAG: rax = 0x0807060504030201
4863
CHECK-AMD64-DAG: rbx = 0x1817161514131211
@@ -125,6 +140,8 @@ def test_x86_64_regs(self):
125140
"""
126141

127142
self.server.responder = MyResponder(
143+
"x86-64",
144+
has_target_xml,
128145
GPRS,
129146
"T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
130147
)
@@ -155,10 +172,21 @@ def test_x86_64_regs(self):
155172
self.match("register read flags", ["eflags = 0x1c1b1a19"])
156173

157174
@skipIfRemote
158-
@skipIfLLVMTargetMissing("AArch64")
159-
def test_aarch64_regs(self):
160-
"""Test grabbing various aarch64 registers from gdbserver."""
175+
@skipIfLLVMTargetMissing("X86")
176+
def test_x86_64_regs_no_target_xml(self):
177+
"""Test grabbing various x86_64 registers from gdbserver when there
178+
is no target XML."""
179+
self.check_x86_64_regs(False)
180+
181+
@skipIfXmlSupportMissing
182+
@skipIfRemote
183+
@skipIfLLVMTargetMissing("X86")
184+
def test_x86_64_regs_no_register_info(self):
185+
"""Test grabbing various x86_64 registers from gdbserver when there
186+
is target XML but it does not include register info."""
187+
self.check_x86_64_regs(True)
161188

189+
def check_aarch64_regs(self, has_target_xml):
162190
GPRS = """
163191
CHECK-AARCH64-DAG: x0 = 0x0001020304050607
164192
CHECK-AARCH64-DAG: x1 = 0x0102030405060708
@@ -232,6 +260,8 @@ def test_aarch64_regs(self):
232260
"""
233261

234262
self.server.responder = MyResponder(
263+
"aarch64",
264+
has_target_xml,
235265
GPRS,
236266
"T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
237267
)
@@ -258,10 +288,21 @@ def test_aarch64_regs(self):
258288
self.match("register read flags", ["cpsr = 0x21222324"])
259289

260290
@skipIfRemote
261-
@skipIfLLVMTargetMissing("X86")
262-
def test_i386_regs(self):
263-
"""Test grabbing various i386 registers from gdbserver."""
291+
@skipIfLLVMTargetMissing("AArch64")
292+
def test_aarch64_regs_no_target_xml(self):
293+
"""Test grabbing various aarch64 registers from gdbserver when there
294+
is no target XML."""
295+
self.check_aarch64_regs(False)
296+
297+
@skipIfXmlSupportMissing
298+
@skipIfRemote
299+
@skipIfLLVMTargetMissing("AArch64")
300+
def test_aarch64_regs_no_register_info(self):
301+
"""Test grabbing various aarch64 registers from gdbserver when there
302+
is target XML but it does not include register info."""
303+
self.check_aarch64_regs(True)
264304

305+
def check_i386_regs(self, has_target_xml):
265306
GPRS = """
266307
CHECK-I386-DAG: eax = 0x04030201
267308
CHECK-I386-DAG: ecx = 0x14131211
@@ -307,6 +348,8 @@ def test_i386_regs(self):
307348
"""
308349

309350
self.server.responder = MyResponder(
351+
"i386",
352+
has_target_xml,
310353
GPRS,
311354
"T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;",
312355
)
@@ -329,3 +372,18 @@ def test_i386_regs(self):
329372
self.match("register read sp", ["esp = 0x44434241"])
330373
self.match("register read pc", ["eip = 0x84838281"])
331374
self.match("register read flags", ["eflags = 0x94939291"])
375+
376+
@skipIfRemote
377+
@skipIfLLVMTargetMissing("X86")
378+
def test_i386_regs_no_target_xml(self):
379+
"""Test grabbing various i386 registers from gdbserver when there is
380+
no target XML."""
381+
self.check_i386_regs(False)
382+
383+
@skipIfXmlSupportMissing
384+
@skipIfRemote
385+
@skipIfLLVMTargetMissing("X86")
386+
def test_i386_regs_no_register_info(self):
387+
"""Test grabbing various i386 registers from gdbserver when there is
388+
target XML but it does not include register info."""
389+
self.check_i386_regs(True)

0 commit comments

Comments
 (0)