https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/203429
>From 2de45d30df5267d3e3f7b162aefc73968b265f24 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Thu, 11 Jun 2026 16:45:42 -0700 Subject: [PATCH] [lldb][API test] TestRunLocker is flakey, fix TestRunLocker is intended to confirm that certain SB API commands behave correctly while the inferior process is running. It has two modes - one where it launches the process stopped, and then resumes it, and another where it simply launches it. Both are intended to wait until the process is eStateRunning, and then do the test commands including a HandleCommand that refers to `lldb.target`. This test is flakey on Linux and macOS because `lldb.target` comes back as a None type very early in process setup. We weren't actually running the "launch to the first instruction, then resume the process" codepath that this test was written to have - I fixed that last week. But we still see flakey behavior. I thought the flakiness might be the private stops we are doing as we're notified about binaries being loaded in the process, stepping past the breakpoint in the dynamic loader, and then resume. I tested this theory by changing the inferior program to be a tight infinite loop, then putting a breakpoint with a very high skip count, so lldb was forced to do many private stop/resumes. I changed the test case to launch to main(), then start hitting these infinite private stop/resumes and doing the test commands. The test commands work fine in this case. It's something unique about the early process startup that is triggering the flakey failures. On the one hand, there is something wrong here, where `lldb.target` will return None when we are doing commands while executing very early in startup. But that wasn't what this test was intended to exercise, and most importantly, it doesn't work consistently so hammering on this in a test case is just making our CI less reliable. I removed the "launch to first instruction, then resume" codepath and have TestRunLocker run to a breakpoint on main() - where we've done all our process setup and binary loading - then resume the process and test our commands while the inferior is in eStateRunning. It doens't fail any more on my macOS desktop. I also removed a Skip for aarch64 linux which said it was flakey. I expect that's the same flakiness that's hitting all the other CI too. --- .../python_api/run_locker/TestRunLocker.py | 65 ++++++------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index 817530c77a429..595dc8f808763 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -14,43 +14,25 @@ class TestRunLocker(TestBase): NO_DEBUG_INFO_TESTCASE = True - @expectedFailureAll(oslist=["windows"]) - # Is flaky on Linux AArch64 buildbot. - @skipIf(oslist=["linux"], archs=["aarch64"]) - def test_run_locker(self): - """Test that the run locker is set correctly when we launch""" - self.build() - self.runlocker_test(False) - - @expectedFailureAll(oslist=["windows"]) - # Is flaky on Linux AArch64 buildbot. - @skipIf(oslist=["linux"], archs=["aarch64"]) - def test_run_locker_stop_at_entry(self): - """Test that the run locker is set correctly when we launch""" - self.build() - self.runlocker_test(True) - def setUp(self): # Call super's setUp(). TestBase.setUp(self) self.main_source_file = lldb.SBFileSpec("main.c") - def runlocker_test(self, stop_at_entry): - """The code to stop at entry handles events slightly differently, so - we test both versions of process launch.""" - + @expectedFailureAll(oslist=["windows"]) + def test_run_locker(self): + """Test that the run locker is set correctly as we're running""" + self.build() target = lldbutil.run_to_breakpoint_make_target(self) - launch_info = target.GetLaunchInfo() - if stop_at_entry: - flags = launch_info.GetLaunchFlags() - launch_info.SetLaunchFlags(flags | lldb.eLaunchFlagStopAtEntry) error = lldb.SBError() # We are trying to do things when the process is running, so # we have to run the debugger asynchronously. self.dbg.SetAsync(True) + main_bp = target.BreakpointCreateByName("main") + listener = lldb.SBListener("test-run-lock-listener") launch_info.SetListener(listener) process = target.Launch(launch_info, error) @@ -69,33 +51,24 @@ def runlocker_test(self, stop_at_entry): ) state_type = lldb.SBProcess.GetStateFromEvent(event) - # A stop_at_entry launch may have already stopped, it may - # not be eStateRunning. - if not stop_at_entry or state_type != lldb.eStateStopped: + # We may be in eStateStopped if we hit the breakpoint already. + if state_type != lldb.eStateStopped: self.assertState( state_type, lldb.eStateRunning, "Didn't get a running event" ) - - # We aren't checking the entry state, but just making sure - # the running state is set properly if we continue in this state. - - if stop_at_entry: - if state_type != lldb.eStateStopped: - event_result = listener.WaitForEvent(10, event) - self.assertTrue( - event_result, "Timed out waiting for stop at entry stop" - ) - state_type = lldb.SBProcess.GetStateFromEvent(event) - self.assertState(state_type, eStateStopped, "Stop at entry stopped") - process.Continue() event_result = listener.WaitForEvent(10, event) - self.assertTrue(event_result, "timed out waiting for Continue") + self.assertTrue(event_result, "timed out waiting for breakpoint stop") state_type = lldb.SBProcess.GetStateFromEvent(event) - self.assertState( - state_type, - lldb.eStateRunning, - "Didn't get a running event after Continue", - ) + + self.assertState(state_type, lldb.eStateStopped, "Stop at main stopped") + main_bp.SetEnabled(False) + process.Continue() + + event_result = listener.WaitForEvent(10, event) + self.assertTrue(event_result, "timed out waiting for process resume") + state_type = lldb.SBProcess.GetStateFromEvent(event) + + self.assertState(state_type, lldb.eStateRunning, "Continue after main() bp") # Okay, now the process is running, make sure we can't do things # you aren't supposed to do while running, and that we get some _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
