1from lldbsuite.test.decorators import *
2from lldbsuite.test.lldbtest import *
3
4from fork_testbase import GdbRemoteForkTestBase
5
6
7class TestGdbRemoteForkNonStop(GdbRemoteForkTestBase):
8    @add_test_categories(["fork"])
9    def test_vfork_nonstop(self):
10        parent_pid, parent_tid = self.fork_and_detach_test("vfork",
11                                                           nonstop=True)
12
13        # resume the parent
14        self.test_sequence.add_log_lines([
15            "read packet: $c#00",
16            "send packet: $OK#00",
17            {"direction": "send",
18             "regex": r"%Stop:T[0-9a-fA-F]{{2}}thread:p{}[.]{}.*vforkdone.*"
19                      .format(parent_pid, parent_tid),
20             },
21            "read packet: $vStopped#00",
22            "send packet: $OK#00",
23            "read packet: $c#00",
24            "send packet: $OK#00",
25            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
26            "read packet: $vStopped#00",
27            "send packet: $OK#00",
28        ], True)
29        self.expect_gdbremote_sequence()
30
31    @add_test_categories(["fork"])
32    def test_fork_nonstop(self):
33        parent_pid, _ = self.fork_and_detach_test("fork", nonstop=True)
34
35        # resume the parent
36        self.test_sequence.add_log_lines([
37            "read packet: $c#00",
38            "send packet: $OK#00",
39            "send packet: %Stop:W00;process:{}#00".format(parent_pid),
40            "read packet: $vStopped#00",
41            "send packet: $OK#00",
42        ], True)
43        self.expect_gdbremote_sequence()
44
45    @add_test_categories(["fork"])
46    def test_fork_follow_nonstop(self):
47        self.fork_and_follow_test("fork", nonstop=True)
48
49    @add_test_categories(["fork"])
50    def test_vfork_follow_nonstop(self):
51        self.fork_and_follow_test("vfork", nonstop=True)
52
53    @add_test_categories(["fork"])
54    def test_detach_all_nonstop(self):
55        self.detach_all_test(nonstop=True)
56
57    @add_test_categories(["fork"])
58    def test_kill_all_nonstop(self):
59        parent_pid, _, child_pid, _ = self.start_fork_test(["fork"],
60                                                           nonstop=True)
61
62        exit_regex = "X09;process:([0-9a-f]+)"
63        # Depending on a potential race, the second kill may make it into
64        # the async queue before we issue vStopped or after.  In the former
65        # case, we should expect the exit status in reply to vStopped.
66        # In the latter, we should expect an OK response (queue empty),
67        # followed by another async notification.
68        vstop_regex = "[$](OK|{})#.*".format(exit_regex)
69        self.test_sequence.add_log_lines([
70            # kill all processes
71            "read packet: $k#00",
72            "send packet: $OK#00",
73            {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
74             "capture": {1: "pid1"}},
75            "read packet: $vStopped#00",
76            {"direction": "send", "regex": vstop_regex,
77             "capture": {1: "vstop_reply", 2: "pid2"}},
78        ], True)
79        ret = self.expect_gdbremote_sequence()
80        pid1 = ret["pid1"]
81        if ret["vstop_reply"] == "OK":
82            self.reset_test_sequence()
83            self.test_sequence.add_log_lines([
84                {"direction": "send", "regex": "%Stop:{}#.*".format(exit_regex),
85                 "capture": {1: "pid2"}},
86            ], True)
87            ret = self.expect_gdbremote_sequence()
88        pid2 = ret["pid2"]
89        self.reset_test_sequence()
90        self.test_sequence.add_log_lines([
91            "read packet: $vStopped#00",
92            "send packet: $OK#00",
93        ], True)
94        self.expect_gdbremote_sequence()
95        self.assertEqual(set([pid1, pid2]), set([parent_pid, child_pid]))
96
97    @add_test_categories(["fork"])
98    def test_vkill_both_nonstop(self):
99        self.vkill_test(kill_parent=True, kill_child=True, nonstop=True)
100
101    @add_test_categories(["fork"])
102    def test_c_interspersed_nonstop(self):
103        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
104                             nonstop=True)
105
106    @add_test_categories(["fork"])
107    def test_vCont_interspersed_nonstop(self):
108        self.resume_one_test(run_order=["parent", "child", "parent", "child"],
109                             use_vCont=True, nonstop=True)
110