[Lldb-commits] [lldb] de94c10 - The test: test_run_then_attach_wait_interrupt was flakey on Linux & Windows.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 20 17:40:52 PDT 2023


Author: Jim Ingham
Date: 2023-09-20T17:38:27-07:00
New Revision: de94c109b64d098c52ffc6f60daadb3eaa8fb944

URL: https://github.com/llvm/llvm-project/commit/de94c109b64d098c52ffc6f60daadb3eaa8fb944
DIFF: https://github.com/llvm/llvm-project/commit/de94c109b64d098c52ffc6f60daadb3eaa8fb944.diff

LOG: 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.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/test/API/commands/process/attach/TestProcessAttach.py b/lldb/test/API/commands/process/attach/TestProcessAttach.py
index 0e916d2e8e4cbe1..d821b4128cde019 100644
--- a/lldb/test/API/commands/process/attach/TestProcessAttach.py
+++ b/lldb/test/API/commands/process/attach/TestProcessAttach.py
@@ -128,3 +128,88 @@ def tearDown(self):
 
         # Call super's tearDown().
         TestBase.tearDown(self)
+
+    # This test is flakey on Linux & Windows.  The failure mode is
+    # that sometimes we miss the interrupt and never succeed in
+    # getting out of the attach wait.
+    @skipUnlessDarwin
+    def test_run_then_attach_wait_interrupt(self):
+        # Test that having run one process doesn't cause us to be unable
+        # to interrupt a subsequent attach attempt.
+        self.build()
+        exe = self.getBuildArtifact(exe_name)
+
+        target = lldbutil.run_to_breakpoint_make_target(self, exe_name, True)
+        launch_info = target.GetLaunchInfo()
+        launch_info.SetArguments(["q"], True)
+        error = lldb.SBError()
+        target.Launch(launch_info, error)
+        self.assertSuccess(error, "Launched a process")
+        self.assertState(target.process.state, lldb.eStateExited, "and it exited.") 
+        
+        # Okay now we've run a process, try to attach/wait to something
+        # and make sure that we can interrupt that.
+        
+        options = lldb.SBCommandInterpreterRunOptions()
+        options.SetPrintResults(True)
+        options.SetEchoCommands(False)
+
+        self.stdin_path = self.getBuildArtifact("stdin.txt")
+
+        with open(self.stdin_path, "w") as input_handle:
+            input_handle.write("process attach -w -n noone_would_use_this_name\nquit")
+
+        # Python will close the file descriptor if all references
+        # to the filehandle object lapse, so we need to keep one
+        # around.
+        self.filehandle = open(self.stdin_path, "r")
+        self.dbg.SetInputFileHandle(self.filehandle, False)
+
+        # No need to track the output
+        self.stdout_path = self.getBuildArtifact("stdout.txt")
+        self.out_filehandle = open(self.stdout_path, "w")
+        self.dbg.SetOutputFileHandle(self.out_filehandle, False)
+        self.dbg.SetErrorFileHandle(self.out_filehandle, False)
+
+        n_errors, quit_req, crashed = self.dbg.RunCommandInterpreter(
+            True, True, options, 0, False, False)
+        
+        while 1:
+            time.sleep(1)
+            if target.process.state == lldb.eStateAttaching:
+                break
+
+        self.dbg.DispatchInputInterrupt()
+        self.dbg.DispatchInputInterrupt()
+
+        # cycle waiting for the process state to change before trying
+        # to read the command output.  I don't want to spin forever.
+        counter = 0
+        got_exit = False
+        while counter < 20:
+            if target.process.state == lldb.eStateExited:
+                got_exit = True
+                break
+            counter += 1
+            time.sleep(1)
+
+        self.assertTrue(got_exit, "The process never switched to eStateExited")
+        # Even if the state has flipped, we still need to wait for the
+        # command to complete to see the result.  We don't have a way to
+        # synchronize on "command completed" right now, but sleeping just
+        # a bit should be enough, all that's left is passing this error
+        # result to the command, and printing it to the debugger output.
+        time.sleep(1)
+
+        self.out_filehandle.flush()
+        reader = open(self.stdout_path, "r")
+        results = reader.readlines()
+        found_result = False
+        for line in results:
+            if "Cancelled async attach" in line:
+                found_result = True
+                break
+        if not found_result:
+            print(f"Results: {results}")
+
+        self.assertTrue(found_result, "Found async error in results")


        


More information about the lldb-commits mailing list