3 from lldbsuite.test.lldbtest import *
4 from lldbsuite.test.decorators import *
5 from gdbclientutils import *
8 class TestGDBRemoteClient(GDBRemoteTestBase):
10 class gPacketResponder(MockGDBServerResponder):
11 def readRegisters(self):
12 return '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
15 super(TestGDBRemoteClient, self).setUp()
16 self._initial_platform = lldb.DBG.GetSelectedPlatform()
19 lldb.DBG.SetSelectedPlatform(self._initial_platform)
20 super(TestGDBRemoteClient, self).tearDown()
22 def test_connect(self):
23 """Test connecting to a remote gdb server"""
24 target = self.createTarget("a.yaml")
25 process = self.connect(target)
26 self.assertPacketLogContains(["qProcessInfo", "qfThreadInfo"])
28 def test_attach_fail(self):
29 error_msg = "mock-error-msg"
31 class MyResponder(MockGDBServerResponder):
32 # Pretend we don't have any process during the initial queries.
36 def qfThreadInfo(self):
37 return "OK" # No threads.
39 # Then, when we are asked to attach, error out.
40 def vAttach(self, pid):
41 return "E42;" + binascii.hexlify(error_msg.encode()).decode()
43 self.server.responder = MyResponder()
45 target = self.dbg.CreateTarget("")
46 process = self.connect(target)
47 lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected])
49 error = lldb.SBError()
50 target.AttachToProcessWithID(lldb.SBListener(), 47, error)
51 self.assertEquals(error_msg, error.GetCString())
53 def test_read_registers_using_g_packets(self):
54 """Test reading registers using 'g' packets (default behavior)"""
55 self.dbg.HandleCommand(
56 "settings set plugin.process.gdb-remote.use-g-packet-for-reading true")
57 self.addTearDownHook(lambda:
58 self.runCmd("settings set plugin.process.gdb-remote.use-g-packet-for-reading false"))
59 self.server.responder = self.gPacketResponder()
60 target = self.createTarget("a.yaml")
61 process = self.connect(target)
63 self.assertEquals(1, self.server.responder.packetLog.count("g"))
64 self.server.responder.packetLog = []
65 self.read_registers(process)
66 # Reading registers should not cause any 'p' packets to be exchanged.
68 0, len([p for p in self.server.responder.packetLog if p.startswith("p")]))
70 def test_read_registers_using_p_packets(self):
71 """Test reading registers using 'p' packets"""
72 self.dbg.HandleCommand(
73 "settings set plugin.process.gdb-remote.use-g-packet-for-reading false")
74 target = self.createTarget("a.yaml")
75 process = self.connect(target)
77 self.read_registers(process)
78 self.assertFalse("g" in self.server.responder.packetLog)
80 len([p for p in self.server.responder.packetLog if p.startswith("p")]), 0)
82 def test_write_registers_using_P_packets(self):
83 """Test writing registers using 'P' packets (default behavior)"""
84 self.server.responder = self.gPacketResponder()
85 target = self.createTarget("a.yaml")
86 process = self.connect(target)
88 self.write_registers(process)
89 self.assertEquals(0, len(
90 [p for p in self.server.responder.packetLog if p.startswith("G")]))
92 len([p for p in self.server.responder.packetLog if p.startswith("P")]), 0)
94 def test_write_registers_using_G_packets(self):
95 """Test writing registers using 'G' packets"""
97 class MyResponder(self.gPacketResponder):
98 def readRegister(self, register):
99 # empty string means unsupported
102 self.server.responder = MyResponder()
103 target = self.createTarget("a.yaml")
104 process = self.connect(target)
106 self.write_registers(process)
107 self.assertEquals(0, len(
108 [p for p in self.server.responder.packetLog if p.startswith("P")]))
109 self.assertGreater(len(
110 [p for p in self.server.responder.packetLog if p.startswith("G")]), 0)
112 def read_registers(self, process):
114 process, lambda r: self.assertEquals("0x00000000", r.GetValue()))
116 def write_registers(self, process):
118 process, lambda r: r.SetValueFromCString("0x00000000"))
120 def for_each_gpr(self, process, operation):
121 registers = process.GetThreadAtIndex(0).GetFrameAtIndex(0).GetRegisters()
122 self.assertGreater(registers.GetSize(), 0)
123 regSet = registers[0]
124 numChildren = regSet.GetNumChildren()
125 self.assertGreater(numChildren, 0)
126 for i in range(numChildren):
127 operation(regSet.GetChildAtIndex(i))