xref: /llvm-project/lldb/test/API/tools/lldb-server/attach-wait/TestGdbRemoteAttachWait.py (revision d38ea8c4c84be9496249098053599c24b87f1376)
182ba3f44SPavel Labathimport os
282ba3f44SPavel Labathfrom time import sleep
382ba3f44SPavel Labath
482ba3f44SPavel Labathimport gdbremote_testcase
582ba3f44SPavel Labathimport lldbgdbserverutils
682ba3f44SPavel Labathfrom lldbsuite.test.decorators import *
782ba3f44SPavel Labathfrom lldbsuite.test.lldbtest import *
882ba3f44SPavel Labathfrom lldbsuite.test import lldbutil
982ba3f44SPavel Labath
1082ba3f44SPavel Labath
1182ba3f44SPavel Labathclass TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase):
12d955185bSPavel Labath    def _set_up_inferior(self):
132238dcc3SJonas Devlieghere        self._exe_to_attach = "%s_%d" % (self.testMethodName, os.getpid())
142238dcc3SJonas Devlieghere        self.build(dictionary={"EXE": self._exe_to_attach, "CXX_SOURCES": "main.cpp"})
1582ba3f44SPavel Labath
16d955185bSPavel Labath        if self.getPlatform() != "windows":
17d955185bSPavel Labath            # Use a shim to ensure that the process is ready to be attached from
18d955185bSPavel Labath            # the get-go.
19d955185bSPavel Labath            self._exe_to_run = "shim"
20*d38ea8c4SDmitry Vasilyev            self._exe_to_attach = lldbutil.install_to_target(
21*d38ea8c4SDmitry Vasilyev                self, self.getBuildArtifact(self._exe_to_attach)
22*d38ea8c4SDmitry Vasilyev            )
23*d38ea8c4SDmitry Vasilyev            self._run_args = [self._exe_to_attach]
242238dcc3SJonas Devlieghere            self.build(dictionary={"EXE": self._exe_to_run, "CXX_SOURCES": "shim.cpp"})
25d955185bSPavel Labath        else:
26d955185bSPavel Labath            self._exe_to_run = self._exe_to_attach
27d955185bSPavel Labath            self._run_args = []
28d955185bSPavel Labath
29d955185bSPavel Labath    def _launch_inferior(self, args):
302238dcc3SJonas Devlieghere        inferior = self.spawnSubprocess(self.getBuildArtifact(self._exe_to_run), args)
3182ba3f44SPavel Labath        self.assertIsNotNone(inferior)
329c246882SJordan Rupprecht        self.assertGreater(inferior.pid, 0)
332238dcc3SJonas Devlieghere        self.assertTrue(lldbgdbserverutils.process_is_running(inferior.pid, True))
3482ba3f44SPavel Labath        return inferior
3582ba3f44SPavel Labath
36d955185bSPavel Labath    def _launch_and_wait_for_init(self):
372238dcc3SJonas Devlieghere        sync_file_path = lldbutil.append_to_process_working_directory(
382238dcc3SJonas Devlieghere            self, "process_ready"
392238dcc3SJonas Devlieghere        )
40d955185bSPavel Labath        inferior = self._launch_inferior(self._run_args + [sync_file_path])
41d955185bSPavel Labath        lldbutil.wait_for_file_on_target(self, sync_file_path)
42d955185bSPavel Labath        return inferior
43d955185bSPavel Labath
44d955185bSPavel Labath    def _attach_packet(self, packet_type):
452238dcc3SJonas Devlieghere        return "read packet: ${};{}#00".format(
462238dcc3SJonas Devlieghere            packet_type,
472238dcc3SJonas Devlieghere            lldbgdbserverutils.gdbremote_hex_encode_string(self._exe_to_attach),
482238dcc3SJonas Devlieghere        )
49d955185bSPavel Labath
50d955185bSPavel Labath    @skipIfWindows  # This test is flaky on Windows
51d955185bSPavel Labath    def test_attach_with_vAttachWait(self):
52d955185bSPavel Labath        self._set_up_inferior()
5382ba3f44SPavel Labath
5482ba3f44SPavel Labath        self.set_inferior_startup_attach_manually()
5582ba3f44SPavel Labath        server = self.connect_to_debug_monitor()
56d955185bSPavel Labath        self.do_handshake()
5782ba3f44SPavel Labath
5882ba3f44SPavel Labath        # Launch the first inferior (we shouldn't attach to this one).
59d955185bSPavel Labath        self._launch_and_wait_for_init()
6082ba3f44SPavel Labath
612238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines([self._attach_packet("vAttachWait")], True)
6282ba3f44SPavel Labath        # Run the stream until attachWait.
6382ba3f44SPavel Labath        context = self.expect_gdbremote_sequence()
6482ba3f44SPavel Labath        self.assertIsNotNone(context)
6582ba3f44SPavel Labath
6682ba3f44SPavel Labath        # Sleep so we're sure that the inferior is launched after we ask for the attach.
6782ba3f44SPavel Labath        sleep(1)
6882ba3f44SPavel Labath
6982ba3f44SPavel Labath        # Launch the second inferior (we SHOULD attach to this one).
70d955185bSPavel Labath        inferior_to_attach = self._launch_inferior(self._run_args)
7182ba3f44SPavel Labath
7282ba3f44SPavel Labath        # Make sure the attach succeeded.
732238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines(
742238dcc3SJonas Devlieghere            [
752238dcc3SJonas Devlieghere                {
762238dcc3SJonas Devlieghere                    "direction": "send",
7782ba3f44SPavel Labath                    "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
782238dcc3SJonas Devlieghere                    "capture": {1: "stop_signal_hex"},
792238dcc3SJonas Devlieghere                },
802238dcc3SJonas Devlieghere            ],
812238dcc3SJonas Devlieghere            True,
822238dcc3SJonas Devlieghere        )
8382ba3f44SPavel Labath        self.add_process_info_collection_packets()
8482ba3f44SPavel Labath
8582ba3f44SPavel Labath        # Run the stream sending the response..
8682ba3f44SPavel Labath        context = self.expect_gdbremote_sequence()
8782ba3f44SPavel Labath        self.assertIsNotNone(context)
8882ba3f44SPavel Labath
8982ba3f44SPavel Labath        # Gather process info response.
9082ba3f44SPavel Labath        process_info = self.parse_process_info_response(context)
9182ba3f44SPavel Labath        self.assertIsNotNone(process_info)
9282ba3f44SPavel Labath
9382ba3f44SPavel Labath        # Ensure the process id matches what we expected.
942238dcc3SJonas Devlieghere        pid_text = process_info.get("pid", None)
9582ba3f44SPavel Labath        self.assertIsNotNone(pid_text)
9682ba3f44SPavel Labath        reported_pid = int(pid_text, base=16)
9782ba3f44SPavel Labath        self.assertEqual(reported_pid, inferior_to_attach.pid)
98d955185bSPavel Labath
99d955185bSPavel Labath    @skipIfWindows  # This test is flaky on Windows
100d955185bSPavel Labath    def test_launch_before_attach_with_vAttachOrWait(self):
101d955185bSPavel Labath        self._set_up_inferior()
102d955185bSPavel Labath
103d955185bSPavel Labath        self.set_inferior_startup_attach_manually()
104d955185bSPavel Labath        server = self.connect_to_debug_monitor()
105d955185bSPavel Labath        self.do_handshake()
106d955185bSPavel Labath
107d955185bSPavel Labath        inferior = self._launch_and_wait_for_init()
108d955185bSPavel Labath
109d955185bSPavel Labath        # Add attach packets.
1102238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines(
1112238dcc3SJonas Devlieghere            [
112d955185bSPavel Labath                # Do the attach.
113d955185bSPavel Labath                self._attach_packet("vAttachOrWait"),
114d955185bSPavel Labath                # Expect a stop notification from the attach.
1152238dcc3SJonas Devlieghere                {
1162238dcc3SJonas Devlieghere                    "direction": "send",
117d955185bSPavel Labath                    "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
1182238dcc3SJonas Devlieghere                    "capture": {1: "stop_signal_hex"},
1192238dcc3SJonas Devlieghere                },
1202238dcc3SJonas Devlieghere            ],
1212238dcc3SJonas Devlieghere            True,
1222238dcc3SJonas Devlieghere        )
123d955185bSPavel Labath        self.add_process_info_collection_packets()
124d955185bSPavel Labath
125d955185bSPavel Labath        # Run the stream
126d955185bSPavel Labath        context = self.expect_gdbremote_sequence()
127d955185bSPavel Labath        self.assertIsNotNone(context)
128d955185bSPavel Labath
129d955185bSPavel Labath        # Gather process info response
130d955185bSPavel Labath        process_info = self.parse_process_info_response(context)
131d955185bSPavel Labath        self.assertIsNotNone(process_info)
132d955185bSPavel Labath
133d955185bSPavel Labath        # Ensure the process id matches what we expected.
1342238dcc3SJonas Devlieghere        pid_text = process_info.get("pid", None)
135d955185bSPavel Labath        self.assertIsNotNone(pid_text)
136d955185bSPavel Labath        reported_pid = int(pid_text, base=16)
137d955185bSPavel Labath        self.assertEqual(reported_pid, inferior.pid)
138d955185bSPavel Labath
139d955185bSPavel Labath    @skipIfWindows  # This test is flaky on Windows
140d955185bSPavel Labath    def test_launch_after_attach_with_vAttachOrWait(self):
141d955185bSPavel Labath        self._set_up_inferior()
142d955185bSPavel Labath
143d955185bSPavel Labath        self.set_inferior_startup_attach_manually()
144d955185bSPavel Labath        server = self.connect_to_debug_monitor()
145d955185bSPavel Labath        self.do_handshake()
146d955185bSPavel Labath
1472238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines([self._attach_packet("vAttachOrWait")], True)
148d955185bSPavel Labath        # Run the stream until attachWait.
149d955185bSPavel Labath        context = self.expect_gdbremote_sequence()
150d955185bSPavel Labath        self.assertIsNotNone(context)
151d955185bSPavel Labath
152d955185bSPavel Labath        # Sleep so we're sure that the inferior is launched after we ask for the attach.
153d955185bSPavel Labath        sleep(1)
154d955185bSPavel Labath
155d955185bSPavel Labath        # Launch the inferior.
156d955185bSPavel Labath        inferior = self._launch_inferior(self._run_args)
157d955185bSPavel Labath
158d955185bSPavel Labath        # Make sure the attach succeeded.
1592238dcc3SJonas Devlieghere        self.test_sequence.add_log_lines(
1602238dcc3SJonas Devlieghere            [
1612238dcc3SJonas Devlieghere                {
1622238dcc3SJonas Devlieghere                    "direction": "send",
163d955185bSPavel Labath                    "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
1642238dcc3SJonas Devlieghere                    "capture": {1: "stop_signal_hex"},
1652238dcc3SJonas Devlieghere                },
1662238dcc3SJonas Devlieghere            ],
1672238dcc3SJonas Devlieghere            True,
1682238dcc3SJonas Devlieghere        )
169d955185bSPavel Labath        self.add_process_info_collection_packets()
170d955185bSPavel Labath
171d955185bSPavel Labath        # Run the stream sending the response..
172d955185bSPavel Labath        context = self.expect_gdbremote_sequence()
173d955185bSPavel Labath        self.assertIsNotNone(context)
174d955185bSPavel Labath
175d955185bSPavel Labath        # Gather process info response.
176d955185bSPavel Labath        process_info = self.parse_process_info_response(context)
177d955185bSPavel Labath        self.assertIsNotNone(process_info)
178d955185bSPavel Labath
179d955185bSPavel Labath        # Ensure the process id matches what we expected.
1802238dcc3SJonas Devlieghere        pid_text = process_info.get("pid", None)
181d955185bSPavel Labath        self.assertIsNotNone(pid_text)
182d955185bSPavel Labath        reported_pid = int(pid_text, base=16)
183d955185bSPavel Labath        self.assertEqual(reported_pid, inferior.pid)
184