4 import gdbremote_testcase
5 import lldbgdbserverutils
6 from lldbsuite
.test
.decorators
import *
7 from lldbsuite
.test
.lldbtest
import *
8 from lldbsuite
.test
import lldbutil
11 class TestGdbRemoteAttachWait(gdbremote_testcase
.GdbRemoteTestCaseBase
):
12 def _set_up_inferior(self
):
13 self
._exe
_to
_attach
= "%s_%d" % (self
.testMethodName
, os
.getpid())
14 self
.build(dictionary
={"EXE": self
._exe
_to
_attach
, "CXX_SOURCES": "main.cpp"})
16 if self
.getPlatform() != "windows":
17 # Use a shim to ensure that the process is ready to be attached from
19 self
._exe
_to
_run
= "shim"
20 self
._run
_args
= [self
.getBuildArtifact(self
._exe
_to
_attach
)]
21 self
.build(dictionary
={"EXE": self
._exe
_to
_run
, "CXX_SOURCES": "shim.cpp"})
23 self
._exe
_to
_run
= self
._exe
_to
_attach
26 def _launch_inferior(self
, args
):
27 inferior
= self
.spawnSubprocess(self
.getBuildArtifact(self
._exe
_to
_run
), args
)
28 self
.assertIsNotNone(inferior
)
29 self
.assertTrue(inferior
.pid
> 0)
30 self
.assertTrue(lldbgdbserverutils
.process_is_running(inferior
.pid
, True))
33 def _launch_and_wait_for_init(self
):
34 sync_file_path
= lldbutil
.append_to_process_working_directory(
37 inferior
= self
._launch
_inferior
(self
._run
_args
+ [sync_file_path
])
38 lldbutil
.wait_for_file_on_target(self
, sync_file_path
)
41 def _attach_packet(self
, packet_type
):
42 return "read packet: ${};{}#00".format(
44 lldbgdbserverutils
.gdbremote_hex_encode_string(self
._exe
_to
_attach
),
47 @skipIfWindows # This test is flaky on Windows
48 def test_attach_with_vAttachWait(self
):
49 self
._set
_up
_inferior
()
51 self
.set_inferior_startup_attach_manually()
52 server
= self
.connect_to_debug_monitor()
55 # Launch the first inferior (we shouldn't attach to this one).
56 self
._launch
_and
_wait
_for
_init
()
58 self
.test_sequence
.add_log_lines([self
._attach
_packet
("vAttachWait")], True)
59 # Run the stream until attachWait.
60 context
= self
.expect_gdbremote_sequence()
61 self
.assertIsNotNone(context
)
63 # Sleep so we're sure that the inferior is launched after we ask for the attach.
66 # Launch the second inferior (we SHOULD attach to this one).
67 inferior_to_attach
= self
._launch
_inferior
(self
._run
_args
)
69 # Make sure the attach succeeded.
70 self
.test_sequence
.add_log_lines(
74 "regex": r
"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
75 "capture": {1: "stop_signal_hex"},
80 self
.add_process_info_collection_packets()
82 # Run the stream sending the response..
83 context
= self
.expect_gdbremote_sequence()
84 self
.assertIsNotNone(context
)
86 # Gather process info response.
87 process_info
= self
.parse_process_info_response(context
)
88 self
.assertIsNotNone(process_info
)
90 # Ensure the process id matches what we expected.
91 pid_text
= process_info
.get("pid", None)
92 self
.assertIsNotNone(pid_text
)
93 reported_pid
= int(pid_text
, base
=16)
94 self
.assertEqual(reported_pid
, inferior_to_attach
.pid
)
96 @skipIfWindows # This test is flaky on Windows
97 def test_launch_before_attach_with_vAttachOrWait(self
):
98 self
._set
_up
_inferior
()
100 self
.set_inferior_startup_attach_manually()
101 server
= self
.connect_to_debug_monitor()
104 inferior
= self
._launch
_and
_wait
_for
_init
()
106 # Add attach packets.
107 self
.test_sequence
.add_log_lines(
110 self
._attach
_packet
("vAttachOrWait"),
111 # Expect a stop notification from the attach.
114 "regex": r
"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
115 "capture": {1: "stop_signal_hex"},
120 self
.add_process_info_collection_packets()
123 context
= self
.expect_gdbremote_sequence()
124 self
.assertIsNotNone(context
)
126 # Gather process info response
127 process_info
= self
.parse_process_info_response(context
)
128 self
.assertIsNotNone(process_info
)
130 # Ensure the process id matches what we expected.
131 pid_text
= process_info
.get("pid", None)
132 self
.assertIsNotNone(pid_text
)
133 reported_pid
= int(pid_text
, base
=16)
134 self
.assertEqual(reported_pid
, inferior
.pid
)
136 @skipIfWindows # This test is flaky on Windows
137 def test_launch_after_attach_with_vAttachOrWait(self
):
138 self
._set
_up
_inferior
()
140 self
.set_inferior_startup_attach_manually()
141 server
= self
.connect_to_debug_monitor()
144 self
.test_sequence
.add_log_lines([self
._attach
_packet
("vAttachOrWait")], True)
145 # Run the stream until attachWait.
146 context
= self
.expect_gdbremote_sequence()
147 self
.assertIsNotNone(context
)
149 # Sleep so we're sure that the inferior is launched after we ask for the attach.
152 # Launch the inferior.
153 inferior
= self
._launch
_inferior
(self
._run
_args
)
155 # Make sure the attach succeeded.
156 self
.test_sequence
.add_log_lines(
160 "regex": r
"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
161 "capture": {1: "stop_signal_hex"},
166 self
.add_process_info_collection_packets()
168 # Run the stream sending the response..
169 context
= self
.expect_gdbremote_sequence()
170 self
.assertIsNotNone(context
)
172 # Gather process info response.
173 process_info
= self
.parse_process_info_response(context
)
174 self
.assertIsNotNone(process_info
)
176 # Ensure the process id matches what we expected.
177 pid_text
= process_info
.get("pid", None)
178 self
.assertIsNotNone(pid_text
)
179 reported_pid
= int(pid_text
, base
=16)
180 self
.assertEqual(reported_pid
, inferior
.pid
)