Skip to content

Commit de94c10

Browse files
committed
The test: test_run_then_attach_wait_interrupt was flakey on Linux & Windows.
I changed the test so I could tell whether the problem was sometimes the interrupt was failing, or maybe the was just racy. It failed again, but in the new failures we waited 20 seconds for the attach-wait to get interrupted and that never happened. So there seems to be some real raciness in the feature of interrupting an attach-wait, but only on Linux & Windows. The bug fix that this test was testing was for a bug that would cause us to never try to interrupt in this case. So it looks like this test is uncovering some flakiness in the underlying interrupt support when in this state. That's a separate bug that needs fixing. For now, I disabled the test except on macOS where it seems to run reliably.
1 parent 61c5ad8 commit de94c10

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

lldb/test/API/commands/process/attach/TestProcessAttach.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,88 @@ def tearDown(self):
128128

129129
# Call super's tearDown().
130130
TestBase.tearDown(self)
131+
132+
# This test is flakey on Linux & Windows. The failure mode is
133+
# that sometimes we miss the interrupt and never succeed in
134+
# getting out of the attach wait.
135+
@skipUnlessDarwin
136+
def test_run_then_attach_wait_interrupt(self):
137+
# Test that having run one process doesn't cause us to be unable
138+
# to interrupt a subsequent attach attempt.
139+
self.build()
140+
exe = self.getBuildArtifact(exe_name)
141+
142+
target = lldbutil.run_to_breakpoint_make_target(self, exe_name, True)
143+
launch_info = target.GetLaunchInfo()
144+
launch_info.SetArguments(["q"], True)
145+
error = lldb.SBError()
146+
target.Launch(launch_info, error)
147+
self.assertSuccess(error, "Launched a process")
148+
self.assertState(target.process.state, lldb.eStateExited, "and it exited.")
149+
150+
# Okay now we've run a process, try to attach/wait to something
151+
# and make sure that we can interrupt that.
152+
153+
options = lldb.SBCommandInterpreterRunOptions()
154+
options.SetPrintResults(True)
155+
options.SetEchoCommands(False)
156+
157+
self.stdin_path = self.getBuildArtifact("stdin.txt")
158+
159+
with open(self.stdin_path, "w") as input_handle:
160+
input_handle.write("process attach -w -n noone_would_use_this_name\nquit")
161+
162+
# Python will close the file descriptor if all references
163+
# to the filehandle object lapse, so we need to keep one
164+
# around.
165+
self.filehandle = open(self.stdin_path, "r")
166+
self.dbg.SetInputFileHandle(self.filehandle, False)
167+
168+
# No need to track the output
169+
self.stdout_path = self.getBuildArtifact("stdout.txt")
170+
self.out_filehandle = open(self.stdout_path, "w")
171+
self.dbg.SetOutputFileHandle(self.out_filehandle, False)
172+
self.dbg.SetErrorFileHandle(self.out_filehandle, False)
173+
174+
n_errors, quit_req, crashed = self.dbg.RunCommandInterpreter(
175+
True, True, options, 0, False, False)
176+
177+
while 1:
178+
time.sleep(1)
179+
if target.process.state == lldb.eStateAttaching:
180+
break
181+
182+
self.dbg.DispatchInputInterrupt()
183+
self.dbg.DispatchInputInterrupt()
184+
185+
# cycle waiting for the process state to change before trying
186+
# to read the command output. I don't want to spin forever.
187+
counter = 0
188+
got_exit = False
189+
while counter < 20:
190+
if target.process.state == lldb.eStateExited:
191+
got_exit = True
192+
break
193+
counter += 1
194+
time.sleep(1)
195+
196+
self.assertTrue(got_exit, "The process never switched to eStateExited")
197+
# Even if the state has flipped, we still need to wait for the
198+
# command to complete to see the result. We don't have a way to
199+
# synchronize on "command completed" right now, but sleeping just
200+
# a bit should be enough, all that's left is passing this error
201+
# result to the command, and printing it to the debugger output.
202+
time.sleep(1)
203+
204+
self.out_filehandle.flush()
205+
reader = open(self.stdout_path, "r")
206+
results = reader.readlines()
207+
found_result = False
208+
for line in results:
209+
if "Cancelled async attach" in line:
210+
found_result = True
211+
break
212+
if not found_result:
213+
print(f"Results: {results}")
214+
215+
self.assertTrue(found_result, "Found async error in results")

0 commit comments

Comments
 (0)