xref: /llvm-project/lldb/test/API/tools/lldb-server/TestLldbGdbServer.py (revision 5a658ee933065d0e4ef1a65d9a6ddfba2874ee98)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest case for testing the gdbremote protocol.
399451b44SJordan Rupprecht
499451b44SJordan RupprechtTests run against debugserver and lldb-server (llgs).
599451b44SJordan Rupprechtlldb-server tests run where the lldb-server exe is
699451b44SJordan Rupprechtavailable.
799451b44SJordan Rupprecht
899451b44SJordan RupprechtThis class will be broken into smaller test case classes by
999451b44SJordan Rupprechtgdb remote packet functional areas.  For now it contains
1099451b44SJordan Rupprechtthe initial set of tests implemented.
1199451b44SJordan Rupprecht"""
1299451b44SJordan Rupprecht
136ba3f723SMichał Górnyimport binascii
146ba3f723SMichał Górnyimport itertools
151e74e5e9SMichał Górnyimport struct
166ba3f723SMichał Górny
1799451b44SJordan Rupprechtimport gdbremote_testcase
1899451b44SJordan Rupprechtimport lldbgdbserverutils
1999451b44SJordan Rupprechtfrom lldbsuite.support import seven
2099451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
2199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
2299451b44SJordan Rupprechtfrom lldbsuite.test.lldbdwarf import *
23ca7824c2SMichał Górnyfrom lldbsuite.test import lldbutil, lldbplatformutil
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht
262238dcc3SJonas Devlieghereclass LldbGdbServerTestCase(
272238dcc3SJonas Devlieghere    gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser
282238dcc3SJonas Devlieghere):
29a0b68a29SPavel Labath    def test_thread_suffix_supported(self):
3099451b44SJordan Rupprecht        server = self.connect_to_debug_monitor()
3199451b44SJordan Rupprecht        self.assertIsNotNone(server)
3299451b44SJordan Rupprecht
33872b1da6SPavel Labath        self.do_handshake()
3499451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
352238dcc3SJonas Devlieghere            [
362238dcc3SJonas Devlieghere                "lldb-server <  26> read packet: $QThreadSuffixSupported#e4",
372238dcc3SJonas Devlieghere                "lldb-server <   6> send packet: $OK#9a",
382238dcc3SJonas Devlieghere            ],
392238dcc3SJonas Devlieghere            True,
402238dcc3SJonas Devlieghere        )
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        self.expect_gdbremote_sequence()
4399451b44SJordan Rupprecht
44a0b68a29SPavel Labath    def test_list_threads_in_stop_reply_supported(self):
4599451b44SJordan Rupprecht        server = self.connect_to_debug_monitor()
4699451b44SJordan Rupprecht        self.assertIsNotNone(server)
4799451b44SJordan Rupprecht
48872b1da6SPavel Labath        self.do_handshake()
4999451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
502238dcc3SJonas Devlieghere            [
512238dcc3SJonas Devlieghere                "lldb-server <  27> read packet: $QListThreadsInStopReply#21",
522238dcc3SJonas Devlieghere                "lldb-server <   6> send packet: $OK#9a",
532238dcc3SJonas Devlieghere            ],
542238dcc3SJonas Devlieghere            True,
552238dcc3SJonas Devlieghere        )
5699451b44SJordan Rupprecht        self.expect_gdbremote_sequence()
5799451b44SJordan Rupprecht
58a0b68a29SPavel Labath    def test_c_packet_works(self):
59a0b68a29SPavel Labath        self.build()
60174b09e9SPavel Labath        procs = self.prep_debug_monitor_and_inferior()
6199451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
622238dcc3SJonas Devlieghere            ["read packet: $c#63", "send packet: $W00#00"], True
632238dcc3SJonas Devlieghere        )
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        self.expect_gdbremote_sequence()
6699451b44SJordan Rupprecht
67a0b68a29SPavel Labath    @skipIfWindows  # No pty support to test any inferior output
68a0b68a29SPavel Labath    def test_inferior_print_exit(self):
6999451b44SJordan Rupprecht        self.build()
702238dcc3SJonas Devlieghere        procs = self.prep_debug_monitor_and_inferior(inferior_args=["hello, world"])
7199451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
722238dcc3SJonas Devlieghere            [
732238dcc3SJonas Devlieghere                "read packet: $vCont;c#a8",
742238dcc3SJonas Devlieghere                {
752238dcc3SJonas Devlieghere                    "type": "output_match",
762238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(r"hello, world\r\n"),
772238dcc3SJonas Devlieghere                },
782238dcc3SJonas Devlieghere                "send packet: $W00#00",
792238dcc3SJonas Devlieghere            ],
802238dcc3SJonas Devlieghere            True,
812238dcc3SJonas Devlieghere        )
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
8499451b44SJordan Rupprecht        self.assertIsNotNone(context)
8599451b44SJordan Rupprecht
86a0b68a29SPavel Labath    def test_first_launch_stop_reply_thread_matches_first_qC(self):
8799451b44SJordan Rupprecht        self.build()
88174b09e9SPavel Labath        procs = self.prep_debug_monitor_and_inferior()
892238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines(
902238dcc3SJonas Devlieghere            [
912238dcc3SJonas Devlieghere                "read packet: $qC#00",
922238dcc3SJonas Devlieghere                {
932238dcc3SJonas Devlieghere                    "direction": "send",
9499451b44SJordan Rupprecht                    "regex": r"^\$QC([0-9a-fA-F]+)#",
952238dcc3SJonas Devlieghere                    "capture": {1: "thread_id_QC"},
962238dcc3SJonas Devlieghere                },
9799451b44SJordan Rupprecht                "read packet: $?#00",
982238dcc3SJonas Devlieghere                {
992238dcc3SJonas Devlieghere                    "direction": "send",
10099451b44SJordan Rupprecht                    "regex": r"^\$T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+)",
1012238dcc3SJonas Devlieghere                    "capture": {1: "thread_id_?"},
1022238dcc3SJonas Devlieghere                },
1032238dcc3SJonas Devlieghere            ],
1042238dcc3SJonas Devlieghere            True,
1052238dcc3SJonas Devlieghere        )
106ded66049SPavel Labath        context = self.expect_gdbremote_sequence()
107ded66049SPavel Labath        self.assertEqual(context.get("thread_id_QC"), context.get("thread_id_?"))
10899451b44SJordan Rupprecht
109a0b68a29SPavel Labath    def test_attach_commandline_continue_app_exits(self):
11099451b44SJordan Rupprecht        self.build()
111a0b68a29SPavel Labath        self.set_inferior_startup_attach()
11299451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
11399451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
1142238dcc3SJonas Devlieghere            ["read packet: $vCont;c#a8", "send packet: $W00#00"], True
1152238dcc3SJonas Devlieghere        )
11699451b44SJordan Rupprecht        self.expect_gdbremote_sequence()
11799451b44SJordan Rupprecht
11899451b44SJordan Rupprecht        # Wait a moment for completed and now-detached inferior process to
11999451b44SJordan Rupprecht        # clear.
12099451b44SJordan Rupprecht        time.sleep(1)
12199451b44SJordan Rupprecht
12299451b44SJordan Rupprecht        if not lldb.remote_platform:
12399451b44SJordan Rupprecht            # Process should be dead now. Reap results.
12499451b44SJordan Rupprecht            poll_result = procs["inferior"].poll()
12599451b44SJordan Rupprecht            self.assertIsNotNone(poll_result)
12699451b44SJordan Rupprecht
12799451b44SJordan Rupprecht        # Where possible, verify at the system level that the process is not
12899451b44SJordan Rupprecht        # running.
12999451b44SJordan Rupprecht        self.assertFalse(
1302238dcc3SJonas Devlieghere            lldbgdbserverutils.process_is_running(procs["inferior"].pid, False)
1312238dcc3SJonas Devlieghere        )
13299451b44SJordan Rupprecht
133a0b68a29SPavel Labath    def test_qRegisterInfo_returns_one_valid_result(self):
13499451b44SJordan Rupprecht        self.build()
135174b09e9SPavel Labath        self.prep_debug_monitor_and_inferior()
13699451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
1372238dcc3SJonas Devlieghere            [
1382238dcc3SJonas Devlieghere                "read packet: $qRegisterInfo0#00",
1392238dcc3SJonas Devlieghere                {
1402238dcc3SJonas Devlieghere                    "direction": "send",
1412238dcc3SJonas Devlieghere                    "regex": r"^\$(.+);#[0-9A-Fa-f]{2}",
1422238dcc3SJonas Devlieghere                    "capture": {1: "reginfo_0"},
1432238dcc3SJonas Devlieghere                },
1442238dcc3SJonas Devlieghere            ],
1452238dcc3SJonas Devlieghere            True,
1462238dcc3SJonas Devlieghere        )
14799451b44SJordan Rupprecht
14899451b44SJordan Rupprecht        # Run the stream
14999451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
15099451b44SJordan Rupprecht        self.assertIsNotNone(context)
15199451b44SJordan Rupprecht
15299451b44SJordan Rupprecht        reg_info_packet = context.get("reginfo_0")
15399451b44SJordan Rupprecht        self.assertIsNotNone(reg_info_packet)
15499451b44SJordan Rupprecht        self.assert_valid_reg_info(
1552238dcc3SJonas Devlieghere            lldbgdbserverutils.parse_reg_info_response(reg_info_packet)
1562238dcc3SJonas Devlieghere        )
15799451b44SJordan Rupprecht
158a0b68a29SPavel Labath    def test_qRegisterInfo_returns_all_valid_results(self):
15999451b44SJordan Rupprecht        self.build()
160174b09e9SPavel Labath        self.prep_debug_monitor_and_inferior()
16199451b44SJordan Rupprecht        self.add_register_info_collection_packets()
16299451b44SJordan Rupprecht
16399451b44SJordan Rupprecht        # Run the stream.
16499451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
16599451b44SJordan Rupprecht        self.assertIsNotNone(context)
16699451b44SJordan Rupprecht
16799451b44SJordan Rupprecht        # Validate that each register info returned validates.
16899451b44SJordan Rupprecht        for reg_info in self.parse_register_info_packets(context):
16999451b44SJordan Rupprecht            self.assert_valid_reg_info(reg_info)
17099451b44SJordan Rupprecht
171a0b68a29SPavel Labath    def test_qRegisterInfo_contains_required_generics_debugserver(self):
17299451b44SJordan Rupprecht        self.build()
173174b09e9SPavel Labath        self.prep_debug_monitor_and_inferior()
17499451b44SJordan Rupprecht        self.add_register_info_collection_packets()
17599451b44SJordan Rupprecht
17699451b44SJordan Rupprecht        # Run the packet stream.
17799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
17899451b44SJordan Rupprecht        self.assertIsNotNone(context)
17999451b44SJordan Rupprecht
18099451b44SJordan Rupprecht        # Gather register info entries.
18199451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
18299451b44SJordan Rupprecht
18399451b44SJordan Rupprecht        # Collect all generic registers found.
18499451b44SJordan Rupprecht        generic_regs = {
1852238dcc3SJonas Devlieghere            reg_info["generic"]: 1 for reg_info in reg_infos if "generic" in reg_info
1862238dcc3SJonas Devlieghere        }
18799451b44SJordan Rupprecht
18899451b44SJordan Rupprecht        # Ensure we have a program counter register.
1892238dcc3SJonas Devlieghere        self.assertIn("pc", generic_regs)
19099451b44SJordan Rupprecht
19199451b44SJordan Rupprecht        # Ensure we have a frame pointer register. PPC64le's FP is the same as SP
1922238dcc3SJonas Devlieghere        if self.getArchitecture() != "powerpc64le":
1932238dcc3SJonas Devlieghere            self.assertIn("fp", generic_regs)
19499451b44SJordan Rupprecht
19599451b44SJordan Rupprecht        # Ensure we have a stack pointer register.
1962238dcc3SJonas Devlieghere        self.assertIn("sp", generic_regs)
19799451b44SJordan Rupprecht
19899451b44SJordan Rupprecht        # Ensure we have a flags register.
1992238dcc3SJonas Devlieghere        self.assertIn("flags", generic_regs)
20099451b44SJordan Rupprecht
201a0b68a29SPavel Labath    def test_qRegisterInfo_contains_at_least_one_register_set(self):
20299451b44SJordan Rupprecht        self.build()
203174b09e9SPavel Labath        self.prep_debug_monitor_and_inferior()
20499451b44SJordan Rupprecht        self.add_register_info_collection_packets()
20599451b44SJordan Rupprecht
20699451b44SJordan Rupprecht        # Run the packet stream.
20799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
20899451b44SJordan Rupprecht        self.assertIsNotNone(context)
20999451b44SJordan Rupprecht
21099451b44SJordan Rupprecht        # Gather register info entries.
21199451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
21299451b44SJordan Rupprecht
21399451b44SJordan Rupprecht        # Collect all register sets found.
21499451b44SJordan Rupprecht        register_sets = {
2152238dcc3SJonas Devlieghere            reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
2162238dcc3SJonas Devlieghere        }
2179c246882SJordan Rupprecht        self.assertGreaterEqual(len(register_sets), 1)
21899451b44SJordan Rupprecht
21999451b44SJordan Rupprecht    def targetHasAVX(self):
22099451b44SJordan Rupprecht        triple = self.dbg.GetSelectedPlatform().GetTriple()
22199451b44SJordan Rupprecht
22299451b44SJordan Rupprecht        # TODO other platforms, please implement this function
22399451b44SJordan Rupprecht        if not re.match(".*-.*-linux", triple):
22499451b44SJordan Rupprecht            return True
22599451b44SJordan Rupprecht
22699451b44SJordan Rupprecht        # Need to do something different for non-Linux/Android targets
22799451b44SJordan Rupprecht        if lldb.remote_platform:
22899451b44SJordan Rupprecht            self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"')
22999451b44SJordan Rupprecht            cpuinfo_path = "cpuinfo"
23099451b44SJordan Rupprecht            self.addTearDownHook(lambda: os.unlink("cpuinfo"))
23199451b44SJordan Rupprecht        else:
23299451b44SJordan Rupprecht            cpuinfo_path = "/proc/cpuinfo"
23399451b44SJordan Rupprecht
2342238dcc3SJonas Devlieghere        f = open(cpuinfo_path, "r")
23599451b44SJordan Rupprecht        cpuinfo = f.read()
23699451b44SJordan Rupprecht        f.close()
23799451b44SJordan Rupprecht        return " avx " in cpuinfo
23899451b44SJordan Rupprecht
239a0b68a29SPavel Labath    @expectedFailureAll(oslist=["windows"])  # no avx for now.
2402238dcc3SJonas Devlieghere    @skipIf(archs=no_match(["amd64", "i386", "x86_64"]))
241a0b68a29SPavel Labath    @add_test_categories(["llgs"])
242a0b68a29SPavel Labath    def test_qRegisterInfo_contains_avx_registers(self):
243a0b68a29SPavel Labath        self.build()
244174b09e9SPavel Labath        self.prep_debug_monitor_and_inferior()
24599451b44SJordan Rupprecht        self.add_register_info_collection_packets()
24699451b44SJordan Rupprecht
24799451b44SJordan Rupprecht        # Run the packet stream.
24899451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
24999451b44SJordan Rupprecht        self.assertIsNotNone(context)
25099451b44SJordan Rupprecht
25199451b44SJordan Rupprecht        # Gather register info entries.
25299451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
25399451b44SJordan Rupprecht
25499451b44SJordan Rupprecht        # Collect all generics found.
25599451b44SJordan Rupprecht        register_sets = {
2562238dcc3SJonas Devlieghere            reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
2572238dcc3SJonas Devlieghere        }
25899451b44SJordan Rupprecht        self.assertEqual(
2592238dcc3SJonas Devlieghere            self.targetHasAVX(), "Advanced Vector Extensions" in register_sets
2602238dcc3SJonas Devlieghere        )
26199451b44SJordan Rupprecht
26299451b44SJordan Rupprecht    def qThreadInfo_contains_thread(self):
26399451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
26499451b44SJordan Rupprecht        self.add_threadinfo_collection_packets()
26599451b44SJordan Rupprecht
26699451b44SJordan Rupprecht        # Run the packet stream.
26799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
26899451b44SJordan Rupprecht        self.assertIsNotNone(context)
26999451b44SJordan Rupprecht
27099451b44SJordan Rupprecht        # Gather threadinfo entries.
27199451b44SJordan Rupprecht        threads = self.parse_threadinfo_packets(context)
27299451b44SJordan Rupprecht        self.assertIsNotNone(threads)
27399451b44SJordan Rupprecht
27499451b44SJordan Rupprecht        # We should have exactly one thread.
27599451b44SJordan Rupprecht        self.assertEqual(len(threads), 1)
27699451b44SJordan Rupprecht
277a0b68a29SPavel Labath    def test_qThreadInfo_contains_thread_launch(self):
27899451b44SJordan Rupprecht        self.build()
27999451b44SJordan Rupprecht        self.set_inferior_startup_launch()
28099451b44SJordan Rupprecht        self.qThreadInfo_contains_thread()
28199451b44SJordan Rupprecht
28299451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"])  # expect one more thread stopped
283a0b68a29SPavel Labath    def test_qThreadInfo_contains_thread_attach(self):
28499451b44SJordan Rupprecht        self.build()
28599451b44SJordan Rupprecht        self.set_inferior_startup_attach()
28699451b44SJordan Rupprecht        self.qThreadInfo_contains_thread()
28799451b44SJordan Rupprecht
28899451b44SJordan Rupprecht    def qThreadInfo_matches_qC(self):
28999451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
29099451b44SJordan Rupprecht
29199451b44SJordan Rupprecht        self.add_threadinfo_collection_packets()
29299451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
2932238dcc3SJonas Devlieghere            [
2942238dcc3SJonas Devlieghere                "read packet: $qC#00",
2952238dcc3SJonas Devlieghere                {
2962238dcc3SJonas Devlieghere                    "direction": "send",
2972238dcc3SJonas Devlieghere                    "regex": r"^\$QC([0-9a-fA-F]+)#",
2982238dcc3SJonas Devlieghere                    "capture": {1: "thread_id"},
2992238dcc3SJonas Devlieghere                },
3002238dcc3SJonas Devlieghere            ],
3012238dcc3SJonas Devlieghere            True,
3022238dcc3SJonas Devlieghere        )
30399451b44SJordan Rupprecht
30499451b44SJordan Rupprecht        # Run the packet stream.
30599451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
30699451b44SJordan Rupprecht        self.assertIsNotNone(context)
30799451b44SJordan Rupprecht
30899451b44SJordan Rupprecht        # Gather threadinfo entries.
30999451b44SJordan Rupprecht        threads = self.parse_threadinfo_packets(context)
31099451b44SJordan Rupprecht        self.assertIsNotNone(threads)
31199451b44SJordan Rupprecht
31299451b44SJordan Rupprecht        # We should have exactly one thread from threadinfo.
31399451b44SJordan Rupprecht        self.assertEqual(len(threads), 1)
31499451b44SJordan Rupprecht
31599451b44SJordan Rupprecht        # We should have a valid thread_id from $QC.
31699451b44SJordan Rupprecht        QC_thread_id_hex = context.get("thread_id")
31799451b44SJordan Rupprecht        self.assertIsNotNone(QC_thread_id_hex)
31899451b44SJordan Rupprecht        QC_thread_id = int(QC_thread_id_hex, 16)
31999451b44SJordan Rupprecht
32099451b44SJordan Rupprecht        # Those two should be the same.
32199451b44SJordan Rupprecht        self.assertEqual(threads[0], QC_thread_id)
32299451b44SJordan Rupprecht
323a0b68a29SPavel Labath    def test_qThreadInfo_matches_qC_launch(self):
32499451b44SJordan Rupprecht        self.build()
32599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
32699451b44SJordan Rupprecht        self.qThreadInfo_matches_qC()
32799451b44SJordan Rupprecht
32899451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"])  # expect one more thread stopped
329a0b68a29SPavel Labath    def test_qThreadInfo_matches_qC_attach(self):
33099451b44SJordan Rupprecht        self.build()
33199451b44SJordan Rupprecht        self.set_inferior_startup_attach()
33299451b44SJordan Rupprecht        self.qThreadInfo_matches_qC()
33399451b44SJordan Rupprecht
334a0b68a29SPavel Labath    def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch(self):
335a0b68a29SPavel Labath        self.build()
336a0b68a29SPavel Labath        self.set_inferior_startup_launch()
33799451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
33899451b44SJordan Rupprecht        self.add_register_info_collection_packets()
33999451b44SJordan Rupprecht
34099451b44SJordan Rupprecht        # Run the packet stream.
34199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
34299451b44SJordan Rupprecht        self.assertIsNotNone(context)
34399451b44SJordan Rupprecht
34499451b44SJordan Rupprecht        # Gather register info entries.
34599451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
34699451b44SJordan Rupprecht        self.assertIsNotNone(reg_infos)
3479c246882SJordan Rupprecht        self.assertGreater(len(reg_infos), 0)
34899451b44SJordan Rupprecht
34999451b44SJordan Rupprecht        byte_order = self.get_target_byte_order()
35099451b44SJordan Rupprecht
35199451b44SJordan Rupprecht        # Read value for each register.
35299451b44SJordan Rupprecht        reg_index = 0
35399451b44SJordan Rupprecht        for reg_info in reg_infos:
35499451b44SJordan Rupprecht            # Skip registers that don't have a register set.  For x86, these are
35599451b44SJordan Rupprecht            # the DRx registers, which have no LLDB-kind register number and thus
35699451b44SJordan Rupprecht            # cannot be read via normal
35799451b44SJordan Rupprecht            # NativeRegisterContext::ReadRegister(reg_info,...) calls.
35899451b44SJordan Rupprecht            if not "set" in reg_info:
35999451b44SJordan Rupprecht                continue
36099451b44SJordan Rupprecht
36199451b44SJordan Rupprecht            # Clear existing packet expectations.
36299451b44SJordan Rupprecht            self.reset_test_sequence()
36399451b44SJordan Rupprecht
36499451b44SJordan Rupprecht            # Run the register query
36599451b44SJordan Rupprecht            self.test_sequence.add_log_lines(
3662238dcc3SJonas Devlieghere                [
3672238dcc3SJonas Devlieghere                    "read packet: $p{0:x}#00".format(reg_index),
3682238dcc3SJonas Devlieghere                    {
3692238dcc3SJonas Devlieghere                        "direction": "send",
3702238dcc3SJonas Devlieghere                        "regex": r"^\$([0-9a-fA-F]+)#",
3712238dcc3SJonas Devlieghere                        "capture": {1: "p_response"},
3722238dcc3SJonas Devlieghere                    },
3732238dcc3SJonas Devlieghere                ],
3742238dcc3SJonas Devlieghere                True,
3752238dcc3SJonas Devlieghere            )
37699451b44SJordan Rupprecht            context = self.expect_gdbremote_sequence()
37799451b44SJordan Rupprecht            self.assertIsNotNone(context)
37899451b44SJordan Rupprecht
37999451b44SJordan Rupprecht            # Verify the response length.
38099451b44SJordan Rupprecht            p_response = context.get("p_response")
38199451b44SJordan Rupprecht            self.assertIsNotNone(p_response)
38299451b44SJordan Rupprecht
3839367b57dSMichał Górny            # Skip erraneous (unsupported) registers.
3849367b57dSMichał Górny            # TODO: remove this once we make unsupported registers disappear.
3859367b57dSMichał Górny            if p_response.startswith("E") and len(p_response) == 3:
3869367b57dSMichał Górny                continue
3879367b57dSMichał Górny
38899451b44SJordan Rupprecht            if "dynamic_size_dwarf_expr_bytes" in reg_info:
38999451b44SJordan Rupprecht                self.updateRegInfoBitsize(reg_info, byte_order)
3902238dcc3SJonas Devlieghere            self.assertEqual(
3912238dcc3SJonas Devlieghere                len(p_response), 2 * int(reg_info["bitsize"]) / 8, reg_info
3922238dcc3SJonas Devlieghere            )
39399451b44SJordan Rupprecht
39499451b44SJordan Rupprecht            # Increment loop
39599451b44SJordan Rupprecht            reg_index += 1
39699451b44SJordan Rupprecht
3976c1a8039SMichał Górny    def Hg_switches_to_3_threads(self, pass_pid=False):
3985a4fe166SPavel Labath        _, threads = self.launch_with_threads(3)
39999451b44SJordan Rupprecht
4006c1a8039SMichał Górny        pid_str = ""
4016c1a8039SMichał Górny        if pass_pid:
4026c1a8039SMichał Górny            pid_str = "p{0:x}.".format(procs["inferior"].pid)
4036c1a8039SMichał Górny
40499451b44SJordan Rupprecht        # verify we can $H to each thead, and $qC matches the thread we set.
40599451b44SJordan Rupprecht        for thread in threads:
40699451b44SJordan Rupprecht            # Change to each thread, verify current thread id.
40799451b44SJordan Rupprecht            self.reset_test_sequence()
40899451b44SJordan Rupprecht            self.test_sequence.add_log_lines(
4092238dcc3SJonas Devlieghere                [
4102238dcc3SJonas Devlieghere                    "read packet: $Hg{0}{1:x}#00".format(
4112238dcc3SJonas Devlieghere                        pid_str, thread
4122238dcc3SJonas Devlieghere                    ),  # Set current thread.
41399451b44SJordan Rupprecht                    "send packet: $OK#00",
41499451b44SJordan Rupprecht                    "read packet: $qC#00",
4152238dcc3SJonas Devlieghere                    {
4162238dcc3SJonas Devlieghere                        "direction": "send",
4172238dcc3SJonas Devlieghere                        "regex": r"^\$QC([0-9a-fA-F]+)#",
4182238dcc3SJonas Devlieghere                        "capture": {1: "thread_id"},
4192238dcc3SJonas Devlieghere                    },
4202238dcc3SJonas Devlieghere                ],
4212238dcc3SJonas Devlieghere                True,
4222238dcc3SJonas Devlieghere            )
42399451b44SJordan Rupprecht
42499451b44SJordan Rupprecht            context = self.expect_gdbremote_sequence()
42599451b44SJordan Rupprecht            self.assertIsNotNone(context)
42699451b44SJordan Rupprecht
42799451b44SJordan Rupprecht            # Verify the thread id.
42899451b44SJordan Rupprecht            self.assertIsNotNone(context.get("thread_id"))
42999451b44SJordan Rupprecht            self.assertEqual(int(context.get("thread_id"), 16), thread)
43099451b44SJordan Rupprecht
4312238dcc3SJonas Devlieghere    @skipIf(compiler="clang", compiler_version=["<", "11.0"])
432a0b68a29SPavel Labath    def test_Hg_switches_to_3_threads_launch(self):
43399451b44SJordan Rupprecht        self.build()
43499451b44SJordan Rupprecht        self.set_inferior_startup_launch()
43599451b44SJordan Rupprecht        self.Hg_switches_to_3_threads()
43699451b44SJordan Rupprecht
4376c1a8039SMichał Górny    def Hg_fails_on_pid(self, pass_pid):
4385a4fe166SPavel Labath        _, threads = self.launch_with_threads(2)
4396c1a8039SMichał Górny
4406c1a8039SMichał Górny        if pass_pid == -1:
4416c1a8039SMichał Górny            pid_str = "p-1."
4426c1a8039SMichał Górny        else:
4436c1a8039SMichał Górny            pid_str = "p{0:x}.".format(pass_pid)
4446c1a8039SMichał Górny        thread = threads[1]
4456c1a8039SMichał Górny
4466c1a8039SMichał Górny        self.test_sequence.add_log_lines(
4472238dcc3SJonas Devlieghere            [
4482238dcc3SJonas Devlieghere                "read packet: $Hg{0}{1:x}#00".format(
4492238dcc3SJonas Devlieghere                    pid_str, thread
4502238dcc3SJonas Devlieghere                ),  # Set current thread.
4512238dcc3SJonas Devlieghere                "send packet: $Eff#00",
4522238dcc3SJonas Devlieghere            ],
4532238dcc3SJonas Devlieghere            True,
4542238dcc3SJonas Devlieghere        )
4556c1a8039SMichał Górny
4566c1a8039SMichał Górny        self.expect_gdbremote_sequence()
4576c1a8039SMichał Górny
458fcea4181SMichał Górny    @add_test_categories(["llgs"])
4596c1a8039SMichał Górny    def test_Hg_fails_on_another_pid(self):
4606c1a8039SMichał Górny        self.build()
4616c1a8039SMichał Górny        self.set_inferior_startup_launch()
4626c1a8039SMichał Górny        self.Hg_fails_on_pid(1)
4636c1a8039SMichał Górny
464fcea4181SMichał Górny    @add_test_categories(["llgs"])
4656c1a8039SMichał Górny    def test_Hg_fails_on_zero_pid(self):
4666c1a8039SMichał Górny        self.build()
4676c1a8039SMichał Górny        self.set_inferior_startup_launch()
4686c1a8039SMichał Górny        self.Hg_fails_on_pid(0)
4696c1a8039SMichał Górny
470fcea4181SMichał Górny    @add_test_categories(["llgs"])
471*5a658ee9SDavid Spickett    @skipIfWindows  # Sometimes returns '$E37'.
4726c1a8039SMichał Górny    def test_Hg_fails_on_minus_one_pid(self):
4736c1a8039SMichał Górny        self.build()
4746c1a8039SMichał Górny        self.set_inferior_startup_launch()
4756c1a8039SMichał Górny        self.Hg_fails_on_pid(-1)
4766c1a8039SMichał Górny
47799451b44SJordan Rupprecht    def Hc_then_Csignal_signals_correct_thread(self, segfault_signo):
47899451b44SJordan Rupprecht        # NOTE only run this one in inferior-launched mode: we can't grab inferior stdout when running attached,
47999451b44SJordan Rupprecht        # and the test requires getting stdout from the exe.
48099451b44SJordan Rupprecht
48199451b44SJordan Rupprecht        NUM_THREADS = 3
48299451b44SJordan Rupprecht
48399451b44SJordan Rupprecht        # Startup the inferior with three threads (main + NUM_THREADS-1 worker threads).
48499451b44SJordan Rupprecht        # inferior_args=["thread:print-ids"]
48599451b44SJordan Rupprecht        inferior_args = ["thread:segfault"]
48699451b44SJordan Rupprecht        for i in range(NUM_THREADS - 1):
48799451b44SJordan Rupprecht            # if i > 0:
48899451b44SJordan Rupprecht            # Give time between thread creation/segfaulting for the handler to work.
48999451b44SJordan Rupprecht            # inferior_args.append("sleep:1")
49099451b44SJordan Rupprecht            inferior_args.append("thread:new")
49199451b44SJordan Rupprecht        inferior_args.append("sleep:10")
49299451b44SJordan Rupprecht
49399451b44SJordan Rupprecht        # Launch/attach.  (In our case, this should only ever be launched since
49499451b44SJordan Rupprecht        # we need inferior stdout/stderr).
4952238dcc3SJonas Devlieghere        procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
49699451b44SJordan Rupprecht        self.test_sequence.add_log_lines(["read packet: $c#63"], True)
49799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
49899451b44SJordan Rupprecht
49999451b44SJordan Rupprecht        signaled_tids = {}
50099451b44SJordan Rupprecht        print_thread_ids = {}
50199451b44SJordan Rupprecht
50299451b44SJordan Rupprecht        # Switch to each thread, deliver a signal, and verify signal delivery
50399451b44SJordan Rupprecht        for i in range(NUM_THREADS - 1):
50499451b44SJordan Rupprecht            # Run until SIGSEGV comes in.
50599451b44SJordan Rupprecht            self.reset_test_sequence()
5062238dcc3SJonas Devlieghere            self.test_sequence.add_log_lines(
5072238dcc3SJonas Devlieghere                [
5082238dcc3SJonas Devlieghere                    {
5092238dcc3SJonas Devlieghere                        "direction": "send",
51099451b44SJordan Rupprecht                        "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
5112238dcc3SJonas Devlieghere                        "capture": {1: "signo", 2: "thread_id"},
5122238dcc3SJonas Devlieghere                    }
5132238dcc3SJonas Devlieghere                ],
5142238dcc3SJonas Devlieghere                True,
5152238dcc3SJonas Devlieghere            )
51699451b44SJordan Rupprecht
5170fbbf3a9SJonas Devlieghere            context = self.expect_gdbremote_sequence()
51899451b44SJordan Rupprecht            self.assertIsNotNone(context)
51999451b44SJordan Rupprecht            signo = context.get("signo")
52099451b44SJordan Rupprecht            self.assertEqual(int(signo, 16), segfault_signo)
52199451b44SJordan Rupprecht
52299451b44SJordan Rupprecht            # Ensure we haven't seen this tid yet.
52399451b44SJordan Rupprecht            thread_id = int(context.get("thread_id"), 16)
5243cc37622SDave Lee            self.assertNotIn(thread_id, signaled_tids)
52599451b44SJordan Rupprecht            signaled_tids[thread_id] = 1
52699451b44SJordan Rupprecht
52799451b44SJordan Rupprecht            # Send SIGUSR1 to the thread that signaled the SIGSEGV.
52899451b44SJordan Rupprecht            self.reset_test_sequence()
52999451b44SJordan Rupprecht            self.test_sequence.add_log_lines(
53099451b44SJordan Rupprecht                [
53199451b44SJordan Rupprecht                    # Set the continue thread.
53299451b44SJordan Rupprecht                    # Set current thread.
53399451b44SJordan Rupprecht                    "read packet: $Hc{0:x}#00".format(thread_id),
53499451b44SJordan Rupprecht                    "send packet: $OK#00",
53599451b44SJordan Rupprecht                    # Continue sending the signal number to the continue thread.
53699451b44SJordan Rupprecht                    # The commented out packet is a way to do this same operation without using
53799451b44SJordan Rupprecht                    # a $Hc (but this test is testing $Hc, so we'll stick with the former).
5382238dcc3SJonas Devlieghere                    "read packet: $C{0:x}#00".format(
5392238dcc3SJonas Devlieghere                        lldbutil.get_signal_number("SIGUSR1")
5402238dcc3SJonas Devlieghere                    ),
54199451b44SJordan Rupprecht                    # "read packet: $vCont;C{0:x}:{1:x};c#00".format(lldbutil.get_signal_number('SIGUSR1'), thread_id),
54299451b44SJordan Rupprecht                    # FIXME: Linux does not report the thread stop on the delivered signal (SIGUSR1 here).  MacOSX debugserver does.
54399451b44SJordan Rupprecht                    # But MacOSX debugserver isn't guaranteeing the thread the signal handler runs on, so currently its an XFAIL.
54499451b44SJordan Rupprecht                    # Need to rectify behavior here.  The linux behavior is more intuitive to me since we're essentially swapping out
54599451b44SJordan Rupprecht                    # an about-to-be-delivered signal (for which we already sent a stop packet) to a different signal.
54699451b44SJordan Rupprecht                    # {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} },
54799451b44SJordan Rupprecht                    #  "read packet: $c#63",
5482238dcc3SJonas Devlieghere                    {
5492238dcc3SJonas Devlieghere                        "type": "output_match",
5502238dcc3SJonas Devlieghere                        "regex": r"^received SIGUSR1 on thread id: ([0-9a-fA-F]+)\r\nthread ([0-9a-fA-F]+): past SIGSEGV\r\n",
5512238dcc3SJonas Devlieghere                        "capture": {1: "print_thread_id", 2: "post_handle_thread_id"},
5522238dcc3SJonas Devlieghere                    },
55399451b44SJordan Rupprecht                ],
5542238dcc3SJonas Devlieghere                True,
5552238dcc3SJonas Devlieghere            )
55699451b44SJordan Rupprecht
55799451b44SJordan Rupprecht            # Run the sequence.
5580fbbf3a9SJonas Devlieghere            context = self.expect_gdbremote_sequence()
55999451b44SJordan Rupprecht            self.assertIsNotNone(context)
56099451b44SJordan Rupprecht
56199451b44SJordan Rupprecht            # Ensure the stop signal is the signal we delivered.
56299451b44SJordan Rupprecht            # stop_signo = context.get("stop_signo")
56399451b44SJordan Rupprecht            # self.assertIsNotNone(stop_signo)
56480fcecb1SJonas Devlieghere            # self.assertEqual(int(stop_signo,16), lldbutil.get_signal_number('SIGUSR1'))
56599451b44SJordan Rupprecht
56699451b44SJordan Rupprecht            # Ensure the stop thread is the thread to which we delivered the signal.
56799451b44SJordan Rupprecht            # stop_thread_id = context.get("stop_thread_id")
56899451b44SJordan Rupprecht            # self.assertIsNotNone(stop_thread_id)
56980fcecb1SJonas Devlieghere            # self.assertEqual(int(stop_thread_id,16), thread_id)
57099451b44SJordan Rupprecht
57199451b44SJordan Rupprecht            # Ensure we haven't seen this thread id yet.  The inferior's
57299451b44SJordan Rupprecht            # self-obtained thread ids are not guaranteed to match the stub
57399451b44SJordan Rupprecht            # tids (at least on MacOSX).
57499451b44SJordan Rupprecht            print_thread_id = context.get("print_thread_id")
57599451b44SJordan Rupprecht            self.assertIsNotNone(print_thread_id)
57699451b44SJordan Rupprecht            print_thread_id = int(print_thread_id, 16)
5773cc37622SDave Lee            self.assertNotIn(print_thread_id, print_thread_ids)
57899451b44SJordan Rupprecht
57999451b44SJordan Rupprecht            # Now remember this print (i.e. inferior-reflected) thread id and
58099451b44SJordan Rupprecht            # ensure we don't hit it again.
58199451b44SJordan Rupprecht            print_thread_ids[print_thread_id] = 1
58299451b44SJordan Rupprecht
58399451b44SJordan Rupprecht            # Ensure post signal-handle thread id matches the thread that
58499451b44SJordan Rupprecht            # initially raised the SIGSEGV.
58599451b44SJordan Rupprecht            post_handle_thread_id = context.get("post_handle_thread_id")
58699451b44SJordan Rupprecht            self.assertIsNotNone(post_handle_thread_id)
58799451b44SJordan Rupprecht            post_handle_thread_id = int(post_handle_thread_id, 16)
58899451b44SJordan Rupprecht            self.assertEqual(post_handle_thread_id, print_thread_id)
58999451b44SJordan Rupprecht
590d9ba8142SPavel Labath    @expectedFailureDarwin
59199451b44SJordan Rupprecht    @skipIfWindows  # no SIGSEGV support
592266c90feSMichał Górny    @expectedFailureNetBSD
593d9ba8142SPavel Labath    def test_Hc_then_Csignal_signals_correct_thread_launch(self):
59499451b44SJordan Rupprecht        self.build()
59599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
596d9ba8142SPavel Labath
597d9ba8142SPavel Labath        if self.platformIsDarwin():
598d9ba8142SPavel Labath            # Darwin debugserver translates some signals like SIGSEGV into some gdb
599d9ba8142SPavel Labath            # expectations about fixed signal numbers.
600d9ba8142SPavel Labath            self.Hc_then_Csignal_signals_correct_thread(self.TARGET_EXC_BAD_ACCESS)
601d9ba8142SPavel Labath        else:
60299451b44SJordan Rupprecht            self.Hc_then_Csignal_signals_correct_thread(
6032238dcc3SJonas Devlieghere                lldbutil.get_signal_number("SIGSEGV")
6042238dcc3SJonas Devlieghere            )
60599451b44SJordan Rupprecht
606d9ba8142SPavel Labath    @skipIfWindows  # No pty support to test any inferior output
607d9ba8142SPavel Labath    def test_m_packet_reads_memory(self):
608d9ba8142SPavel Labath        self.build()
609d9ba8142SPavel Labath        self.set_inferior_startup_launch()
61099451b44SJordan Rupprecht        # This is the memory we will write into the inferior and then ensure we
61199451b44SJordan Rupprecht        # can read back with $m.
61299451b44SJordan Rupprecht        MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
61399451b44SJordan Rupprecht
61499451b44SJordan Rupprecht        # Start up the inferior.
61599451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
61699451b44SJordan Rupprecht            inferior_args=[
6172238dcc3SJonas Devlieghere                "set-message:%s" % MEMORY_CONTENTS,
61899451b44SJordan Rupprecht                "get-data-address-hex:g_message",
6192238dcc3SJonas Devlieghere                "sleep:5",
6202238dcc3SJonas Devlieghere            ]
6212238dcc3SJonas Devlieghere        )
62299451b44SJordan Rupprecht
62399451b44SJordan Rupprecht        # Run the process
62499451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
62599451b44SJordan Rupprecht            [
62699451b44SJordan Rupprecht                # Start running after initial stop.
62799451b44SJordan Rupprecht                "read packet: $c#63",
62899451b44SJordan Rupprecht                # Match output line that prints the memory address of the message buffer within the inferior.
62999451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
6302238dcc3SJonas Devlieghere                {
6312238dcc3SJonas Devlieghere                    "type": "output_match",
6322238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
6332238dcc3SJonas Devlieghere                        r"data address: 0x([0-9a-fA-F]+)\r\n"
6342238dcc3SJonas Devlieghere                    ),
6352238dcc3SJonas Devlieghere                    "capture": {1: "message_address"},
6362238dcc3SJonas Devlieghere                },
63799451b44SJordan Rupprecht                # Now stop the inferior.
63899451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
63999451b44SJordan Rupprecht                # And wait for the stop notification.
6402238dcc3SJonas Devlieghere                {
6412238dcc3SJonas Devlieghere                    "direction": "send",
6422238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
6432238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
6442238dcc3SJonas Devlieghere                },
6452238dcc3SJonas Devlieghere            ],
6462238dcc3SJonas Devlieghere            True,
6472238dcc3SJonas Devlieghere        )
64899451b44SJordan Rupprecht
64999451b44SJordan Rupprecht        # Run the packet stream.
65099451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
65199451b44SJordan Rupprecht        self.assertIsNotNone(context)
65299451b44SJordan Rupprecht
65399451b44SJordan Rupprecht        # Grab the message address.
65499451b44SJordan Rupprecht        self.assertIsNotNone(context.get("message_address"))
65599451b44SJordan Rupprecht        message_address = int(context.get("message_address"), 16)
65699451b44SJordan Rupprecht
65799451b44SJordan Rupprecht        # Grab contents from the inferior.
65899451b44SJordan Rupprecht        self.reset_test_sequence()
65999451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
6602238dcc3SJonas Devlieghere            [
6612238dcc3SJonas Devlieghere                "read packet: $m{0:x},{1:x}#00".format(
6622238dcc3SJonas Devlieghere                    message_address, len(MEMORY_CONTENTS)
6632238dcc3SJonas Devlieghere                ),
6642238dcc3SJonas Devlieghere                {
6652238dcc3SJonas Devlieghere                    "direction": "send",
6662238dcc3SJonas Devlieghere                    "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
6672238dcc3SJonas Devlieghere                    "capture": {1: "read_contents"},
6682238dcc3SJonas Devlieghere                },
6692238dcc3SJonas Devlieghere            ],
6702238dcc3SJonas Devlieghere            True,
6712238dcc3SJonas Devlieghere        )
67299451b44SJordan Rupprecht
67399451b44SJordan Rupprecht        # Run the packet stream.
67499451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
67599451b44SJordan Rupprecht        self.assertIsNotNone(context)
67699451b44SJordan Rupprecht
67799451b44SJordan Rupprecht        # Ensure what we read from inferior memory is what we wrote.
67899451b44SJordan Rupprecht        self.assertIsNotNone(context.get("read_contents"))
67999451b44SJordan Rupprecht        read_contents = seven.unhexlify(context.get("read_contents"))
68099451b44SJordan Rupprecht        self.assertEqual(read_contents, MEMORY_CONTENTS)
68199451b44SJordan Rupprecht
682d9ba8142SPavel Labath    def test_qMemoryRegionInfo_is_supported(self):
68399451b44SJordan Rupprecht        self.build()
68499451b44SJordan Rupprecht        self.set_inferior_startup_launch()
68599451b44SJordan Rupprecht        # Start up the inferior.
68699451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
68799451b44SJordan Rupprecht
68899451b44SJordan Rupprecht        # Ask if it supports $qMemoryRegionInfo.
68999451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
6902238dcc3SJonas Devlieghere            ["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True
6912238dcc3SJonas Devlieghere        )
69299451b44SJordan Rupprecht        self.expect_gdbremote_sequence()
69399451b44SJordan Rupprecht
694d9ba8142SPavel Labath    @skipIfWindows  # No pty support to test any inferior output
695d9ba8142SPavel Labath    def test_qMemoryRegionInfo_reports_code_address_as_executable(self):
69699451b44SJordan Rupprecht        self.build()
69799451b44SJordan Rupprecht        self.set_inferior_startup_launch()
69899451b44SJordan Rupprecht
69999451b44SJordan Rupprecht        # Start up the inferior.
70099451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
7012238dcc3SJonas Devlieghere            inferior_args=["get-code-address-hex:hello", "sleep:5"]
7022238dcc3SJonas Devlieghere        )
70399451b44SJordan Rupprecht
70499451b44SJordan Rupprecht        # Run the process
70599451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
70699451b44SJordan Rupprecht            [
70799451b44SJordan Rupprecht                # Start running after initial stop.
70899451b44SJordan Rupprecht                "read packet: $c#63",
70999451b44SJordan Rupprecht                # Match output line that prints the memory address of the message buffer within the inferior.
71099451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
7112238dcc3SJonas Devlieghere                {
7122238dcc3SJonas Devlieghere                    "type": "output_match",
7132238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
7142238dcc3SJonas Devlieghere                        r"code address: 0x([0-9a-fA-F]+)\r\n"
7152238dcc3SJonas Devlieghere                    ),
7162238dcc3SJonas Devlieghere                    "capture": {1: "code_address"},
7172238dcc3SJonas Devlieghere                },
71899451b44SJordan Rupprecht                # Now stop the inferior.
71999451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
72099451b44SJordan Rupprecht                # And wait for the stop notification.
7212238dcc3SJonas Devlieghere                {
7222238dcc3SJonas Devlieghere                    "direction": "send",
7232238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
7242238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
7252238dcc3SJonas Devlieghere                },
7262238dcc3SJonas Devlieghere            ],
7272238dcc3SJonas Devlieghere            True,
7282238dcc3SJonas Devlieghere        )
72999451b44SJordan Rupprecht
73099451b44SJordan Rupprecht        # Run the packet stream.
73199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
73299451b44SJordan Rupprecht        self.assertIsNotNone(context)
73399451b44SJordan Rupprecht
73499451b44SJordan Rupprecht        # Grab the code address.
73599451b44SJordan Rupprecht        self.assertIsNotNone(context.get("code_address"))
73699451b44SJordan Rupprecht        code_address = int(context.get("code_address"), 16)
73799451b44SJordan Rupprecht
73899451b44SJordan Rupprecht        # Grab memory region info from the inferior.
73999451b44SJordan Rupprecht        self.reset_test_sequence()
74099451b44SJordan Rupprecht        self.add_query_memory_region_packets(code_address)
74199451b44SJordan Rupprecht
74299451b44SJordan Rupprecht        # Run the packet stream.
74399451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
74499451b44SJordan Rupprecht        self.assertIsNotNone(context)
74599451b44SJordan Rupprecht        mem_region_dict = self.parse_memory_region_packet(context)
74699451b44SJordan Rupprecht
74799451b44SJordan Rupprecht        # Ensure there are no errors reported.
7483cc37622SDave Lee        self.assertNotIn("error", mem_region_dict)
74999451b44SJordan Rupprecht
75099451b44SJordan Rupprecht        # Ensure code address is readable and executable.
7513cc37622SDave Lee        self.assertIn("permissions", mem_region_dict)
7523cc37622SDave Lee        self.assertIn("r", mem_region_dict["permissions"])
7533cc37622SDave Lee        self.assertIn("x", mem_region_dict["permissions"])
75499451b44SJordan Rupprecht
75599451b44SJordan Rupprecht        # Ensure the start address and size encompass the address we queried.
75699451b44SJordan Rupprecht        self.assert_address_within_memory_region(code_address, mem_region_dict)
75799451b44SJordan Rupprecht
75899451b44SJordan Rupprecht    @skipIfWindows  # No pty support to test any inferior output
759d9ba8142SPavel Labath    def test_qMemoryRegionInfo_reports_stack_address_as_rw(self):
76099451b44SJordan Rupprecht        self.build()
76199451b44SJordan Rupprecht        self.set_inferior_startup_launch()
76299451b44SJordan Rupprecht
76399451b44SJordan Rupprecht        # Start up the inferior.
76499451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
7652238dcc3SJonas Devlieghere            inferior_args=["get-stack-address-hex:", "sleep:5"]
7662238dcc3SJonas Devlieghere        )
76799451b44SJordan Rupprecht
76899451b44SJordan Rupprecht        # Run the process
76999451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
77099451b44SJordan Rupprecht            [
77199451b44SJordan Rupprecht                # Start running after initial stop.
77299451b44SJordan Rupprecht                "read packet: $c#63",
77399451b44SJordan Rupprecht                # Match output line that prints the memory address of the message buffer within the inferior.
77499451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
7752238dcc3SJonas Devlieghere                {
7762238dcc3SJonas Devlieghere                    "type": "output_match",
7772238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
7782238dcc3SJonas Devlieghere                        r"stack address: 0x([0-9a-fA-F]+)\r\n"
7792238dcc3SJonas Devlieghere                    ),
7802238dcc3SJonas Devlieghere                    "capture": {1: "stack_address"},
7812238dcc3SJonas Devlieghere                },
78299451b44SJordan Rupprecht                # Now stop the inferior.
78399451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
78499451b44SJordan Rupprecht                # And wait for the stop notification.
7852238dcc3SJonas Devlieghere                {
7862238dcc3SJonas Devlieghere                    "direction": "send",
7872238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
7882238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
7892238dcc3SJonas Devlieghere                },
7902238dcc3SJonas Devlieghere            ],
7912238dcc3SJonas Devlieghere            True,
7922238dcc3SJonas Devlieghere        )
79399451b44SJordan Rupprecht
79499451b44SJordan Rupprecht        # Run the packet stream.
79599451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
79699451b44SJordan Rupprecht        self.assertIsNotNone(context)
79799451b44SJordan Rupprecht
79899451b44SJordan Rupprecht        # Grab the address.
79999451b44SJordan Rupprecht        self.assertIsNotNone(context.get("stack_address"))
80099451b44SJordan Rupprecht        stack_address = int(context.get("stack_address"), 16)
80199451b44SJordan Rupprecht
80299451b44SJordan Rupprecht        # Grab memory region info from the inferior.
80399451b44SJordan Rupprecht        self.reset_test_sequence()
80499451b44SJordan Rupprecht        self.add_query_memory_region_packets(stack_address)
80599451b44SJordan Rupprecht
80699451b44SJordan Rupprecht        # Run the packet stream.
80799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
80899451b44SJordan Rupprecht        self.assertIsNotNone(context)
80999451b44SJordan Rupprecht        mem_region_dict = self.parse_memory_region_packet(context)
81099451b44SJordan Rupprecht
81199451b44SJordan Rupprecht        # Ensure there are no errors reported.
8123cc37622SDave Lee        self.assertNotIn("error", mem_region_dict)
81399451b44SJordan Rupprecht
81499451b44SJordan Rupprecht        # Ensure address is readable and executable.
8153cc37622SDave Lee        self.assertIn("permissions", mem_region_dict)
8163cc37622SDave Lee        self.assertIn("r", mem_region_dict["permissions"])
8173cc37622SDave Lee        self.assertIn("w", mem_region_dict["permissions"])
81899451b44SJordan Rupprecht
81999451b44SJordan Rupprecht        # Ensure the start address and size encompass the address we queried.
8202238dcc3SJonas Devlieghere        self.assert_address_within_memory_region(stack_address, mem_region_dict)
82199451b44SJordan Rupprecht
82299451b44SJordan Rupprecht    @skipIfWindows  # No pty support to test any inferior output
823d9ba8142SPavel Labath    def test_qMemoryRegionInfo_reports_heap_address_as_rw(self):
82499451b44SJordan Rupprecht        self.build()
82599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
82699451b44SJordan Rupprecht
82799451b44SJordan Rupprecht        # Start up the inferior.
82899451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
8292238dcc3SJonas Devlieghere            inferior_args=["get-heap-address-hex:", "sleep:5"]
8302238dcc3SJonas Devlieghere        )
83199451b44SJordan Rupprecht
83299451b44SJordan Rupprecht        # Run the process
83399451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
83499451b44SJordan Rupprecht            [
83599451b44SJordan Rupprecht                # Start running after initial stop.
83699451b44SJordan Rupprecht                "read packet: $c#63",
83799451b44SJordan Rupprecht                # Match output line that prints the memory address of the message buffer within the inferior.
83899451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
8392238dcc3SJonas Devlieghere                {
8402238dcc3SJonas Devlieghere                    "type": "output_match",
8412238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
8422238dcc3SJonas Devlieghere                        r"heap address: 0x([0-9a-fA-F]+)\r\n"
8432238dcc3SJonas Devlieghere                    ),
8442238dcc3SJonas Devlieghere                    "capture": {1: "heap_address"},
8452238dcc3SJonas Devlieghere                },
84699451b44SJordan Rupprecht                # Now stop the inferior.
84799451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
84899451b44SJordan Rupprecht                # And wait for the stop notification.
8492238dcc3SJonas Devlieghere                {
8502238dcc3SJonas Devlieghere                    "direction": "send",
8512238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
8522238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
8532238dcc3SJonas Devlieghere                },
8542238dcc3SJonas Devlieghere            ],
8552238dcc3SJonas Devlieghere            True,
8562238dcc3SJonas Devlieghere        )
85799451b44SJordan Rupprecht
85899451b44SJordan Rupprecht        # Run the packet stream.
85999451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
86099451b44SJordan Rupprecht        self.assertIsNotNone(context)
86199451b44SJordan Rupprecht
86299451b44SJordan Rupprecht        # Grab the address.
86399451b44SJordan Rupprecht        self.assertIsNotNone(context.get("heap_address"))
86499451b44SJordan Rupprecht        heap_address = int(context.get("heap_address"), 16)
86599451b44SJordan Rupprecht
86699451b44SJordan Rupprecht        # Grab memory region info from the inferior.
86799451b44SJordan Rupprecht        self.reset_test_sequence()
86899451b44SJordan Rupprecht        self.add_query_memory_region_packets(heap_address)
86999451b44SJordan Rupprecht
87099451b44SJordan Rupprecht        # Run the packet stream.
87199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
87299451b44SJordan Rupprecht        self.assertIsNotNone(context)
87399451b44SJordan Rupprecht        mem_region_dict = self.parse_memory_region_packet(context)
87499451b44SJordan Rupprecht
87599451b44SJordan Rupprecht        # Ensure there are no errors reported.
8763cc37622SDave Lee        self.assertNotIn("error", mem_region_dict)
87799451b44SJordan Rupprecht
87899451b44SJordan Rupprecht        # Ensure address is readable and executable.
8793cc37622SDave Lee        self.assertIn("permissions", mem_region_dict)
8803cc37622SDave Lee        self.assertIn("r", mem_region_dict["permissions"])
8813cc37622SDave Lee        self.assertIn("w", mem_region_dict["permissions"])
88299451b44SJordan Rupprecht
88399451b44SJordan Rupprecht        # Ensure the start address and size encompass the address we queried.
88499451b44SJordan Rupprecht        self.assert_address_within_memory_region(heap_address, mem_region_dict)
88599451b44SJordan Rupprecht
886d9ba8142SPavel Labath    def breakpoint_set_and_remove_work(self, want_hardware):
88799451b44SJordan Rupprecht        # Start up the inferior.
88899451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
88999451b44SJordan Rupprecht            inferior_args=[
89099451b44SJordan Rupprecht                "get-code-address-hex:hello",
89199451b44SJordan Rupprecht                "sleep:1",
8922238dcc3SJonas Devlieghere                "call-function:hello",
8932238dcc3SJonas Devlieghere            ]
8942238dcc3SJonas Devlieghere        )
89599451b44SJordan Rupprecht
89699451b44SJordan Rupprecht        # Run the process
89799451b44SJordan Rupprecht        self.add_register_info_collection_packets()
89899451b44SJordan Rupprecht        self.add_process_info_collection_packets()
89999451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
90099451b44SJordan Rupprecht            [  # Start running after initial stop.
90199451b44SJordan Rupprecht                "read packet: $c#63",
90299451b44SJordan Rupprecht                # Match output line that prints the memory address of the function call entry point.
90399451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
9042238dcc3SJonas Devlieghere                {
9052238dcc3SJonas Devlieghere                    "type": "output_match",
9062238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
9072238dcc3SJonas Devlieghere                        r"code address: 0x([0-9a-fA-F]+)\r\n"
9082238dcc3SJonas Devlieghere                    ),
9092238dcc3SJonas Devlieghere                    "capture": {1: "function_address"},
9102238dcc3SJonas Devlieghere                },
91199451b44SJordan Rupprecht                # Now stop the inferior.
91299451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
91399451b44SJordan Rupprecht                # And wait for the stop notification.
9142238dcc3SJonas Devlieghere                {
9152238dcc3SJonas Devlieghere                    "direction": "send",
9162238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
9172238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
9182238dcc3SJonas Devlieghere                },
9192238dcc3SJonas Devlieghere            ],
9202238dcc3SJonas Devlieghere            True,
9212238dcc3SJonas Devlieghere        )
92299451b44SJordan Rupprecht
92399451b44SJordan Rupprecht        # Run the packet stream.
92499451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
92599451b44SJordan Rupprecht        self.assertIsNotNone(context)
92699451b44SJordan Rupprecht
92799451b44SJordan Rupprecht        # Gather process info - we need endian of target to handle register
92899451b44SJordan Rupprecht        # value conversions.
92999451b44SJordan Rupprecht        process_info = self.parse_process_info_response(context)
93099451b44SJordan Rupprecht        endian = process_info.get("endian")
93199451b44SJordan Rupprecht        self.assertIsNotNone(endian)
93299451b44SJordan Rupprecht
93399451b44SJordan Rupprecht        # Gather register info entries.
93499451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
93599451b44SJordan Rupprecht        (pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_infos)
93699451b44SJordan Rupprecht        self.assertIsNotNone(pc_lldb_reg_index)
93799451b44SJordan Rupprecht        self.assertIsNotNone(pc_reg_info)
93899451b44SJordan Rupprecht
93999451b44SJordan Rupprecht        # Grab the function address.
94099451b44SJordan Rupprecht        self.assertIsNotNone(context.get("function_address"))
94199451b44SJordan Rupprecht        function_address = int(context.get("function_address"), 16)
94299451b44SJordan Rupprecht
94399451b44SJordan Rupprecht        # Get current target architecture
94499451b44SJordan Rupprecht        target_arch = self.getArchitecture()
94599451b44SJordan Rupprecht
94699451b44SJordan Rupprecht        # Set the breakpoint.
947b9a30b69SJonas Devlieghere        if target_arch in ["arm", "arm64", "aarch64"]:
94899451b44SJordan Rupprecht            # TODO: Handle case when setting breakpoint in thumb code
94999451b44SJordan Rupprecht            BREAKPOINT_KIND = 4
95099451b44SJordan Rupprecht        else:
95199451b44SJordan Rupprecht            BREAKPOINT_KIND = 1
95299451b44SJordan Rupprecht
95399451b44SJordan Rupprecht        # Set default packet type to Z0 (software breakpoint)
95499451b44SJordan Rupprecht        z_packet_type = 0
95599451b44SJordan Rupprecht
95699451b44SJordan Rupprecht        # If hardware breakpoint is requested set packet type to Z1
957fd35a923SEisuke Kawashima        if want_hardware:
95899451b44SJordan Rupprecht            z_packet_type = 1
95999451b44SJordan Rupprecht
96099451b44SJordan Rupprecht        self.reset_test_sequence()
96199451b44SJordan Rupprecht        self.add_set_breakpoint_packets(
96299451b44SJordan Rupprecht            function_address,
96399451b44SJordan Rupprecht            z_packet_type,
96499451b44SJordan Rupprecht            do_continue=True,
9652238dcc3SJonas Devlieghere            breakpoint_kind=BREAKPOINT_KIND,
9662238dcc3SJonas Devlieghere        )
96799451b44SJordan Rupprecht
96899451b44SJordan Rupprecht        # Run the packet stream.
96999451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
97099451b44SJordan Rupprecht        self.assertIsNotNone(context)
97199451b44SJordan Rupprecht
97299451b44SJordan Rupprecht        # Verify the stop signal reported was the breakpoint signal number.
97399451b44SJordan Rupprecht        stop_signo = context.get("stop_signo")
97499451b44SJordan Rupprecht        self.assertIsNotNone(stop_signo)
9752238dcc3SJonas Devlieghere        self.assertEqual(int(stop_signo, 16), lldbutil.get_signal_number("SIGTRAP"))
97699451b44SJordan Rupprecht
97799451b44SJordan Rupprecht        # Ensure we did not receive any output.  If the breakpoint was not set, we would
97899451b44SJordan Rupprecht        # see output (from a launched process with captured stdio) printing a hello, world message.
97999451b44SJordan Rupprecht        # That would indicate the breakpoint didn't take.
98099451b44SJordan Rupprecht        self.assertEqual(len(context["O_content"]), 0)
98199451b44SJordan Rupprecht
98299451b44SJordan Rupprecht        # Verify that the PC for the main thread is where we expect it - right at the breakpoint address.
98399451b44SJordan Rupprecht        # This acts as a another validation on the register reading code.
98499451b44SJordan Rupprecht        self.reset_test_sequence()
98599451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
98699451b44SJordan Rupprecht            [
98799451b44SJordan Rupprecht                # Print the PC.  This should match the breakpoint address.
98899451b44SJordan Rupprecht                "read packet: $p{0:x}#00".format(pc_lldb_reg_index),
98999451b44SJordan Rupprecht                # Capture $p results.
9902238dcc3SJonas Devlieghere                {
9912238dcc3SJonas Devlieghere                    "direction": "send",
99299451b44SJordan Rupprecht                    "regex": r"^\$([0-9a-fA-F]+)#",
9932238dcc3SJonas Devlieghere                    "capture": {1: "p_response"},
9942238dcc3SJonas Devlieghere                },
9952238dcc3SJonas Devlieghere            ],
9962238dcc3SJonas Devlieghere            True,
9972238dcc3SJonas Devlieghere        )
99899451b44SJordan Rupprecht
99999451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
100099451b44SJordan Rupprecht        self.assertIsNotNone(context)
100199451b44SJordan Rupprecht
100299451b44SJordan Rupprecht        # Verify the PC is where we expect.  Note response is in endianness of
100399451b44SJordan Rupprecht        # the inferior.
100499451b44SJordan Rupprecht        p_response = context.get("p_response")
100599451b44SJordan Rupprecht        self.assertIsNotNone(p_response)
100699451b44SJordan Rupprecht
100799451b44SJordan Rupprecht        # Convert from target endian to int.
100899451b44SJordan Rupprecht        returned_pc = lldbgdbserverutils.unpack_register_hex_unsigned(
10092238dcc3SJonas Devlieghere            endian, p_response
10102238dcc3SJonas Devlieghere        )
101199451b44SJordan Rupprecht        self.assertEqual(returned_pc, function_address)
101299451b44SJordan Rupprecht
101399451b44SJordan Rupprecht        # Verify that a breakpoint remove and continue gets us the expected
101499451b44SJordan Rupprecht        # output.
101599451b44SJordan Rupprecht        self.reset_test_sequence()
101699451b44SJordan Rupprecht
101799451b44SJordan Rupprecht        # Add breakpoint remove packets
101899451b44SJordan Rupprecht        self.add_remove_breakpoint_packets(
10192238dcc3SJonas Devlieghere            function_address, z_packet_type, breakpoint_kind=BREAKPOINT_KIND
10202238dcc3SJonas Devlieghere        )
102199451b44SJordan Rupprecht
102299451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
102399451b44SJordan Rupprecht            [
102499451b44SJordan Rupprecht                # Continue running.
102599451b44SJordan Rupprecht                "read packet: $c#63",
102699451b44SJordan Rupprecht                # We should now receive the output from the call.
102799451b44SJordan Rupprecht                {"type": "output_match", "regex": r"^hello, world\r\n$"},
102899451b44SJordan Rupprecht                # And wait for program completion.
102999451b44SJordan Rupprecht                {"direction": "send", "regex": r"^\$W00(.*)#[0-9a-fA-F]{2}$"},
10302238dcc3SJonas Devlieghere            ],
10312238dcc3SJonas Devlieghere            True,
10322238dcc3SJonas Devlieghere        )
103399451b44SJordan Rupprecht
103499451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
103599451b44SJordan Rupprecht        self.assertIsNotNone(context)
103699451b44SJordan Rupprecht
103799451b44SJordan Rupprecht    @skipIfWindows  # No pty support to test any inferior output
1038d9ba8142SPavel Labath    def test_software_breakpoint_set_and_remove_work(self):
103999451b44SJordan Rupprecht        if self.getArchitecture() == "arm":
104099451b44SJordan Rupprecht            # TODO: Handle case when setting breakpoint in thumb code
10412238dcc3SJonas Devlieghere            self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
104299451b44SJordan Rupprecht        else:
104399451b44SJordan Rupprecht            self.build()
104499451b44SJordan Rupprecht        self.set_inferior_startup_launch()
104599451b44SJordan Rupprecht        self.breakpoint_set_and_remove_work(want_hardware=False)
104699451b44SJordan Rupprecht
10472238dcc3SJonas Devlieghere    @skipUnlessPlatform(oslist=["linux"])
10482238dcc3SJonas Devlieghere    @skipIf(archs=no_match(["arm", "aarch64"]))
1049d9ba8142SPavel Labath    def test_hardware_breakpoint_set_and_remove_work(self):
105099451b44SJordan Rupprecht        if self.getArchitecture() == "arm":
105199451b44SJordan Rupprecht            # TODO: Handle case when setting breakpoint in thumb code
10522238dcc3SJonas Devlieghere            self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
105399451b44SJordan Rupprecht        else:
105499451b44SJordan Rupprecht            self.build()
105599451b44SJordan Rupprecht        self.set_inferior_startup_launch()
105699451b44SJordan Rupprecht        self.breakpoint_set_and_remove_work(want_hardware=True)
105799451b44SJordan Rupprecht
105831225768SMichał Górny    def get_qSupported_dict(self, features=[]):
105999451b44SJordan Rupprecht        self.build()
106099451b44SJordan Rupprecht        self.set_inferior_startup_launch()
106199451b44SJordan Rupprecht
106299451b44SJordan Rupprecht        # Start up the stub and start/prep the inferior.
106399451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior()
106431225768SMichał Górny        self.add_qSupported_packets(features)
106599451b44SJordan Rupprecht
106699451b44SJordan Rupprecht        # Run the packet stream.
106799451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
106899451b44SJordan Rupprecht        self.assertIsNotNone(context)
106999451b44SJordan Rupprecht
107099451b44SJordan Rupprecht        # Retrieve the qSupported features.
107131225768SMichał Górny        return self.parse_qSupported_response(context)
107231225768SMichał Górny
107331225768SMichał Górny    def test_qSupported_returns_known_stub_features(self):
107431225768SMichał Górny        supported_dict = self.get_qSupported_dict()
107599451b44SJordan Rupprecht        self.assertIsNotNone(supported_dict)
10769c246882SJordan Rupprecht        self.assertGreater(len(supported_dict), 0)
107799451b44SJordan Rupprecht
1078ca7824c2SMichał Górny    def test_qSupported_auvx(self):
10792238dcc3SJonas Devlieghere        expected = (
10802238dcc3SJonas Devlieghere            "+"
10812238dcc3SJonas Devlieghere            if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
10822238dcc3SJonas Devlieghere            else "-"
10832238dcc3SJonas Devlieghere        )
1084ca7824c2SMichał Górny        supported_dict = self.get_qSupported_dict()
10852238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("qXfer:auxv:read", "-"), expected)
1086ca7824c2SMichał Górny
1087ca7824c2SMichał Górny    def test_qSupported_libraries_svr4(self):
10882238dcc3SJonas Devlieghere        expected = (
10892238dcc3SJonas Devlieghere            "+"
10902238dcc3SJonas Devlieghere            if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
10912238dcc3SJonas Devlieghere            else "-"
10922238dcc3SJonas Devlieghere        )
1093ca7824c2SMichał Górny        supported_dict = self.get_qSupported_dict()
10942238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("qXfer:libraries-svr4:read", "-"), expected)
1095ca7824c2SMichał Górny
10961e74e5e9SMichał Górny    def test_qSupported_siginfo_read(self):
10972238dcc3SJonas Devlieghere        expected = (
10982238dcc3SJonas Devlieghere            "+" if lldbplatformutil.getPlatform() in ["freebsd", "linux"] else "-"
10992238dcc3SJonas Devlieghere        )
11001e74e5e9SMichał Górny        supported_dict = self.get_qSupported_dict()
11012238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("qXfer:siginfo:read", "-"), expected)
11021e74e5e9SMichał Górny
1103ca7824c2SMichał Górny    def test_qSupported_QPassSignals(self):
11042238dcc3SJonas Devlieghere        expected = (
11052238dcc3SJonas Devlieghere            "+"
11062238dcc3SJonas Devlieghere            if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
11072238dcc3SJonas Devlieghere            else "-"
11082238dcc3SJonas Devlieghere        )
1109ca7824c2SMichał Górny        supported_dict = self.get_qSupported_dict()
11102238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("QPassSignals", "-"), expected)
1111ca7824c2SMichał Górny
111231225768SMichał Górny    @add_test_categories(["fork"])
111331225768SMichał Górny    def test_qSupported_fork_events(self):
11142238dcc3SJonas Devlieghere        supported_dict = self.get_qSupported_dict(["multiprocess+", "fork-events+"])
11152238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
11162238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("fork-events", "-"), "+")
11172238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
111831225768SMichał Górny
111931225768SMichał Górny    @add_test_categories(["fork"])
112031225768SMichał Górny    def test_qSupported_fork_events_without_multiprocess(self):
11212238dcc3SJonas Devlieghere        supported_dict = self.get_qSupported_dict(["fork-events+"])
11222238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
11232238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("fork-events", "-"), "-")
11242238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
112531225768SMichał Górny
112631225768SMichał Górny    @add_test_categories(["fork"])
112731225768SMichał Górny    def test_qSupported_vfork_events(self):
11282238dcc3SJonas Devlieghere        supported_dict = self.get_qSupported_dict(["multiprocess+", "vfork-events+"])
11292238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
11302238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("fork-events", "-"), "-")
11312238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("vfork-events", "-"), "+")
113231225768SMichał Górny
113331225768SMichał Górny    @add_test_categories(["fork"])
113431225768SMichał Górny    def test_qSupported_vfork_events_without_multiprocess(self):
11352238dcc3SJonas Devlieghere        supported_dict = self.get_qSupported_dict(["vfork-events+"])
11362238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
11372238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("fork-events", "-"), "-")
11382238dcc3SJonas Devlieghere        self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
113931225768SMichał Górny
11408d58fbd0SDavid Spickett    # We need to be able to self.runCmd to get cpuinfo,
11418d58fbd0SDavid Spickett    # which is not possible when using a remote platform.
11428d58fbd0SDavid Spickett    @skipIfRemote
11438d58fbd0SDavid Spickett    def test_qSupported_memory_tagging(self):
11448d58fbd0SDavid Spickett        supported_dict = self.get_qSupported_dict()
11452238dcc3SJonas Devlieghere        self.assertEqual(
11462238dcc3SJonas Devlieghere            supported_dict.get("memory-tagging", "-"),
11472238dcc3SJonas Devlieghere            "+" if self.isAArch64MTE() else "-",
11482238dcc3SJonas Devlieghere        )
11498d58fbd0SDavid Spickett
1150d9ba8142SPavel Labath    @skipIfWindows  # No pty support to test any inferior output
1151d9ba8142SPavel Labath    def test_written_M_content_reads_back_correctly(self):
115299451b44SJordan Rupprecht        self.build()
115399451b44SJordan Rupprecht        self.set_inferior_startup_launch()
115499451b44SJordan Rupprecht
115599451b44SJordan Rupprecht        TEST_MESSAGE = "Hello, memory"
115699451b44SJordan Rupprecht
115799451b44SJordan Rupprecht        # Start up the stub and start/prep the inferior.
115899451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(
115999451b44SJordan Rupprecht            inferior_args=[
116099451b44SJordan Rupprecht                "set-message:xxxxxxxxxxxxxX",
116199451b44SJordan Rupprecht                "get-data-address-hex:g_message",
116299451b44SJordan Rupprecht                "sleep:1",
11632238dcc3SJonas Devlieghere                "print-message:",
11642238dcc3SJonas Devlieghere            ]
11652238dcc3SJonas Devlieghere        )
116699451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
116799451b44SJordan Rupprecht            [
116899451b44SJordan Rupprecht                # Start running after initial stop.
116999451b44SJordan Rupprecht                "read packet: $c#63",
117099451b44SJordan Rupprecht                # Match output line that prints the memory address of the message buffer within the inferior.
117199451b44SJordan Rupprecht                # Note we require launch-only testing so we can get inferior otuput.
11722238dcc3SJonas Devlieghere                {
11732238dcc3SJonas Devlieghere                    "type": "output_match",
11742238dcc3SJonas Devlieghere                    "regex": self.maybe_strict_output_regex(
11752238dcc3SJonas Devlieghere                        r"data address: 0x([0-9a-fA-F]+)\r\n"
11762238dcc3SJonas Devlieghere                    ),
11772238dcc3SJonas Devlieghere                    "capture": {1: "message_address"},
11782238dcc3SJonas Devlieghere                },
117999451b44SJordan Rupprecht                # Now stop the inferior.
118099451b44SJordan Rupprecht                "read packet: {}".format(chr(3)),
118199451b44SJordan Rupprecht                # And wait for the stop notification.
11822238dcc3SJonas Devlieghere                {
11832238dcc3SJonas Devlieghere                    "direction": "send",
11842238dcc3SJonas Devlieghere                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
11852238dcc3SJonas Devlieghere                    "capture": {1: "stop_signo", 2: "stop_thread_id"},
11862238dcc3SJonas Devlieghere                },
11872238dcc3SJonas Devlieghere            ],
11882238dcc3SJonas Devlieghere            True,
11892238dcc3SJonas Devlieghere        )
119099451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
119199451b44SJordan Rupprecht        self.assertIsNotNone(context)
119299451b44SJordan Rupprecht
119399451b44SJordan Rupprecht        # Grab the message address.
119499451b44SJordan Rupprecht        self.assertIsNotNone(context.get("message_address"))
119599451b44SJordan Rupprecht        message_address = int(context.get("message_address"), 16)
119699451b44SJordan Rupprecht
119799451b44SJordan Rupprecht        # Hex-encode the test message, adding null termination.
119899451b44SJordan Rupprecht        hex_encoded_message = seven.hexlify(TEST_MESSAGE)
119999451b44SJordan Rupprecht
120099451b44SJordan Rupprecht        # Write the message to the inferior. Verify that we can read it with the hex-encoded (m)
120199451b44SJordan Rupprecht        # and binary (x) memory read packets.
120299451b44SJordan Rupprecht        self.reset_test_sequence()
120399451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
12042238dcc3SJonas Devlieghere            [
12052238dcc3SJonas Devlieghere                "read packet: $M{0:x},{1:x}:{2}#00".format(
12062238dcc3SJonas Devlieghere                    message_address, len(TEST_MESSAGE), hex_encoded_message
12072238dcc3SJonas Devlieghere                ),
120899451b44SJordan Rupprecht                "send packet: $OK#00",
12092238dcc3SJonas Devlieghere                "read packet: $m{0:x},{1:x}#00".format(
12102238dcc3SJonas Devlieghere                    message_address, len(TEST_MESSAGE)
12112238dcc3SJonas Devlieghere                ),
121299451b44SJordan Rupprecht                "send packet: ${0}#00".format(hex_encoded_message),
12132238dcc3SJonas Devlieghere                "read packet: $x{0:x},{1:x}#00".format(
12142238dcc3SJonas Devlieghere                    message_address, len(TEST_MESSAGE)
12152238dcc3SJonas Devlieghere                ),
121699451b44SJordan Rupprecht                "send packet: ${0}#00".format(TEST_MESSAGE),
121799451b44SJordan Rupprecht                "read packet: $m{0:x},4#00".format(message_address),
121899451b44SJordan Rupprecht                "send packet: ${0}#00".format(hex_encoded_message[0:8]),
121999451b44SJordan Rupprecht                "read packet: $x{0:x},4#00".format(message_address),
122099451b44SJordan Rupprecht                "send packet: ${0}#00".format(TEST_MESSAGE[0:4]),
122199451b44SJordan Rupprecht                "read packet: $c#63",
12222238dcc3SJonas Devlieghere                {
12232238dcc3SJonas Devlieghere                    "type": "output_match",
12242238dcc3SJonas Devlieghere                    "regex": r"^message: (.+)\r\n$",
12252238dcc3SJonas Devlieghere                    "capture": {1: "printed_message"},
12262238dcc3SJonas Devlieghere                },
122799451b44SJordan Rupprecht                "send packet: $W00#00",
12282238dcc3SJonas Devlieghere            ],
12292238dcc3SJonas Devlieghere            True,
12302238dcc3SJonas Devlieghere        )
123199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
123299451b44SJordan Rupprecht        self.assertIsNotNone(context)
123399451b44SJordan Rupprecht
123499451b44SJordan Rupprecht        # Ensure what we read from inferior memory is what we wrote.
123599451b44SJordan Rupprecht        printed_message = context.get("printed_message")
123699451b44SJordan Rupprecht        self.assertIsNotNone(printed_message)
123799451b44SJordan Rupprecht        self.assertEqual(printed_message, TEST_MESSAGE + "X")
123899451b44SJordan Rupprecht
1239d9ba8142SPavel Labath    # Note: as of this moment, a hefty number of the GPR writes are failing with E32 (everything except rax-rdx, rdi, rsi, rbp).
1240d9ba8142SPavel Labath    # Come back to this.  I have the test rigged to verify that at least some
1241d9ba8142SPavel Labath    # of the bit-flip writes work.
1242d9ba8142SPavel Labath    def test_P_writes_all_gpr_registers(self):
124399451b44SJordan Rupprecht        self.build()
124499451b44SJordan Rupprecht        self.set_inferior_startup_launch()
124599451b44SJordan Rupprecht
124699451b44SJordan Rupprecht        # Start inferior debug session, grab all register info.
124799451b44SJordan Rupprecht        procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
124899451b44SJordan Rupprecht        self.add_register_info_collection_packets()
124999451b44SJordan Rupprecht        self.add_process_info_collection_packets()
125099451b44SJordan Rupprecht
125199451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
125299451b44SJordan Rupprecht        self.assertIsNotNone(context)
125399451b44SJordan Rupprecht
125499451b44SJordan Rupprecht        # Process register infos.
125599451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
125699451b44SJordan Rupprecht        self.assertIsNotNone(reg_infos)
125799451b44SJordan Rupprecht        self.add_lldb_register_index(reg_infos)
125899451b44SJordan Rupprecht
125999451b44SJordan Rupprecht        # Process endian.
126099451b44SJordan Rupprecht        process_info = self.parse_process_info_response(context)
126199451b44SJordan Rupprecht        endian = process_info.get("endian")
126299451b44SJordan Rupprecht        self.assertIsNotNone(endian)
126399451b44SJordan Rupprecht
126499451b44SJordan Rupprecht        # Pull out the register infos that we think we can bit flip
126599451b44SJordan Rupprecht        # successfully,.
126699451b44SJordan Rupprecht        gpr_reg_infos = [
12672238dcc3SJonas Devlieghere            reg_info
12682238dcc3SJonas Devlieghere            for reg_info in reg_infos
12692238dcc3SJonas Devlieghere            if self.is_bit_flippable_register(reg_info)
12702238dcc3SJonas Devlieghere        ]
12719c246882SJordan Rupprecht        self.assertGreater(len(gpr_reg_infos), 0)
127299451b44SJordan Rupprecht
127399451b44SJordan Rupprecht        # Write flipped bit pattern of existing value to each register.
127499451b44SJordan Rupprecht        (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
12752238dcc3SJonas Devlieghere            gpr_reg_infos, endian
12762238dcc3SJonas Devlieghere        )
12772238dcc3SJonas Devlieghere        self.trace(
12782238dcc3SJonas Devlieghere            "successful writes: {}, failed writes: {}".format(
12792238dcc3SJonas Devlieghere                successful_writes, failed_writes
12802238dcc3SJonas Devlieghere            )
12812238dcc3SJonas Devlieghere        )
12829c246882SJordan Rupprecht        self.assertGreater(successful_writes, 0)
128399451b44SJordan Rupprecht
1284d9ba8142SPavel Labath    # Note: as of this moment, a hefty number of the GPR writes are failing
1285d9ba8142SPavel Labath    # with E32 (everything except rax-rdx, rdi, rsi, rbp).
1286d9ba8142SPavel Labath    @skipIfWindows
1287d9ba8142SPavel Labath    def test_P_and_p_thread_suffix_work(self):
128899451b44SJordan Rupprecht        self.build()
128999451b44SJordan Rupprecht        self.set_inferior_startup_launch()
129099451b44SJordan Rupprecht
129199451b44SJordan Rupprecht        # Startup the inferior with three threads.
12925a4fe166SPavel Labath        _, threads = self.launch_with_threads(3)
12935a4fe166SPavel Labath
12945a4fe166SPavel Labath        self.reset_test_sequence()
129599451b44SJordan Rupprecht        self.add_thread_suffix_request_packets()
129699451b44SJordan Rupprecht        self.add_register_info_collection_packets()
129799451b44SJordan Rupprecht        self.add_process_info_collection_packets()
129899451b44SJordan Rupprecht
129999451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
130099451b44SJordan Rupprecht        self.assertIsNotNone(context)
130199451b44SJordan Rupprecht
130299451b44SJordan Rupprecht        process_info = self.parse_process_info_response(context)
130399451b44SJordan Rupprecht        self.assertIsNotNone(process_info)
130499451b44SJordan Rupprecht        endian = process_info.get("endian")
130599451b44SJordan Rupprecht        self.assertIsNotNone(endian)
130699451b44SJordan Rupprecht
130799451b44SJordan Rupprecht        reg_infos = self.parse_register_info_packets(context)
130899451b44SJordan Rupprecht        self.assertIsNotNone(reg_infos)
130999451b44SJordan Rupprecht        self.add_lldb_register_index(reg_infos)
131099451b44SJordan Rupprecht
131199451b44SJordan Rupprecht        reg_index = self.select_modifiable_register(reg_infos)
131299451b44SJordan Rupprecht        self.assertIsNotNone(reg_index)
131399451b44SJordan Rupprecht        reg_byte_size = int(reg_infos[reg_index]["bitsize"]) // 8
13149c246882SJordan Rupprecht        self.assertGreater(reg_byte_size, 0)
131599451b44SJordan Rupprecht
131699451b44SJordan Rupprecht        expected_reg_values = []
131799451b44SJordan Rupprecht        register_increment = 1
131899451b44SJordan Rupprecht        next_value = None
131999451b44SJordan Rupprecht
132099451b44SJordan Rupprecht        # Set the same register in each of 3 threads to a different value.
132199451b44SJordan Rupprecht        # Verify each one has the unique value.
132299451b44SJordan Rupprecht        for thread in threads:
132399451b44SJordan Rupprecht            # If we don't have a next value yet, start it with the initial read
132499451b44SJordan Rupprecht            # value + 1
132599451b44SJordan Rupprecht            if not next_value:
132699451b44SJordan Rupprecht                # Read pre-existing register value.
132799451b44SJordan Rupprecht                self.reset_test_sequence()
132899451b44SJordan Rupprecht                self.test_sequence.add_log_lines(
13292238dcc3SJonas Devlieghere                    [
13302238dcc3SJonas Devlieghere                        "read packet: $p{0:x};thread:{1:x}#00".format(
13312238dcc3SJonas Devlieghere                            reg_index, thread
13322238dcc3SJonas Devlieghere                        ),
13332238dcc3SJonas Devlieghere                        {
13342238dcc3SJonas Devlieghere                            "direction": "send",
13352238dcc3SJonas Devlieghere                            "regex": r"^\$([0-9a-fA-F]+)#",
13362238dcc3SJonas Devlieghere                            "capture": {1: "p_response"},
13372238dcc3SJonas Devlieghere                        },
13382238dcc3SJonas Devlieghere                    ],
13392238dcc3SJonas Devlieghere                    True,
13402238dcc3SJonas Devlieghere                )
134199451b44SJordan Rupprecht                context = self.expect_gdbremote_sequence()
134299451b44SJordan Rupprecht                self.assertIsNotNone(context)
134399451b44SJordan Rupprecht
134499451b44SJordan Rupprecht                # Set the next value to use for writing as the increment plus
134599451b44SJordan Rupprecht                # current value.
134699451b44SJordan Rupprecht                p_response = context.get("p_response")
134799451b44SJordan Rupprecht                self.assertIsNotNone(p_response)
134899451b44SJordan Rupprecht                next_value = lldbgdbserverutils.unpack_register_hex_unsigned(
13492238dcc3SJonas Devlieghere                    endian, p_response
13502238dcc3SJonas Devlieghere                )
135199451b44SJordan Rupprecht
135299451b44SJordan Rupprecht            # Set new value using P and thread suffix.
135399451b44SJordan Rupprecht            self.reset_test_sequence()
135499451b44SJordan Rupprecht            self.test_sequence.add_log_lines(
135599451b44SJordan Rupprecht                [
135699451b44SJordan Rupprecht                    "read packet: $P{0:x}={1};thread:{2:x}#00".format(
135799451b44SJordan Rupprecht                        reg_index,
135899451b44SJordan Rupprecht                        lldbgdbserverutils.pack_register_hex(
13592238dcc3SJonas Devlieghere                            endian, next_value, byte_size=reg_byte_size
13602238dcc3SJonas Devlieghere                        ),
13612238dcc3SJonas Devlieghere                        thread,
13622238dcc3SJonas Devlieghere                    ),
136399451b44SJordan Rupprecht                    "send packet: $OK#00",
136499451b44SJordan Rupprecht                ],
13652238dcc3SJonas Devlieghere                True,
13662238dcc3SJonas Devlieghere            )
136799451b44SJordan Rupprecht            context = self.expect_gdbremote_sequence()
136899451b44SJordan Rupprecht            self.assertIsNotNone(context)
136999451b44SJordan Rupprecht
137099451b44SJordan Rupprecht            # Save the value we set.
137199451b44SJordan Rupprecht            expected_reg_values.append(next_value)
137299451b44SJordan Rupprecht
137399451b44SJordan Rupprecht            # Increment value for next thread to use (we want them all
137499451b44SJordan Rupprecht            # different so we can verify they wrote to each thread correctly
137599451b44SJordan Rupprecht            # next.)
137699451b44SJordan Rupprecht            next_value += register_increment
137799451b44SJordan Rupprecht
137899451b44SJordan Rupprecht        # Revisit each thread and verify they have the expected value set for
137999451b44SJordan Rupprecht        # the register we wrote.
138099451b44SJordan Rupprecht        thread_index = 0
138199451b44SJordan Rupprecht        for thread in threads:
138299451b44SJordan Rupprecht            # Read pre-existing register value.
138399451b44SJordan Rupprecht            self.reset_test_sequence()
138499451b44SJordan Rupprecht            self.test_sequence.add_log_lines(
13852238dcc3SJonas Devlieghere                [
13862238dcc3SJonas Devlieghere                    "read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread),
13872238dcc3SJonas Devlieghere                    {
13882238dcc3SJonas Devlieghere                        "direction": "send",
13892238dcc3SJonas Devlieghere                        "regex": r"^\$([0-9a-fA-F]+)#",
13902238dcc3SJonas Devlieghere                        "capture": {1: "p_response"},
13912238dcc3SJonas Devlieghere                    },
13922238dcc3SJonas Devlieghere                ],
13932238dcc3SJonas Devlieghere                True,
13942238dcc3SJonas Devlieghere            )
139599451b44SJordan Rupprecht            context = self.expect_gdbremote_sequence()
139699451b44SJordan Rupprecht            self.assertIsNotNone(context)
139799451b44SJordan Rupprecht
139899451b44SJordan Rupprecht            # Get the register value.
139999451b44SJordan Rupprecht            p_response = context.get("p_response")
140099451b44SJordan Rupprecht            self.assertIsNotNone(p_response)
140199451b44SJordan Rupprecht            read_value = lldbgdbserverutils.unpack_register_hex_unsigned(
14022238dcc3SJonas Devlieghere                endian, p_response
14032238dcc3SJonas Devlieghere            )
140499451b44SJordan Rupprecht
140599451b44SJordan Rupprecht            # Make sure we read back what we wrote.
140699451b44SJordan Rupprecht            self.assertEqual(read_value, expected_reg_values[thread_index])
140799451b44SJordan Rupprecht            thread_index += 1
14086ba3f723SMichał Górny
14091e74e5e9SMichał Górny    @skipUnlessPlatform(oslist=["freebsd", "linux"])
14101e74e5e9SMichał Górny    @add_test_categories(["llgs"])
14111e74e5e9SMichał Górny    def test_qXfer_siginfo_read(self):
14121e74e5e9SMichał Górny        self.build()
14131e74e5e9SMichał Górny        self.set_inferior_startup_launch()
14141e74e5e9SMichał Górny        procs = self.prep_debug_monitor_and_inferior(
14152238dcc3SJonas Devlieghere            inferior_args=["thread:segfault", "thread:new", "sleep:10"]
14162238dcc3SJonas Devlieghere        )
14171e74e5e9SMichał Górny        self.test_sequence.add_log_lines(["read packet: $c#63"], True)
14181e74e5e9SMichał Górny        self.expect_gdbremote_sequence()
14191e74e5e9SMichał Górny
14201e74e5e9SMichał Górny        # Run until SIGSEGV comes in.
14211e74e5e9SMichał Górny        self.reset_test_sequence()
14221e74e5e9SMichał Górny        self.test_sequence.add_log_lines(
14232238dcc3SJonas Devlieghere            [
14242238dcc3SJonas Devlieghere                {
14252238dcc3SJonas Devlieghere                    "direction": "send",
14261e74e5e9SMichał Górny                    "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
14271e74e5e9SMichał Górny                    "capture": {1: "signo", 2: "thread_id"},
14282238dcc3SJonas Devlieghere                }
14292238dcc3SJonas Devlieghere            ],
14302238dcc3SJonas Devlieghere            True,
14312238dcc3SJonas Devlieghere        )
14321e74e5e9SMichał Górny
14331e74e5e9SMichał Górny        # Figure out which thread crashed.
14341e74e5e9SMichał Górny        context = self.expect_gdbremote_sequence()
14351e74e5e9SMichał Górny        self.assertIsNotNone(context)
14362238dcc3SJonas Devlieghere        self.assertEqual(
14372238dcc3SJonas Devlieghere            int(context["signo"], 16), lldbutil.get_signal_number("SIGSEGV")
14382238dcc3SJonas Devlieghere        )
14391e74e5e9SMichał Górny        crashing_thread = int(context["thread_id"], 16)
14401e74e5e9SMichał Górny
14411e74e5e9SMichał Górny        # Grab siginfo for the crashing thread.
14421e74e5e9SMichał Górny        self.reset_test_sequence()
14431e74e5e9SMichał Górny        self.add_process_info_collection_packets()
14441e74e5e9SMichał Górny        self.test_sequence.add_log_lines(
14452238dcc3SJonas Devlieghere            [
14462238dcc3SJonas Devlieghere                "read packet: $Hg{:x}#00".format(crashing_thread),
14471e74e5e9SMichał Górny                "send packet: $OK#00",
14481e74e5e9SMichał Górny                "read packet: $qXfer:siginfo:read::0,80:#00",
14492238dcc3SJonas Devlieghere                {
14502238dcc3SJonas Devlieghere                    "direction": "send",
14512238dcc3SJonas Devlieghere                    "regex": re.compile(
14522238dcc3SJonas Devlieghere                        r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
14532238dcc3SJonas Devlieghere                    ),
14541e74e5e9SMichał Górny                    "capture": {1: "response_type", 2: "content_raw"},
14552238dcc3SJonas Devlieghere                },
14562238dcc3SJonas Devlieghere            ],
14572238dcc3SJonas Devlieghere            True,
14582238dcc3SJonas Devlieghere        )
14591e74e5e9SMichał Górny        context = self.expect_gdbremote_sequence()
14601e74e5e9SMichał Górny        self.assertIsNotNone(context)
14611e74e5e9SMichał Górny
14621e74e5e9SMichał Górny        # Ensure we end up with all data in one packet.
14631e74e5e9SMichał Górny        self.assertEqual(context.get("response_type"), "l")
14641e74e5e9SMichał Górny
14651e74e5e9SMichał Górny        # Decode binary data.
14661e74e5e9SMichał Górny        content_raw = context.get("content_raw")
14671e74e5e9SMichał Górny        self.assertIsNotNone(content_raw)
14681e74e5e9SMichał Górny        content = self.decode_gdbremote_binary(content_raw).encode("latin1")
14691e74e5e9SMichał Górny
14701e74e5e9SMichał Górny        # Decode siginfo_t.
14711e74e5e9SMichał Górny        process_info = self.parse_process_info_response(context)
14721e74e5e9SMichał Górny        pad = ""
14731e74e5e9SMichał Górny        if process_info["ptrsize"] == "8":
14741e74e5e9SMichał Górny            pad = "i"
14751e74e5e9SMichał Górny        signo_idx = 0
14761e74e5e9SMichał Górny        errno_idx = 1
14771e74e5e9SMichał Górny        code_idx = 2
14781e74e5e9SMichał Górny        addr_idx = -1
14791e74e5e9SMichał Górny        SEGV_MAPERR = 1
14801e74e5e9SMichał Górny        if process_info["ostype"] == "linux":
14811e74e5e9SMichał Górny            # si_signo, si_errno, si_code, [pad], _sifields._sigfault.si_addr
14821e74e5e9SMichał Górny            format_str = "iii{}P".format(pad)
14831e74e5e9SMichał Górny        elif process_info["ostype"].startswith("freebsd"):
14841e74e5e9SMichał Górny            # si_signo, si_errno, si_code, si_pid, si_uid, si_status, si_addr
14851e74e5e9SMichał Górny            format_str = "iiiiiiP"
14861e74e5e9SMichał Górny        elif process_info["ostype"].startswith("netbsd"):
14871e74e5e9SMichał Górny            # _signo, _code, _errno, [pad], _reason._fault._addr
14881e74e5e9SMichał Górny            format_str = "iii{}P".format(pad)
14891e74e5e9SMichał Górny            errno_idx = 2
14901e74e5e9SMichał Górny            code_idx = 1
14911e74e5e9SMichał Górny        else:
14921e74e5e9SMichał Górny            assert False, "unknown ostype"
14931e74e5e9SMichał Górny
14941e74e5e9SMichał Górny        decoder = struct.Struct(format_str)
14951e74e5e9SMichał Górny        decoded = decoder.unpack(content[: decoder.size])
14962238dcc3SJonas Devlieghere        self.assertEqual(decoded[signo_idx], lldbutil.get_signal_number("SIGSEGV"))
14971e74e5e9SMichał Górny        self.assertEqual(decoded[errno_idx], 0)  # si_errno
14981e74e5e9SMichał Górny        self.assertEqual(decoded[code_idx], SEGV_MAPERR)  # si_code
14991e74e5e9SMichał Górny        self.assertEqual(decoded[addr_idx], 0)  # si_addr
1500