182ba3f44SPavel Labath 282ba3f44SPavel Labathimport os 382ba3f44SPavel Labathfrom time import sleep 482ba3f44SPavel Labath 582ba3f44SPavel Labathimport gdbremote_testcase 682ba3f44SPavel Labathimport lldbgdbserverutils 782ba3f44SPavel Labathfrom lldbsuite.test.decorators import * 882ba3f44SPavel Labathfrom lldbsuite.test.lldbtest import * 982ba3f44SPavel Labathfrom lldbsuite.test import lldbutil 1082ba3f44SPavel Labath 1182ba3f44SPavel Labath 1282ba3f44SPavel Labathclass TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase): 1382ba3f44SPavel Labath 14*d955185bSPavel Labath def _set_up_inferior(self): 15*d955185bSPavel Labath self._exe_to_attach = '%s_%d' % (self.testMethodName, os.getpid()) 16*d955185bSPavel Labath self.build(dictionary={'EXE': self._exe_to_attach, 'CXX_SOURCES': 'main.cpp'}) 1782ba3f44SPavel Labath 18*d955185bSPavel Labath if self.getPlatform() != "windows": 19*d955185bSPavel Labath # Use a shim to ensure that the process is ready to be attached from 20*d955185bSPavel Labath # the get-go. 21*d955185bSPavel Labath self._exe_to_run = "shim" 22*d955185bSPavel Labath self._run_args = [self.getBuildArtifact(self._exe_to_attach)] 23*d955185bSPavel Labath self.build(dictionary={'EXE': self._exe_to_run, 'CXX_SOURCES': 24*d955185bSPavel Labath 'shim.cpp'}) 25*d955185bSPavel Labath else: 26*d955185bSPavel Labath self._exe_to_run = self._exe_to_attach 27*d955185bSPavel Labath self._run_args = [] 28*d955185bSPavel Labath 29*d955185bSPavel Labath def _launch_inferior(self, args): 30*d955185bSPavel Labath inferior = self.spawnSubprocess(self.getBuildArtifact(self._exe_to_run), 31*d955185bSPavel Labath args) 3282ba3f44SPavel Labath self.assertIsNotNone(inferior) 3382ba3f44SPavel Labath self.assertTrue(inferior.pid > 0) 3482ba3f44SPavel Labath self.assertTrue( 3582ba3f44SPavel Labath lldbgdbserverutils.process_is_running( 3682ba3f44SPavel Labath inferior.pid, True)) 3782ba3f44SPavel Labath return inferior 3882ba3f44SPavel Labath 39*d955185bSPavel Labath def _launch_and_wait_for_init(self): 40*d955185bSPavel Labath sync_file_path = lldbutil.append_to_process_working_directory(self, 41*d955185bSPavel Labath "process_ready") 42*d955185bSPavel Labath inferior = self._launch_inferior(self._run_args + [sync_file_path]) 43*d955185bSPavel Labath lldbutil.wait_for_file_on_target(self, sync_file_path) 44*d955185bSPavel Labath return inferior 45*d955185bSPavel Labath 46*d955185bSPavel Labath def _attach_packet(self, packet_type): 47*d955185bSPavel Labath return "read packet: ${};{}#00".format(packet_type, 48*d955185bSPavel Labath lldbgdbserverutils.gdbremote_hex_encode_string(self._exe_to_attach)) 49*d955185bSPavel Labath 50*d955185bSPavel Labath 51*d955185bSPavel Labath @skipIfWindows # This test is flaky on Windows 52*d955185bSPavel Labath def test_attach_with_vAttachWait(self): 53*d955185bSPavel Labath self._set_up_inferior() 5482ba3f44SPavel Labath 5582ba3f44SPavel Labath self.set_inferior_startup_attach_manually() 5682ba3f44SPavel Labath server = self.connect_to_debug_monitor() 57*d955185bSPavel Labath self.do_handshake() 5882ba3f44SPavel Labath 5982ba3f44SPavel Labath # Launch the first inferior (we shouldn't attach to this one). 60*d955185bSPavel Labath self._launch_and_wait_for_init() 6182ba3f44SPavel Labath 62*d955185bSPavel Labath self.test_sequence.add_log_lines([self._attach_packet("vAttachWait")], 63*d955185bSPavel Labath True) 6482ba3f44SPavel Labath # Run the stream until attachWait. 6582ba3f44SPavel Labath context = self.expect_gdbremote_sequence() 6682ba3f44SPavel Labath self.assertIsNotNone(context) 6782ba3f44SPavel Labath 6882ba3f44SPavel Labath # Sleep so we're sure that the inferior is launched after we ask for the attach. 6982ba3f44SPavel Labath sleep(1) 7082ba3f44SPavel Labath 7182ba3f44SPavel Labath # Launch the second inferior (we SHOULD attach to this one). 72*d955185bSPavel Labath inferior_to_attach = self._launch_inferior(self._run_args) 7382ba3f44SPavel Labath 7482ba3f44SPavel Labath # Make sure the attach succeeded. 7582ba3f44SPavel Labath self.test_sequence.add_log_lines([ 7682ba3f44SPavel Labath {"direction": "send", 7782ba3f44SPavel Labath "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$", 7882ba3f44SPavel Labath "capture": {1: "stop_signal_hex"}}, 7982ba3f44SPavel Labath ], True) 8082ba3f44SPavel Labath self.add_process_info_collection_packets() 8182ba3f44SPavel Labath 8282ba3f44SPavel Labath 8382ba3f44SPavel Labath # Run the stream sending the response.. 8482ba3f44SPavel Labath context = self.expect_gdbremote_sequence() 8582ba3f44SPavel Labath self.assertIsNotNone(context) 8682ba3f44SPavel Labath 8782ba3f44SPavel Labath # Gather process info response. 8882ba3f44SPavel Labath process_info = self.parse_process_info_response(context) 8982ba3f44SPavel Labath self.assertIsNotNone(process_info) 9082ba3f44SPavel Labath 9182ba3f44SPavel Labath # Ensure the process id matches what we expected. 9282ba3f44SPavel Labath pid_text = process_info.get('pid', None) 9382ba3f44SPavel Labath self.assertIsNotNone(pid_text) 9482ba3f44SPavel Labath reported_pid = int(pid_text, base=16) 9582ba3f44SPavel Labath self.assertEqual(reported_pid, inferior_to_attach.pid) 96*d955185bSPavel Labath 97*d955185bSPavel Labath @skipIfWindows # This test is flaky on Windows 98*d955185bSPavel Labath def test_launch_before_attach_with_vAttachOrWait(self): 99*d955185bSPavel Labath self._set_up_inferior() 100*d955185bSPavel Labath 101*d955185bSPavel Labath self.set_inferior_startup_attach_manually() 102*d955185bSPavel Labath server = self.connect_to_debug_monitor() 103*d955185bSPavel Labath self.do_handshake() 104*d955185bSPavel Labath 105*d955185bSPavel Labath inferior = self._launch_and_wait_for_init() 106*d955185bSPavel Labath 107*d955185bSPavel Labath # Add attach packets. 108*d955185bSPavel Labath self.test_sequence.add_log_lines([ 109*d955185bSPavel Labath # Do the attach. 110*d955185bSPavel Labath self._attach_packet("vAttachOrWait"), 111*d955185bSPavel Labath # Expect a stop notification from the attach. 112*d955185bSPavel Labath {"direction": "send", 113*d955185bSPavel Labath "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$", 114*d955185bSPavel Labath "capture": {1: "stop_signal_hex"}}, 115*d955185bSPavel Labath ], True) 116*d955185bSPavel Labath self.add_process_info_collection_packets() 117*d955185bSPavel Labath 118*d955185bSPavel Labath # Run the stream 119*d955185bSPavel Labath context = self.expect_gdbremote_sequence() 120*d955185bSPavel Labath self.assertIsNotNone(context) 121*d955185bSPavel Labath 122*d955185bSPavel Labath # Gather process info response 123*d955185bSPavel Labath process_info = self.parse_process_info_response(context) 124*d955185bSPavel Labath self.assertIsNotNone(process_info) 125*d955185bSPavel Labath 126*d955185bSPavel Labath # Ensure the process id matches what we expected. 127*d955185bSPavel Labath pid_text = process_info.get('pid', None) 128*d955185bSPavel Labath self.assertIsNotNone(pid_text) 129*d955185bSPavel Labath reported_pid = int(pid_text, base=16) 130*d955185bSPavel Labath self.assertEqual(reported_pid, inferior.pid) 131*d955185bSPavel Labath 132*d955185bSPavel Labath @skipIfWindows # This test is flaky on Windows 133*d955185bSPavel Labath def test_launch_after_attach_with_vAttachOrWait(self): 134*d955185bSPavel Labath self._set_up_inferior() 135*d955185bSPavel Labath 136*d955185bSPavel Labath self.set_inferior_startup_attach_manually() 137*d955185bSPavel Labath server = self.connect_to_debug_monitor() 138*d955185bSPavel Labath self.do_handshake() 139*d955185bSPavel Labath 140*d955185bSPavel Labath self.test_sequence.add_log_lines([self._attach_packet("vAttachOrWait")], 141*d955185bSPavel Labath True) 142*d955185bSPavel Labath # Run the stream until attachWait. 143*d955185bSPavel Labath context = self.expect_gdbremote_sequence() 144*d955185bSPavel Labath self.assertIsNotNone(context) 145*d955185bSPavel Labath 146*d955185bSPavel Labath # Sleep so we're sure that the inferior is launched after we ask for the attach. 147*d955185bSPavel Labath sleep(1) 148*d955185bSPavel Labath 149*d955185bSPavel Labath # Launch the inferior. 150*d955185bSPavel Labath inferior = self._launch_inferior(self._run_args) 151*d955185bSPavel Labath 152*d955185bSPavel Labath # Make sure the attach succeeded. 153*d955185bSPavel Labath self.test_sequence.add_log_lines([ 154*d955185bSPavel Labath {"direction": "send", 155*d955185bSPavel Labath "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$", 156*d955185bSPavel Labath "capture": {1: "stop_signal_hex"}}, 157*d955185bSPavel Labath ], True) 158*d955185bSPavel Labath self.add_process_info_collection_packets() 159*d955185bSPavel Labath 160*d955185bSPavel Labath 161*d955185bSPavel Labath # Run the stream sending the response.. 162*d955185bSPavel Labath context = self.expect_gdbremote_sequence() 163*d955185bSPavel Labath self.assertIsNotNone(context) 164*d955185bSPavel Labath 165*d955185bSPavel Labath # Gather process info response. 166*d955185bSPavel Labath process_info = self.parse_process_info_response(context) 167*d955185bSPavel Labath self.assertIsNotNone(process_info) 168*d955185bSPavel Labath 169*d955185bSPavel Labath # Ensure the process id matches what we expected. 170*d955185bSPavel Labath pid_text = process_info.get('pid', None) 171*d955185bSPavel Labath self.assertIsNotNone(pid_text) 172*d955185bSPavel Labath reported_pid = int(pid_text, base=16) 173*d955185bSPavel Labath self.assertEqual(reported_pid, inferior.pid) 174