199451b44SJordan Rupprechtimport lldb 299451b44SJordan Rupprechtimport binascii 3784281d3SMichał Górnyimport os.path 499451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 599451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 633c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import * 733c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 899451b44SJordan Rupprecht 999451b44SJordan Rupprecht 1099451b44SJordan Rupprechtclass TestGDBRemoteClient(GDBRemoteTestBase): 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht class gPacketResponder(MockGDBServerResponder): 13270c989fSMichał Górny registers = [ 14270c989fSMichał Górny "name:rax;bitsize:64;offset:0;encoding:uint;format:hex;set:General Purpose Registers;ehframe:0;dwarf:0;", 15270c989fSMichał Górny "name:rbx;bitsize:64;offset:8;encoding:uint;format:hex;set:General Purpose Registers;ehframe:3;dwarf:3;", 16270c989fSMichał Górny "name:rcx;bitsize:64;offset:16;encoding:uint;format:hex;set:General Purpose Registers;ehframe:2;dwarf:2;generic:arg4;", 17270c989fSMichał Górny "name:rdx;bitsize:64;offset:24;encoding:uint;format:hex;set:General Purpose Registers;ehframe:1;dwarf:1;generic:arg3;", 18270c989fSMichał Górny "name:rdi;bitsize:64;offset:32;encoding:uint;format:hex;set:General Purpose Registers;ehframe:5;dwarf:5;generic:arg1;", 19270c989fSMichał Górny "name:rsi;bitsize:64;offset:40;encoding:uint;format:hex;set:General Purpose Registers;ehframe:4;dwarf:4;generic:arg2;", 20270c989fSMichał Górny "name:rbp;bitsize:64;offset:48;encoding:uint;format:hex;set:General Purpose Registers;ehframe:6;dwarf:6;generic:fp;", 21270c989fSMichał Górny "name:rsp;bitsize:64;offset:56;encoding:uint;format:hex;set:General Purpose Registers;ehframe:7;dwarf:7;generic:sp;", 22270c989fSMichał Górny ] 23270c989fSMichał Górny 24270c989fSMichał Górny def qRegisterInfo(self, num): 25270c989fSMichał Górny try: 26270c989fSMichał Górny return self.registers[num] 27270c989fSMichał Górny except IndexError: 28270c989fSMichał Górny return "E45" 29270c989fSMichał Górny 3099451b44SJordan Rupprecht def readRegisters(self): 31270c989fSMichał Górny return len(self.registers) * 16 * '0' 32270c989fSMichał Górny 33270c989fSMichał Górny def readRegister(self, register): 34270c989fSMichał Górny return "0000000000000000" 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht def test_connect(self): 3799451b44SJordan Rupprecht """Test connecting to a remote gdb server""" 3899451b44SJordan Rupprecht target = self.createTarget("a.yaml") 3999451b44SJordan Rupprecht process = self.connect(target) 4099451b44SJordan Rupprecht self.assertPacketLogContains(["qProcessInfo", "qfThreadInfo"]) 4199451b44SJordan Rupprecht 4299451b44SJordan Rupprecht def test_attach_fail(self): 4399451b44SJordan Rupprecht error_msg = "mock-error-msg" 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht class MyResponder(MockGDBServerResponder): 4699451b44SJordan Rupprecht # Pretend we don't have any process during the initial queries. 4799451b44SJordan Rupprecht def qC(self): 4899451b44SJordan Rupprecht return "E42" 4999451b44SJordan Rupprecht 5099451b44SJordan Rupprecht def qfThreadInfo(self): 5199451b44SJordan Rupprecht return "OK" # No threads. 5299451b44SJordan Rupprecht 5399451b44SJordan Rupprecht # Then, when we are asked to attach, error out. 5499451b44SJordan Rupprecht def vAttach(self, pid): 5599451b44SJordan Rupprecht return "E42;" + binascii.hexlify(error_msg.encode()).decode() 5699451b44SJordan Rupprecht 5799451b44SJordan Rupprecht self.server.responder = MyResponder() 5899451b44SJordan Rupprecht 5999451b44SJordan Rupprecht target = self.dbg.CreateTarget("") 6099451b44SJordan Rupprecht process = self.connect(target) 6199451b44SJordan Rupprecht lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht error = lldb.SBError() 6499451b44SJordan Rupprecht target.AttachToProcessWithID(lldb.SBListener(), 47, error) 6599451b44SJordan Rupprecht self.assertEquals(error_msg, error.GetCString()) 6699451b44SJordan Rupprecht 6765e843c9SPavel Labath def test_launch_fail(self): 6865e843c9SPavel Labath class MyResponder(MockGDBServerResponder): 6965e843c9SPavel Labath # Pretend we don't have any process during the initial queries. 7065e843c9SPavel Labath def qC(self): 7165e843c9SPavel Labath return "E42" 7265e843c9SPavel Labath 7365e843c9SPavel Labath def qfThreadInfo(self): 7465e843c9SPavel Labath return "OK" # No threads. 7565e843c9SPavel Labath 7665e843c9SPavel Labath # Then, when we are asked to attach, error out. 7765e843c9SPavel Labath def A(self, packet): 7865e843c9SPavel Labath return "E47" 7965e843c9SPavel Labath 8065e843c9SPavel Labath self.server.responder = MyResponder() 8165e843c9SPavel Labath 8265e843c9SPavel Labath target = self.createTarget("a.yaml") 8365e843c9SPavel Labath process = self.connect(target) 8465e843c9SPavel Labath lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) 8565e843c9SPavel Labath 8665e843c9SPavel Labath error = lldb.SBError() 8765e843c9SPavel Labath target.Launch(lldb.SBListener(), None, None, None, None, None, 8865e843c9SPavel Labath None, 0, True, error) 8983bea6d9SJason Molenda self.assertEquals("'A' packet returned an error: 71", error.GetCString()) 9065e843c9SPavel Labath 9199451b44SJordan Rupprecht def test_read_registers_using_g_packets(self): 9299451b44SJordan Rupprecht """Test reading registers using 'g' packets (default behavior)""" 9399451b44SJordan Rupprecht self.dbg.HandleCommand( 9499451b44SJordan Rupprecht "settings set plugin.process.gdb-remote.use-g-packet-for-reading true") 9599451b44SJordan Rupprecht self.addTearDownHook(lambda: 9699451b44SJordan Rupprecht self.runCmd("settings set plugin.process.gdb-remote.use-g-packet-for-reading false")) 9799451b44SJordan Rupprecht self.server.responder = self.gPacketResponder() 9899451b44SJordan Rupprecht target = self.createTarget("a.yaml") 9999451b44SJordan Rupprecht process = self.connect(target) 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht self.assertEquals(1, self.server.responder.packetLog.count("g")) 10299451b44SJordan Rupprecht self.server.responder.packetLog = [] 10399451b44SJordan Rupprecht self.read_registers(process) 10499451b44SJordan Rupprecht # Reading registers should not cause any 'p' packets to be exchanged. 10599451b44SJordan Rupprecht self.assertEquals( 10699451b44SJordan Rupprecht 0, len([p for p in self.server.responder.packetLog if p.startswith("p")])) 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht def test_read_registers_using_p_packets(self): 10999451b44SJordan Rupprecht """Test reading registers using 'p' packets""" 11099451b44SJordan Rupprecht self.dbg.HandleCommand( 11199451b44SJordan Rupprecht "settings set plugin.process.gdb-remote.use-g-packet-for-reading false") 112270c989fSMichał Górny self.server.responder = self.gPacketResponder() 11399451b44SJordan Rupprecht target = self.createTarget("a.yaml") 11499451b44SJordan Rupprecht process = self.connect(target) 11599451b44SJordan Rupprecht 11699451b44SJordan Rupprecht self.read_registers(process) 1173cc37622SDave Lee self.assertNotIn("g", self.server.responder.packetLog) 11899451b44SJordan Rupprecht self.assertGreater( 11999451b44SJordan Rupprecht len([p for p in self.server.responder.packetLog if p.startswith("p")]), 0) 12099451b44SJordan Rupprecht 12199451b44SJordan Rupprecht def test_write_registers_using_P_packets(self): 12299451b44SJordan Rupprecht """Test writing registers using 'P' packets (default behavior)""" 12399451b44SJordan Rupprecht self.server.responder = self.gPacketResponder() 12499451b44SJordan Rupprecht target = self.createTarget("a.yaml") 12599451b44SJordan Rupprecht process = self.connect(target) 12699451b44SJordan Rupprecht 12799451b44SJordan Rupprecht self.write_registers(process) 12899451b44SJordan Rupprecht self.assertEquals(0, len( 12999451b44SJordan Rupprecht [p for p in self.server.responder.packetLog if p.startswith("G")])) 13099451b44SJordan Rupprecht self.assertGreater( 13199451b44SJordan Rupprecht len([p for p in self.server.responder.packetLog if p.startswith("P")]), 0) 13299451b44SJordan Rupprecht 13399451b44SJordan Rupprecht def test_write_registers_using_G_packets(self): 13499451b44SJordan Rupprecht """Test writing registers using 'G' packets""" 13599451b44SJordan Rupprecht 13699451b44SJordan Rupprecht class MyResponder(self.gPacketResponder): 13799451b44SJordan Rupprecht def readRegister(self, register): 13899451b44SJordan Rupprecht # empty string means unsupported 13999451b44SJordan Rupprecht return "" 14099451b44SJordan Rupprecht 14199451b44SJordan Rupprecht self.server.responder = MyResponder() 14299451b44SJordan Rupprecht target = self.createTarget("a.yaml") 14399451b44SJordan Rupprecht process = self.connect(target) 14499451b44SJordan Rupprecht 14599451b44SJordan Rupprecht self.write_registers(process) 14699451b44SJordan Rupprecht self.assertEquals(0, len( 14799451b44SJordan Rupprecht [p for p in self.server.responder.packetLog if p.startswith("P")])) 14899451b44SJordan Rupprecht self.assertGreater(len( 14999451b44SJordan Rupprecht [p for p in self.server.responder.packetLog if p.startswith("G")]), 0) 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht def read_registers(self, process): 15299451b44SJordan Rupprecht self.for_each_gpr( 153270c989fSMichał Górny process, lambda r: self.assertEquals("0x0000000000000000", r.GetValue())) 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht def write_registers(self, process): 15699451b44SJordan Rupprecht self.for_each_gpr( 157270c989fSMichał Górny process, lambda r: r.SetValueFromCString("0x0000000000000000")) 15899451b44SJordan Rupprecht 15999451b44SJordan Rupprecht def for_each_gpr(self, process, operation): 16099451b44SJordan Rupprecht registers = process.GetThreadAtIndex(0).GetFrameAtIndex(0).GetRegisters() 16199451b44SJordan Rupprecht self.assertGreater(registers.GetSize(), 0) 16299451b44SJordan Rupprecht regSet = registers[0] 16399451b44SJordan Rupprecht numChildren = regSet.GetNumChildren() 16499451b44SJordan Rupprecht self.assertGreater(numChildren, 0) 16599451b44SJordan Rupprecht for i in range(numChildren): 16699451b44SJordan Rupprecht operation(regSet.GetChildAtIndex(i)) 1676ba3f723SMichał Górny 1686ba3f723SMichał Górny def test_launch_A(self): 1696ba3f723SMichał Górny class MyResponder(MockGDBServerResponder): 1706ba3f723SMichał Górny def __init__(self, *args, **kwargs): 1716ba3f723SMichał Górny self.started = False 1726ba3f723SMichał Górny return super().__init__(*args, **kwargs) 1736ba3f723SMichał Górny 1746ba3f723SMichał Górny def qC(self): 1756ba3f723SMichał Górny if self.started: 1766ba3f723SMichał Górny return "QCp10.10" 1776ba3f723SMichał Górny else: 1786ba3f723SMichał Górny return "E42" 1796ba3f723SMichał Górny 1806ba3f723SMichał Górny def qfThreadInfo(self): 1816ba3f723SMichał Górny if self.started: 1826ba3f723SMichał Górny return "mp10.10" 1836ba3f723SMichał Górny else: 1846ba3f723SMichał Górny return "E42" 1856ba3f723SMichał Górny 1866ba3f723SMichał Górny def qsThreadInfo(self): 1876ba3f723SMichał Górny return "l" 1886ba3f723SMichał Górny 1896ba3f723SMichał Górny def A(self, packet): 1906ba3f723SMichał Górny self.started = True 1916ba3f723SMichał Górny return "OK" 1926ba3f723SMichał Górny 1936ba3f723SMichał Górny def qLaunchSuccess(self): 1946ba3f723SMichał Górny if self.started: 1956ba3f723SMichał Górny return "OK" 1966ba3f723SMichał Górny return "E42" 1976ba3f723SMichał Górny 1986ba3f723SMichał Górny self.server.responder = MyResponder() 1996ba3f723SMichał Górny 2006ba3f723SMichał Górny target = self.createTarget("a.yaml") 201784281d3SMichał Górny # NB: apparently GDB packets are using "/" on Windows too 202784281d3SMichał Górny exe_path = self.getBuildArtifact("a").replace(os.path.sep, '/') 2036ba3f723SMichał Górny exe_hex = binascii.b2a_hex(exe_path.encode()).decode() 2046ba3f723SMichał Górny process = self.connect(target) 2056ba3f723SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 2066ba3f723SMichał Górny [lldb.eStateConnected]) 2076ba3f723SMichał Górny 2086ba3f723SMichał Górny target.Launch(lldb.SBListener(), 2096ba3f723SMichał Górny ["arg1", "arg2", "arg3"], # argv 2106ba3f723SMichał Górny [], # envp 2116ba3f723SMichał Górny None, # stdin_path 2126ba3f723SMichał Górny None, # stdout_path 2136ba3f723SMichał Górny None, # stderr_path 2146ba3f723SMichał Górny None, # working_directory 2156ba3f723SMichał Górny 0, # launch_flags 2166ba3f723SMichał Górny True, # stop_at_entry 2176ba3f723SMichał Górny lldb.SBError()) # error 2186ba3f723SMichał Górny self.assertTrue(process, PROCESS_IS_VALID) 2196ba3f723SMichał Górny self.assertEqual(process.GetProcessID(), 16) 2206ba3f723SMichał Górny 2216ba3f723SMichał Górny self.assertPacketLogContains([ 2226ba3f723SMichał Górny "A%d,0,%s,8,1,61726731,8,2,61726732,8,3,61726733" % ( 2236ba3f723SMichał Górny len(exe_hex), exe_hex), 2246ba3f723SMichał Górny ]) 2256ba3f723SMichał Górny 2266ba3f723SMichał Górny def test_launch_vRun(self): 2276ba3f723SMichał Górny class MyResponder(MockGDBServerResponder): 2286ba3f723SMichał Górny def __init__(self, *args, **kwargs): 2296ba3f723SMichał Górny self.started = False 2306ba3f723SMichał Górny return super().__init__(*args, **kwargs) 2316ba3f723SMichał Górny 2326ba3f723SMichał Górny def qC(self): 2336ba3f723SMichał Górny if self.started: 2346ba3f723SMichał Górny return "QCp10.10" 2356ba3f723SMichał Górny else: 2366ba3f723SMichał Górny return "E42" 2376ba3f723SMichał Górny 2386ba3f723SMichał Górny def qfThreadInfo(self): 2396ba3f723SMichał Górny if self.started: 2406ba3f723SMichał Górny return "mp10.10" 2416ba3f723SMichał Górny else: 2426ba3f723SMichał Górny return "E42" 2436ba3f723SMichał Górny 2446ba3f723SMichał Górny def qsThreadInfo(self): 2456ba3f723SMichał Górny return "l" 2466ba3f723SMichał Górny 2476ba3f723SMichał Górny def vRun(self, packet): 2486ba3f723SMichał Górny self.started = True 2496ba3f723SMichał Górny return "T13" 2506ba3f723SMichał Górny 2516ba3f723SMichał Górny def A(self, packet): 2526ba3f723SMichał Górny return "E28" 2536ba3f723SMichał Górny 2546ba3f723SMichał Górny self.server.responder = MyResponder() 2556ba3f723SMichał Górny 2566ba3f723SMichał Górny target = self.createTarget("a.yaml") 257784281d3SMichał Górny # NB: apparently GDB packets are using "/" on Windows too 258784281d3SMichał Górny exe_path = self.getBuildArtifact("a").replace(os.path.sep, '/') 2596ba3f723SMichał Górny exe_hex = binascii.b2a_hex(exe_path.encode()).decode() 2606ba3f723SMichał Górny process = self.connect(target) 2616ba3f723SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 2626ba3f723SMichał Górny [lldb.eStateConnected]) 2636ba3f723SMichał Górny 2646ba3f723SMichał Górny process = target.Launch(lldb.SBListener(), 2656ba3f723SMichał Górny ["arg1", "arg2", "arg3"], # argv 2666ba3f723SMichał Górny [], # envp 2676ba3f723SMichał Górny None, # stdin_path 2686ba3f723SMichał Górny None, # stdout_path 2696ba3f723SMichał Górny None, # stderr_path 2706ba3f723SMichał Górny None, # working_directory 2716ba3f723SMichał Górny 0, # launch_flags 2726ba3f723SMichał Górny True, # stop_at_entry 2736ba3f723SMichał Górny lldb.SBError()) # error 2746ba3f723SMichał Górny self.assertTrue(process, PROCESS_IS_VALID) 2756ba3f723SMichał Górny self.assertEqual(process.GetProcessID(), 16) 2766ba3f723SMichał Górny 2776ba3f723SMichał Górny self.assertPacketLogContains([ 2786ba3f723SMichał Górny "vRun;%s;61726731;61726732;61726733" % (exe_hex,) 2796ba3f723SMichał Górny ]) 2803fade954SMichał Górny 2813fade954SMichał Górny def test_launch_QEnvironment(self): 2823fade954SMichał Górny class MyResponder(MockGDBServerResponder): 2833fade954SMichał Górny def qC(self): 2843fade954SMichał Górny return "E42" 2853fade954SMichał Górny 2863fade954SMichał Górny def qfThreadInfo(self): 2873fade954SMichał Górny return "E42" 2883fade954SMichał Górny 2893fade954SMichał Górny def vRun(self, packet): 2903fade954SMichał Górny self.started = True 2913fade954SMichał Górny return "E28" 2923fade954SMichał Górny 2933fade954SMichał Górny self.server.responder = MyResponder() 2943fade954SMichał Górny 2953fade954SMichał Górny target = self.createTarget("a.yaml") 2963fade954SMichał Górny process = self.connect(target) 2973fade954SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 2983fade954SMichał Górny [lldb.eStateConnected]) 2993fade954SMichał Górny 3003fade954SMichał Górny target.Launch(lldb.SBListener(), 3013fade954SMichał Górny [], # argv 3023fade954SMichał Górny ["PLAIN=foo", 3033fade954SMichał Górny "NEEDSENC=frob$", 3043fade954SMichał Górny "NEEDSENC2=fr*ob", 3053fade954SMichał Górny "NEEDSENC3=fro}b", 3063fade954SMichał Górny "NEEDSENC4=f#rob", 3073fade954SMichał Górny "EQUALS=foo=bar", 3083fade954SMichał Górny ], # envp 3093fade954SMichał Górny None, # stdin_path 3103fade954SMichał Górny None, # stdout_path 3113fade954SMichał Górny None, # stderr_path 3123fade954SMichał Górny None, # working_directory 3133fade954SMichał Górny 0, # launch_flags 3143fade954SMichał Górny True, # stop_at_entry 3153fade954SMichał Górny lldb.SBError()) # error 3163fade954SMichał Górny 3173fade954SMichał Górny self.assertPacketLogContains([ 3183fade954SMichał Górny "QEnvironment:PLAIN=foo", 3193fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e433d66726f6224", 3203fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43323d66722a6f62", 3213fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43333d66726f7d62", 3223fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43343d6623726f62", 3233fade954SMichał Górny "QEnvironment:EQUALS=foo=bar", 3243fade954SMichał Górny ]) 3253fade954SMichał Górny 3263fade954SMichał Górny def test_launch_QEnvironmentHexEncoded_only(self): 3273fade954SMichał Górny class MyResponder(MockGDBServerResponder): 3283fade954SMichał Górny def qC(self): 3293fade954SMichał Górny return "E42" 3303fade954SMichał Górny 3313fade954SMichał Górny def qfThreadInfo(self): 3323fade954SMichał Górny return "E42" 3333fade954SMichał Górny 3343fade954SMichał Górny def vRun(self, packet): 3353fade954SMichał Górny self.started = True 3363fade954SMichał Górny return "E28" 3373fade954SMichał Górny 3383fade954SMichał Górny def QEnvironment(self, packet): 3393fade954SMichał Górny return "" 3403fade954SMichał Górny 3413fade954SMichał Górny self.server.responder = MyResponder() 3423fade954SMichał Górny 3433fade954SMichał Górny target = self.createTarget("a.yaml") 3443fade954SMichał Górny process = self.connect(target) 3453fade954SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 3463fade954SMichał Górny [lldb.eStateConnected]) 3473fade954SMichał Górny 3483fade954SMichał Górny target.Launch(lldb.SBListener(), 3493fade954SMichał Górny [], # argv 3503fade954SMichał Górny ["PLAIN=foo", 3513fade954SMichał Górny "NEEDSENC=frob$", 3523fade954SMichał Górny "NEEDSENC2=fr*ob", 3533fade954SMichał Górny "NEEDSENC3=fro}b", 3543fade954SMichał Górny "NEEDSENC4=f#rob", 3553fade954SMichał Górny "EQUALS=foo=bar", 3563fade954SMichał Górny ], # envp 3573fade954SMichał Górny None, # stdin_path 3583fade954SMichał Górny None, # stdout_path 3593fade954SMichał Górny None, # stderr_path 3603fade954SMichał Górny None, # working_directory 3613fade954SMichał Górny 0, # launch_flags 3623fade954SMichał Górny True, # stop_at_entry 3633fade954SMichał Górny lldb.SBError()) # error 3643fade954SMichał Górny 3653fade954SMichał Górny self.assertPacketLogContains([ 3663fade954SMichał Górny "QEnvironmentHexEncoded:504c41494e3d666f6f", 3673fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e433d66726f6224", 3683fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43323d66722a6f62", 3693fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43333d66726f7d62", 3703fade954SMichał Górny "QEnvironmentHexEncoded:4e45454453454e43343d6623726f62", 3713fade954SMichał Górny "QEnvironmentHexEncoded:455155414c533d666f6f3d626172", 3723fade954SMichał Górny ]) 373b1099120SMichał Górny 374b1099120SMichał Górny def test_detach_no_multiprocess(self): 375b1099120SMichał Górny class MyResponder(MockGDBServerResponder): 376b1099120SMichał Górny def __init__(self): 377b1099120SMichał Górny super().__init__() 378b1099120SMichał Górny self.detached = None 379b1099120SMichał Górny 380b1099120SMichał Górny def qfThreadInfo(self): 381b1099120SMichał Górny return "10200" 382b1099120SMichał Górny 383b1099120SMichał Górny def D(self, packet): 384b1099120SMichał Górny self.detached = packet 385b1099120SMichał Górny return "OK" 386b1099120SMichał Górny 387b1099120SMichał Górny self.server.responder = MyResponder() 388b1099120SMichał Górny target = self.dbg.CreateTarget('') 389b1099120SMichał Górny process = self.connect(target) 390b1099120SMichał Górny process.Detach() 391b1099120SMichał Górny self.assertEqual(self.server.responder.detached, "D") 392b1099120SMichał Górny 393b1099120SMichał Górny def test_detach_pid(self): 394b1099120SMichał Górny class MyResponder(MockGDBServerResponder): 395b1099120SMichał Górny def __init__(self, test_case): 396b1099120SMichał Górny super().__init__() 397b1099120SMichał Górny self.test_case = test_case 398b1099120SMichał Górny self.detached = None 399b1099120SMichał Górny 400b1099120SMichał Górny def qSupported(self, client_supported): 401b1099120SMichał Górny self.test_case.assertIn("multiprocess+", client_supported) 402b1099120SMichał Górny return "multiprocess+;" + super().qSupported(client_supported) 403b1099120SMichał Górny 404b1099120SMichał Górny def qfThreadInfo(self): 405b1099120SMichał Górny return "mp400.10200" 406b1099120SMichał Górny 407b1099120SMichał Górny def D(self, packet): 408b1099120SMichał Górny self.detached = packet 409b1099120SMichał Górny return "OK" 410b1099120SMichał Górny 411b1099120SMichał Górny self.server.responder = MyResponder(self) 412b1099120SMichał Górny target = self.dbg.CreateTarget('') 413b1099120SMichał Górny process = self.connect(target) 414b1099120SMichał Górny process.Detach() 415b1099120SMichał Górny self.assertRegex(self.server.responder.detached, r"D;0*400") 4163f137236SMichał Górny 4173f137236SMichał Górny def test_signal_gdb(self): 4183f137236SMichał Górny class MyResponder(MockGDBServerResponder): 4193f137236SMichał Górny def qSupported(self, client_supported): 4203f137236SMichał Górny return "PacketSize=3fff;QStartNoAckMode+" 4213f137236SMichał Górny 4223f137236SMichał Górny def haltReason(self): 4233f137236SMichał Górny return "S0a" 4243f137236SMichał Górny 4253f137236SMichał Górny def cont(self): 4263f137236SMichał Górny return self.haltReason() 4273f137236SMichał Górny 4283f137236SMichał Górny self.server.responder = MyResponder() 4293f137236SMichał Górny 430d96656caSMichał Górny self.runCmd("platform select remote-linux") 4313f137236SMichał Górny target = self.createTarget("a.yaml") 4323f137236SMichał Górny process = self.connect(target) 4333f137236SMichał Górny 4343f137236SMichał Górny self.assertEqual(process.threads[0].GetStopReason(), 4353f137236SMichał Górny lldb.eStopReasonSignal) 4363f137236SMichał Górny self.assertEqual(process.threads[0].GetStopDescription(100), 4373f137236SMichał Górny 'signal SIGBUS') 4383f137236SMichał Górny 4393f137236SMichał Górny def test_signal_lldb_old(self): 4403f137236SMichał Górny class MyResponder(MockGDBServerResponder): 4413f137236SMichał Górny def qSupported(self, client_supported): 4423f137236SMichał Górny return "PacketSize=3fff;QStartNoAckMode+" 4433f137236SMichał Górny 4443f137236SMichał Górny def qHostInfo(self): 4453f137236SMichał Górny return "triple:61726d76372d756e6b6e6f776e2d6c696e75782d676e75;" 4463f137236SMichał Górny 4473f137236SMichał Górny def QThreadSuffixSupported(self): 4483f137236SMichał Górny return "OK" 4493f137236SMichał Górny 4503f137236SMichał Górny def haltReason(self): 4513f137236SMichał Górny return "S0a" 4523f137236SMichał Górny 4533f137236SMichał Górny def cont(self): 4543f137236SMichał Górny return self.haltReason() 4553f137236SMichał Górny 4563f137236SMichał Górny self.server.responder = MyResponder() 4573f137236SMichał Górny 458d96656caSMichał Górny self.runCmd("platform select remote-linux") 4593f137236SMichał Górny target = self.createTarget("a.yaml") 4603f137236SMichał Górny process = self.connect(target) 4613f137236SMichał Górny 4623f137236SMichał Górny self.assertEqual(process.threads[0].GetStopReason(), 4633f137236SMichał Górny lldb.eStopReasonSignal) 4643f137236SMichał Górny self.assertEqual(process.threads[0].GetStopDescription(100), 4653f137236SMichał Górny 'signal SIGUSR1') 4663f137236SMichał Górny 4673f137236SMichał Górny def test_signal_lldb(self): 4683f137236SMichał Górny class MyResponder(MockGDBServerResponder): 4693f137236SMichał Górny def qSupported(self, client_supported): 4703f137236SMichał Górny return "PacketSize=3fff;QStartNoAckMode+;native-signals+" 4713f137236SMichał Górny 4723f137236SMichał Górny def qHostInfo(self): 4733f137236SMichał Górny return "triple:61726d76372d756e6b6e6f776e2d6c696e75782d676e75;" 4743f137236SMichał Górny 4753f137236SMichał Górny def haltReason(self): 4763f137236SMichał Górny return "S0a" 4773f137236SMichał Górny 4783f137236SMichał Górny def cont(self): 4793f137236SMichał Górny return self.haltReason() 4803f137236SMichał Górny 4813f137236SMichał Górny self.server.responder = MyResponder() 4823f137236SMichał Górny 483d96656caSMichał Górny self.runCmd("platform select remote-linux") 4843f137236SMichał Górny target = self.createTarget("a.yaml") 4853f137236SMichał Górny process = self.connect(target) 4863f137236SMichał Górny 4873f137236SMichał Górny self.assertEqual(process.threads[0].GetStopReason(), 4883f137236SMichał Górny lldb.eStopReasonSignal) 4893f137236SMichał Górny self.assertEqual(process.threads[0].GetStopDescription(100), 4903f137236SMichał Górny 'signal SIGUSR1') 491ac666d17SMichał Górny 492ac666d17SMichał Górny def do_siginfo_test(self, platform, target_yaml, raw_data, expected): 493ac666d17SMichał Górny class MyResponder(MockGDBServerResponder): 494ac666d17SMichał Górny def qSupported(self, client_supported): 495ac666d17SMichał Górny return "PacketSize=3fff;QStartNoAckMode+;qXfer:siginfo:read+" 496ac666d17SMichał Górny 497ac666d17SMichał Górny def qXferRead(self, obj, annex, offset, length): 498ac666d17SMichał Górny if obj == "siginfo": 499ac666d17SMichał Górny return raw_data, False 500ac666d17SMichał Górny else: 501ac666d17SMichał Górny return None, False 502ac666d17SMichał Górny 503ac666d17SMichał Górny def haltReason(self): 504ac666d17SMichał Górny return "T02" 505ac666d17SMichał Górny 506ac666d17SMichał Górny def cont(self): 507ac666d17SMichał Górny return self.haltReason() 508ac666d17SMichał Górny 509ac666d17SMichał Górny self.server.responder = MyResponder() 510ac666d17SMichał Górny 511ac666d17SMichał Górny self.runCmd("platform select " + platform) 512ac666d17SMichał Górny target = self.createTarget(target_yaml) 513ac666d17SMichał Górny process = self.connect(target) 514ac666d17SMichał Górny 515ac666d17SMichał Górny siginfo = process.threads[0].GetSiginfo() 516*779bbbf2SDave Lee self.assertSuccess(siginfo.GetError()) 517ac666d17SMichał Górny 518ac666d17SMichał Górny for key, value in expected.items(): 519ac666d17SMichał Górny self.assertEqual(siginfo.GetValueForExpressionPath("." + key) 520ac666d17SMichał Górny .GetValueAsUnsigned(), 521ac666d17SMichał Górny value) 522ac666d17SMichał Górny 523ac666d17SMichał Górny 524ac666d17SMichał Górny def test_siginfo_linux_amd64(self): 525ac666d17SMichał Górny data = ( 526ac666d17SMichał Górny # si_signo si_errno si_code 527ac666d17SMichał Górny "\x11\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" 528ac666d17SMichał Górny # __pad0 si_pid si_uid 529ac666d17SMichał Górny "\x00\x00\x00\x00\xbf\xf7\x0b\x00\xe8\x03\x00\x00" 530ac666d17SMichał Górny # si_status 531ac666d17SMichał Górny "\x0c\x00\x00\x00" + "\x00" * 100) 532ac666d17SMichał Górny expected = { 533ac666d17SMichał Górny "si_signo": 17, # SIGCHLD 534ac666d17SMichał Górny "si_errno": 0, 535ac666d17SMichał Górny "si_code": 1, # CLD_EXITED 536ac666d17SMichał Górny "_sifields._sigchld.si_pid": 784319, 537ac666d17SMichał Górny "_sifields._sigchld.si_uid": 1000, 538ac666d17SMichał Górny "_sifields._sigchld.si_status": 12, 539ac666d17SMichał Górny "_sifields._sigchld.si_utime": 0, 540ac666d17SMichał Górny "_sifields._sigchld.si_stime": 0, 541ac666d17SMichał Górny } 542ac666d17SMichał Górny self.do_siginfo_test("remote-linux", "basic_eh_frame.yaml", 543ac666d17SMichał Górny data, expected) 544ac666d17SMichał Górny 545ac666d17SMichał Górny def test_siginfo_linux_i386(self): 546ac666d17SMichał Górny data = ( 547ac666d17SMichał Górny # si_signo si_errno si_code 548ac666d17SMichał Górny "\x11\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" 549ac666d17SMichał Górny # si_pid si_uid si_status 550ac666d17SMichał Górny "\x49\x43\x07\x00\xe8\x03\x00\x00\x0c\x00\x00\x00" 551ac666d17SMichał Górny + "\x00" * 104) 552ac666d17SMichał Górny expected = { 553ac666d17SMichał Górny "si_signo": 17, # SIGCHLD 554ac666d17SMichał Górny "si_errno": 0, 555ac666d17SMichał Górny "si_code": 1, # CLD_EXITED 556ac666d17SMichał Górny "_sifields._sigchld.si_pid": 475977, 557ac666d17SMichał Górny "_sifields._sigchld.si_uid": 1000, 558ac666d17SMichał Górny "_sifields._sigchld.si_status": 12, 559ac666d17SMichał Górny "_sifields._sigchld.si_utime": 0, 560ac666d17SMichał Górny "_sifields._sigchld.si_stime": 0, 561ac666d17SMichał Górny } 562ac666d17SMichał Górny self.do_siginfo_test("remote-linux", "basic_eh_frame-i386.yaml", 563ac666d17SMichał Górny data, expected) 564ac666d17SMichał Górny 565ac666d17SMichał Górny def test_siginfo_freebsd_amd64(self): 566ac666d17SMichał Górny data = ( 567ac666d17SMichał Górny # si_signo si_errno si_code 568ac666d17SMichał Górny "\x0b\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" 569ac666d17SMichał Górny # si_pid si_uid si_status 570ac666d17SMichał Górny "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 571ac666d17SMichał Górny # si_addr 572ac666d17SMichał Górny "\x76\x98\xba\xdc\xfe\x00\x00\x00" 573ac666d17SMichał Górny # si_status si_trapno 574ac666d17SMichał Górny "\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00" 575ac666d17SMichał Górny + "\x00" * 36) 576ac666d17SMichał Górny 577ac666d17SMichał Górny expected = { 578ac666d17SMichał Górny "si_signo": 11, # SIGSEGV 579ac666d17SMichał Górny "si_errno": 0, 580ac666d17SMichał Górny "si_code": 1, # SEGV_MAPERR 581ac666d17SMichał Górny "si_addr": 0xfedcba9876, 582ac666d17SMichał Górny "_reason._fault._trapno": 12, 583ac666d17SMichał Górny } 584ac666d17SMichał Górny self.do_siginfo_test("remote-freebsd", "basic_eh_frame.yaml", 585ac666d17SMichał Górny data, expected) 586