1from lldbsuite.test.decorators import *
2from lldbsuite.test.lldbtest import *
3
4from fork_testbase import GdbRemoteForkTestBase
5
6
7class TestGdbRemoteForkNonStop(GdbRemoteForkTestBase):
8    def setUp(self):
9        GdbRemoteForkTestBase.setUp(self)
10        if self.getPlatform() == "linux" and self.getArchitecture() in ['arm', 'aarch64']:
11            self.skipTest("Unsupported for Arm/AArch64 Linux")
12
13    @add_test_categories(["fork"])
14    def test_vfork_nonstop(self):
15        parent_pid, parent_tid = self.fork_and_detach_test("vfork",
16                                                           nonstop=True)
17
18        # resume the parent
19        self.test_sequence.add_log_lines([
20            "read packet: $c#00",
21            "send packet: $OK#00",
22            {"direction": "send",
23             "regex": r"%Stop:T[0-9a-fA-F]{{2}}thread:p{}[.]{}.*vforkdone.*"
24                      .format(parent_pid, parent_tid),
25             },
26            "read packet: $vStopped#00",
27            "send packet: $OK#00",
28            "read packet: $c#00",
29            "send packet: $OK#00",
30            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
31            "read packet: $vStopped#00",
32            "send packet: $OK#00",
33        ], True)
34        self.expect_gdbremote_sequence()
35
36    @add_test_categories(["fork"])
37    def test_fork_nonstop(self):
38        parent_pid, _ = self.fork_and_detach_test("fork", nonstop=True)
39
40        # resume the parent
41        self.test_sequence.add_log_lines([
42            "read packet: $c#00",
43            "send packet: $OK#00",
44            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
45            "read packet: $vStopped#00",
46            "send packet: $OK#00",
47        ], True)
48        self.expect_gdbremote_sequence()
49
50    @add_test_categories(["fork"])
51    def test_fork_follow_nonstop(self):
52        self.fork_and_follow_test("fork", nonstop=True)
53
54    @add_test_categories(["fork"])
55    def test_vfork_follow_nonstop(self):
56        self.fork_and_follow_test("vfork", nonstop=True)
57
58    @add_test_categories(["fork"])
59    def test_detach_all_nonstop(self):
60        self.detach_all_test(nonstop=True)
61
62    @add_test_categories(["fork"])
63    def test_kill_all_nonstop(self):
64        parent_pid, _, child_pid, _ = self.start_fork_test(["fork"],
65                                                           nonstop=True)
66
67        exit_regex = "X09;process:([0-9a-f]+)"
68        # Depending on a potential race, the second kill may make it into
69        # the async queue before we issue vStopped or after.  In the former
70        # case, we should expect the exit status in reply to vStopped.
71        # In the latter, we should expect an OK response (queue empty),
72        # followed by another async notification.
73        vstop_regex = "[$](OK|{})#.*".format(exit_regex)
74        self.test_sequence.add_log_lines([
75            # kill all processes
76            "read packet: $k#00",
77            "send packet: $OK#00",
78            {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
79             "capture": {1: "pid1"}},
80            "read packet: $vStopped#00",
81            {"direction": "send", "regex": vstop_regex,
82             "capture": {1: "vstop_reply", 2: "pid2"}},
83        ], True)
84        ret = self.expect_gdbremote_sequence()
85        pid1 = ret["pid1"]
86        if ret["vstop_reply"] == "OK":
87            self.reset_test_sequence()
88            self.test_sequence.add_log_lines([
89                {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
90                 "capture": {1: "pid2"}},
91            ], True)
92            ret = self.expect_gdbremote_sequence()
93        pid2 = ret["pid2"]
94        self.reset_test_sequence()
95        self.test_sequence.add_log_lines([
96            "read packet: $vStopped#00",
97            "send packet: $OK#00",
98        ], True)
99        self.expect_gdbremote_sequence()
100        self.assertEqual(set([pid1, pid2]), set([parent_pid, child_pid]))
101
102    @add_test_categories(["fork"])
103    def test_vkill_both_nonstop(self):
104        self.vkill_test(kill_parent=True, kill_child=True, nonstop=True)
105
106    @add_test_categories(["fork"])
107    def test_c_interspersed_nonstop(self):
108        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
109                             nonstop=True)
110
111    @add_test_categories(["fork"])
112    def test_vCont_interspersed_nonstop(self):
113        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
114                             use_vCont=True, nonstop=True)
115
116    @add_test_categories(["fork"])
117    def test_c_both_nonstop(self):
118        lock1 = self.getBuildArtifact("lock1")
119        lock2 = self.getBuildArtifact("lock2")
120        parent_pid, parent_tid, child_pid, child_tid = (
121            self.start_fork_test(["fork", "process:sync:" + lock1, "print-pid",
122                                  "process:sync:" + lock2, "stop"],
123                                 nonstop=True))
124
125        self.test_sequence.add_log_lines([
126            "read packet: $Hcp{}.{}#00".format(parent_pid, parent_tid),
127            "send packet: $OK#00",
128            "read packet: $c#00",
129            "send packet: $OK#00",
130            "read packet: $Hcp{}.{}#00".format(child_pid, child_tid),
131            "send packet: $OK#00",
132            "read packet: $c#00",
133            "send packet: $OK#00",
134            {"direction": "send", "regex": "%Stop:T.*"},
135            # see the comment in TestNonStop.py, test_stdio
136            "read packet: $vStdio#00",
137            "read packet: $vStdio#00",
138            "send packet: $OK#00",
139            ], True)
140        ret = self.expect_gdbremote_sequence()
141        self.assertIn("PID: {}".format(int(parent_pid, 16)).encode(),
142                      ret["O_content"])
143        self.assertIn("PID: {}".format(int(child_pid, 16)).encode(),
144                      ret["O_content"])
145