1import lldb 2import unittest 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test.decorators import * 5from lldbsuite.test.gdbclientutils import * 6from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 7 8 9class TestMultiprocess(GDBRemoteTestBase): 10 def base_test(self, variant, follow_child=False): 11 class MyResponder(MockGDBServerResponder): 12 def __init__(self): 13 super().__init__() 14 self.first = True 15 self.detached = None 16 self.property = "{}-events+".format(variant) 17 18 def qSupported(self, client_supported): 19 assert "multiprocess+" in client_supported 20 assert self.property in client_supported 21 return "{};multiprocess+;{}".format( 22 super().qSupported(client_supported), self.property 23 ) 24 25 def qfThreadInfo(self): 26 return "mp400.10200" 27 28 def cont(self): 29 if self.first: 30 self.first = False 31 return "T0fthread:p400.10200;reason:{0};{0}:p401.10400;".format( 32 variant 33 ) 34 return "W00" 35 36 def D(self, packet): 37 self.detached = packet 38 return "OK" 39 40 self.server.responder = MyResponder() 41 target = self.dbg.CreateTarget("") 42 if self.TraceOn(): 43 self.runCmd("log enable gdb-remote packets") 44 self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets")) 45 if follow_child: 46 self.runCmd("settings set target.process.follow-fork-mode child") 47 process = self.connect(target) 48 self.assertEqual(process.GetProcessID(), 1024) 49 process.Continue() 50 self.assertRegex( 51 self.server.responder.detached, r"D;0*400" if follow_child else r"D;0*401" 52 ) 53 self.assertEqual(process.GetProcessID(), 1025 if follow_child else 1024) 54 55 def test_fork(self): 56 self.base_test("fork") 57 58 def test_vfork(self): 59 self.base_test("vfork") 60 61 def test_fork_follow_child(self): 62 self.base_test("fork", follow_child=True) 63 64 def test_vfork_follow_child(self): 65 self.base_test("vfork", follow_child=True) 66