xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestFork.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
10a1d80d5SMichał Górnyimport lldb
20a1d80d5SMichał Górnyimport unittest
30a1d80d5SMichał Górnyfrom lldbsuite.test.lldbtest import *
40a1d80d5SMichał Górnyfrom lldbsuite.test.decorators import *
533c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
633c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
70a1d80d5SMichał Górny
80a1d80d5SMichał Górny
90a1d80d5SMichał Górnyclass TestMultiprocess(GDBRemoteTestBase):
10b61b8efcSMichał Górny    def base_test(self, variant, follow_child=False):
110a1d80d5SMichał Górny        class MyResponder(MockGDBServerResponder):
120a1d80d5SMichał Górny            def __init__(self):
130a1d80d5SMichał Górny                super().__init__()
140a1d80d5SMichał Górny                self.first = True
150a1d80d5SMichał Górny                self.detached = None
160a1d80d5SMichał Górny                self.property = "{}-events+".format(variant)
170a1d80d5SMichał Górny
180a1d80d5SMichał Górny            def qSupported(self, client_supported):
190a1d80d5SMichał Górny                assert "multiprocess+" in client_supported
200a1d80d5SMichał Górny                assert self.property in client_supported
210a1d80d5SMichał Górny                return "{};multiprocess+;{}".format(
22*2238dcc3SJonas Devlieghere                    super().qSupported(client_supported), self.property
23*2238dcc3SJonas Devlieghere                )
240a1d80d5SMichał Górny
250a1d80d5SMichał Górny            def qfThreadInfo(self):
260a1d80d5SMichał Górny                return "mp400.10200"
270a1d80d5SMichał Górny
280a1d80d5SMichał Górny            def cont(self):
290a1d80d5SMichał Górny                if self.first:
300a1d80d5SMichał Górny                    self.first = False
31*2238dcc3SJonas Devlieghere                    return "T0fthread:p400.10200;reason:{0};{0}:p401.10400;".format(
32*2238dcc3SJonas Devlieghere                        variant
33*2238dcc3SJonas Devlieghere                    )
340a1d80d5SMichał Górny                return "W00"
350a1d80d5SMichał Górny
360a1d80d5SMichał Górny            def D(self, packet):
370a1d80d5SMichał Górny                self.detached = packet
380a1d80d5SMichał Górny                return "OK"
390a1d80d5SMichał Górny
400a1d80d5SMichał Górny        self.server.responder = MyResponder()
41*2238dcc3SJonas Devlieghere        target = self.dbg.CreateTarget("")
420a1d80d5SMichał Górny        if self.TraceOn():
430a1d80d5SMichał Górny            self.runCmd("log enable gdb-remote packets")
44*2238dcc3SJonas Devlieghere            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
45b61b8efcSMichał Górny        if follow_child:
46b61b8efcSMichał Górny            self.runCmd("settings set target.process.follow-fork-mode child")
470a1d80d5SMichał Górny        process = self.connect(target)
48b61b8efcSMichał Górny        self.assertEqual(process.GetProcessID(), 1024)
490a1d80d5SMichał Górny        process.Continue()
50*2238dcc3SJonas Devlieghere        self.assertRegex(
51*2238dcc3SJonas Devlieghere            self.server.responder.detached, r"D;0*400" if follow_child else r"D;0*401"
52*2238dcc3SJonas Devlieghere        )
53*2238dcc3SJonas Devlieghere        self.assertEqual(process.GetProcessID(), 1025 if follow_child else 1024)
540a1d80d5SMichał Górny
550a1d80d5SMichał Górny    def test_fork(self):
560a1d80d5SMichał Górny        self.base_test("fork")
570a1d80d5SMichał Górny
580a1d80d5SMichał Górny    def test_vfork(self):
590a1d80d5SMichał Górny        self.base_test("vfork")
60b61b8efcSMichał Górny
61b61b8efcSMichał Górny    def test_fork_follow_child(self):
62b61b8efcSMichał Górny        self.base_test("fork", follow_child=True)
63b61b8efcSMichał Górny
64b61b8efcSMichał Górny    def test_vfork_follow_child(self):
65b61b8efcSMichał Górny        self.base_test("vfork", follow_child=True)
66