1import gdbremote_testcase
2from lldbsuite.test.decorators import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5
6class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
7    mydir = TestBase.compute_mydir(__file__)
8
9    def fork_and_detach_test(self, variant):
10        self.build()
11        self.prep_debug_monitor_and_inferior(inferior_args=[variant])
12        self.add_qSupported_packets(["multiprocess+",
13                                     "{}-events+".format(variant)])
14        ret = self.expect_gdbremote_sequence()
15        self.assertIn("{}-events+".format(variant), ret["qSupported_response"])
16        self.reset_test_sequence()
17
18        # continue and expect fork
19        fork_regex = "[$]T.*;{}:p([0-9a-f]*)[.]([0-9a-f]*).*".format(variant)
20        self.test_sequence.add_log_lines([
21            "read packet: $c#00",
22            {"direction": "send", "regex": fork_regex,
23             "capture": {1: "pid", 2: "tid"}},
24        ], True)
25        ret = self.expect_gdbremote_sequence()
26        pid = int(ret["pid"], 16)
27        self.reset_test_sequence()
28
29        # detach the forked child
30        self.test_sequence.add_log_lines([
31            "read packet: $D;{:x}#00".format(pid),
32            {"direction": "send", "regex": r"[$]OK#.*"},
33        ], True)
34        ret = self.expect_gdbremote_sequence()
35        self.reset_test_sequence()
36
37    @add_test_categories(["fork"])
38    def test_fork(self):
39        self.fork_and_detach_test("fork")
40
41        # resume the parent
42        self.test_sequence.add_log_lines([
43            "read packet: $c#00",
44            {"direction": "send", "regex": r"[$]W00#.*"},
45        ], True)
46        self.expect_gdbremote_sequence()
47
48    @add_test_categories(["fork"])
49    def test_vfork(self):
50        self.fork_and_detach_test("vfork")
51
52        # resume the parent
53        self.test_sequence.add_log_lines([
54            "read packet: $c#00",
55            {"direction": "send", "regex": r"[$]T.*vforkdone.*"},
56            "read packet: $c#00",
57            {"direction": "send", "regex": r"[$]W00#.*"},
58        ], True)
59        self.expect_gdbremote_sequence()
60