1 2import os 3from time import sleep 4 5import gdbremote_testcase 6import lldbgdbserverutils 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase): 13 14 @skipIfWindows # This test is flaky on Windows 15 def test_attach_with_vAttachWait(self): 16 exe = '%s_%d' % (self.testMethodName, os.getpid()) 17 exe_to_attach = exe 18 sync_file_path = lldbutil.append_to_process_working_directory(self, "process_ready") 19 args = [sync_file_path] 20 21 def launch_inferior(): 22 inferior = self.launch_process_for_attach( 23 inferior_args=args, 24 exe_path=self.getBuildArtifact(exe)) 25 self.assertIsNotNone(inferior) 26 self.assertTrue(inferior.pid > 0) 27 self.assertTrue( 28 lldbgdbserverutils.process_is_running( 29 inferior.pid, True)) 30 return inferior 31 32 self.build(dictionary={'EXE': exe, 'CXX_SOURCES': 'main.cpp'}) 33 if self.getPlatform() != "windows": 34 # Use a shim to ensure that the process is ready to be attached from 35 # the get-go. 36 args = [self.getBuildArtifact(exe)] + args 37 exe = "shim" 38 self.build(dictionary={'EXE': exe, 'CXX_SOURCES': 'shim.cpp'}) 39 40 self.set_inferior_startup_attach_manually() 41 42 server = self.connect_to_debug_monitor() 43 self.assertIsNotNone(server) 44 45 # Launch the first inferior (we shouldn't attach to this one). 46 launch_inferior() 47 48 lldbutil.wait_for_file_on_target(self, sync_file_path) 49 50 self.do_handshake() 51 self.test_sequence.add_log_lines([ 52 # Do the attach. 53 "read packet: $vAttachWait;{}#00".format( 54 lldbgdbserverutils.gdbremote_hex_encode_string(exe_to_attach)), 55 ], True) 56 # Run the stream until attachWait. 57 context = self.expect_gdbremote_sequence() 58 self.assertIsNotNone(context) 59 60 # Sleep so we're sure that the inferior is launched after we ask for the attach. 61 sleep(1) 62 63 # Launch the second inferior (we SHOULD attach to this one). 64 inferior_to_attach = launch_inferior() 65 66 # Make sure the attach succeeded. 67 self.test_sequence.add_log_lines([ 68 {"direction": "send", 69 "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$", 70 "capture": {1: "stop_signal_hex"}}, 71 ], True) 72 self.add_process_info_collection_packets() 73 74 75 # Run the stream sending the response.. 76 context = self.expect_gdbremote_sequence() 77 self.assertIsNotNone(context) 78 79 # Gather process info response. 80 process_info = self.parse_process_info_response(context) 81 self.assertIsNotNone(process_info) 82 83 # Ensure the process id matches what we expected. 84 pid_text = process_info.get('pid', None) 85 self.assertIsNotNone(pid_text) 86 reported_pid = int(pid_text, base=16) 87 self.assertEqual(reported_pid, inferior_to_attach.pid) 88