xref: /llvm-project/lldb/test/API/tools/lldb-server/vCont-threads/TestPartialResume.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1import re
2
3import gdbremote_testcase
4from lldbsuite.test.decorators import *
5from lldbsuite.test.lldbtest import *
6
7
8class TestPartialResume(gdbremote_testcase.GdbRemoteTestCaseBase):
9    THREAD_MATCH_RE = re.compile(r"thread ([0-9a-f]+) running")
10
11    def start_vCont_run_subset_of_threads_test(self):
12        self.build()
13        self.set_inferior_startup_launch()
14
15        procs = self.prep_debug_monitor_and_inferior(inferior_args=["3"])
16        # grab the main thread id
17        self.add_threadinfo_collection_packets()
18        main_thread = self.parse_threadinfo_packets(self.expect_gdbremote_sequence())
19        self.assertEqual(len(main_thread), 1)
20        self.reset_test_sequence()
21
22        # run until threads start, then grab full thread list
23        self.test_sequence.add_log_lines(
24            [
25                "read packet: $c#63",
26                {"direction": "send", "regex": "[$]T.*;reason:signal.*"},
27            ],
28            True,
29        )
30        self.add_threadinfo_collection_packets()
31
32        all_threads = self.parse_threadinfo_packets(self.expect_gdbremote_sequence())
33        self.assertEqual(len(all_threads), 4)
34        self.assertIn(main_thread[0], all_threads)
35        self.reset_test_sequence()
36
37        all_subthreads = set(all_threads) - set(main_thread)
38        self.assertEqual(len(all_subthreads), 3)
39
40        return (main_thread[0], list(all_subthreads))
41
42    def continue_and_get_threads_running(self, main_thread, vCont_req):
43        self.test_sequence.add_log_lines(
44            [
45                "read packet: $vCont;c:{:x};{}#00".format(main_thread, vCont_req),
46                "send packet: $W00#00",
47            ],
48            True,
49        )
50        exp = self.expect_gdbremote_sequence()
51        self.reset_test_sequence()
52        found = set()
53        for line in exp["O_content"].decode().splitlines():
54            m = self.THREAD_MATCH_RE.match(line)
55            if m is not None:
56                found.add(int(m.group(1), 16))
57        return found
58
59    @skipIfWindows
60    @add_test_categories(["llgs"])
61    def test_vCont_cxcx(self):
62        main_thread, all_subthreads_list = self.start_vCont_run_subset_of_threads_test()
63        # resume two threads explicitly, stop the third one implicitly
64        self.assertEqual(
65            self.continue_and_get_threads_running(
66                main_thread, "c:{:x};c:{:x}".format(*all_subthreads_list[:2])
67            ),
68            set(all_subthreads_list[:2]),
69        )
70
71    @skipIfWindows
72    @add_test_categories(["llgs"])
73    def test_vCont_cxcxt(self):
74        main_thread, all_subthreads_list = self.start_vCont_run_subset_of_threads_test()
75        # resume two threads explicitly, stop others explicitly
76        self.assertEqual(
77            self.continue_and_get_threads_running(
78                main_thread, "c:{:x};c:{:x};t".format(*all_subthreads_list[:2])
79            ),
80            set(all_subthreads_list[:2]),
81        )
82