[Lldb-commits] [lldb] lldb: Try to fix flaky tests (PR #231306)

Matt Arsenault via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 12 14:47:05 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/231306

The lldb api test are extremely flaky and have been pissing me off for
a long time. These constantly block my automerges, usually at least
once per day. This was exceptionally painful during the recent github
breakage where automerge was the only way to submit anything. This is
a pure slop fix.

Wait for the private state thread before destroying a process

StopForDestroyOrDetach only halted the process if the public or private
state was running. After an SBProcess::Continue from another thread, both
can say stopped while the private state thread is still handling the next
stop. DestroyImpl then discarded thread plans concurrently with it, which
hit the "Can't pop the base thread plan" assert.

Let the private state thread finish its pending events first, and also
halt if the last broadcast state was running.

This fixes the flaky test_sb_api_listener_resume, so re-enable it on
Linux. Under heavy load it failed 8 of 1536 runs before and 0 of 4608
after. Keep it disabled on Windows until verified there (#231113).

Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>


>From 76e95e58116fd74b3db46bb86e8931db96bd8d45 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 12 Oct 2026 12:40:36 -0700
Subject: [PATCH] lldb: Try to fix flaky tests

The lldb api test are extremely flaky and have been pissing me off for
a long time. These constantly block my automerges, usually at least
once per day. This was exceptionally painful during the recent github
breakage where automerge was the only way to submit anything. This is
a pure slop fix.

Wait for the private state thread before destroying a process

StopForDestroyOrDetach only halted the process if the public or private
state was running. After an SBProcess::Continue from another thread, both
can say stopped while the private state thread is still handling the next
stop. DestroyImpl then discarded thread plans concurrently with it, which
hit the "Can't pop the base thread plan" assert.

Let the private state thread finish its pending events first, and also
halt if the last broadcast state was running.

This fixes the flaky test_sb_api_listener_resume, so re-enable it on
Linux. Under heavy load it failed 8 of 1536 runs before and 0 of 4608
after. Keep it disabled on Windows until verified there (#231113).

Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
 lldb/include/lldb/Target/Process.h                |  5 ++---
 lldb/source/Target/Process.cpp                    | 15 +++++++++++++--
 .../API/api/multithreaded/TestMultithreaded.py    |  1 -
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 226c58034dd65..a09998a5ac7c3 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -3602,9 +3602,8 @@ void PruneThreadPlans();
 
   bool m_clear_thread_plans_on_stop;
   bool m_force_next_event_delivery;
-  lldb::StateType m_last_broadcast_state; /// This helps with the Public event
-                                          /// coalescing in
-                                          /// ShouldBroadcastEvent.
+  /// This helps with the Public event coalescing in ShouldBroadcastEvent.
+  std::atomic<lldb::StateType> m_last_broadcast_state;
   std::map<lldb::addr_t, lldb::addr_t> m_resolved_indirect_addresses;
   bool m_destroy_in_process;
   bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel,
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index c1343fa196f6e..8760f7c14b1ae 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -3736,10 +3736,21 @@ lldb::addr_t Process::FindInMemory(lldb::addr_t low, lldb::addr_t high,
 Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
   Status error;
 
+  // Let the private state thread finish handling pending events first, since
+  // it may resume the process.
+  if (PrivateStateThreadIsRunning() &&
+      !m_current_private_state_thread_sp->IsOnThread(
+          Host::GetCurrentThread())) {
+    PausePrivateStateThread();
+    ResumePrivateStateThread();
+  }
+
   // Check both the public & private states here.  If we're hung evaluating an
   // expression, for instance, then the public state will be stopped, but we
-  // still need to interrupt.
-  if (GetPublicState() == eStateRunning || GetPrivateState() == eStateRunning) {
+  // still need to interrupt. The public state can also be stale, so check the
+  // last broadcast state too.
+  if (GetPublicState() == eStateRunning || GetPrivateState() == eStateRunning ||
+      StateIsRunningState(m_last_broadcast_state)) {
     Log *log = GetLog(LLDBLog::Process);
     LLDB_LOGF(log, "Process::%s() About to stop.", __FUNCTION__);
 
diff --git a/lldb/test/API/api/multithreaded/TestMultithreaded.py b/lldb/test/API/api/multithreaded/TestMultithreaded.py
index 8275626fba20e..7e44332dfc8e5 100644
--- a/lldb/test/API/api/multithreaded/TestMultithreaded.py
+++ b/lldb/test/API/api/multithreaded/TestMultithreaded.py
@@ -69,7 +69,6 @@ def test_sb_api_listener_event_process_state(self):
     @skipIfRemote
     @expectedFlakeyFreeBSD
     @skipIfWindows  # https://github.com/llvm/llvm-project/issues/231113
-    @skipIf(oslist=["linux"])  # flakey
     @skipIfHostIncompatibleWithTarget
     def test_sb_api_listener_resume(self):
         """Test that a process can be resumed from a non-main thread."""



More information about the lldb-commits mailing list