https://github.com/jimingham updated 
https://github.com/llvm/llvm-project/pull/184272

>From 92d85a0253ba4f5623d3d2cc30bfef2cc3d86885 Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Mon, 9 Feb 2026 14:15:24 -0800
Subject: [PATCH 1/6] Add the ability to "allow another thread to see the
 private state" mode.

When lldb stops to run a breakpoint condition or other callback that has to
happen between the private stop and returning control to the user, it will
run in the state where the public state is still "running".  But if the
callback needs to run lldb commands or python code, it needs to see the
correct "stop" state.

We used to handle that by switching the public state to stopped before running
the callbacks.  However, that opened a window where we are still handling the 
stop
event and another thread would be allowed to continue the target or do other
actions that can interfere with that orderly process.

This patch adds the ability to designate a particular thread as "seeing the
private state" while all other threads see the "public state".  Then when
we run a breakpoint callback, no threads but the one that is actually running
the callback will see the state change until the event has been delivered to the
primary state listener.

It also adds a test that while a long-running breakpoint callback runs, another
thread continues to see the state as running.
---
 lldb/include/lldb/Host/ProcessRunLock.h       |   2 +
 lldb/include/lldb/Target/Process.h            |  37 +++++-
 lldb/source/Target/Process.cpp                |  31 +++--
 lldb/source/Target/StopInfo.cpp               |   5 +-
 .../python_api/run_locker/TestRunLocker.py    | 116 +++++++++++++-----
 5 files changed, 146 insertions(+), 45 deletions(-)

diff --git a/lldb/include/lldb/Host/ProcessRunLock.h 
b/lldb/include/lldb/Host/ProcessRunLock.h
index 27d10942ddb4c..f68d42f74b919 100644
--- a/lldb/include/lldb/Host/ProcessRunLock.h
+++ b/lldb/include/lldb/Host/ProcessRunLock.h
@@ -33,6 +33,8 @@ class ProcessRunLock {
   /// Set the process to running. Returns true if the process was stopped.
   /// Return false if the process was running.
   bool SetRunning();
+  
+  bool IsRunning() { return m_running; }
 
   /// Set the process to stopped. Returns true if the process was running.
   /// Returns false if the process was stopped.
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index c4eb8cf3694b1..24474e721e398 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -14,6 +14,7 @@
 #include <climits>
 
 #include <chrono>
+#include <deque>
 #include <list>
 #include <memory>
 #include <mutex>
@@ -3215,7 +3216,7 @@ void PruneThreadPlans();
     // you won't be doing any debugging today.
     bool StartupThread();
 
-    bool IsOnThread(const HostThread &thread) const;
+    bool IsOnThread(lldb::thread_t thread) const;
 
     bool IsJoinable() { return m_private_state_thread.IsJoinable(); }
 
@@ -3234,7 +3235,12 @@ void PruneThreadPlans();
       return m_private_state.GetValue();
     }
 
-    lldb::StateType GetPublicState() const { return m_public_state.GetValue(); 
}
+    lldb::StateType GetPublicState() const {
+      if (UsesPrivateState())
+        return m_private_state.GetValue();
+      else
+        return m_public_state.GetValue(); 
+    }
 
     void SetPublicState(lldb::StateType new_value) {
       m_public_state.SetValue(new_value);
@@ -3273,12 +3279,33 @@ void PruneThreadPlans();
     }
 
     ProcessRunLock &GetRunLock() {
-      if (IsOnThread(Host::GetCurrentThread()))
+      lldb::thread_t curr_thread = Host::GetCurrentThread();
+      if (IsOnThread(curr_thread) || UsesPrivateState(curr_thread))
         return m_private_run_lock;
       else
         return m_public_run_lock;
     }
-
+    
+    void PushUsePrivateState(lldb::thread_t new_thread) {
+      m_use_private_state_stack.push_back(new_thread);
+    }
+    
+    void PopUsePrivateState() {
+      // Should we be permissive here?
+      if (!m_use_private_state_stack.empty())
+        m_use_private_state_stack.pop_back();
+    }
+    
+    bool UsesPrivateState() const {
+      return UsesPrivateState(Host::GetCurrentThread());
+    }
+    
+    bool UsesPrivateState(lldb::thread_t thread) const {
+      if (m_use_private_state_stack.empty())
+        return false;
+      return m_use_private_state_stack.back() == thread;
+    }
+    
     Process &m_process;
     ///< The process state that we show to client code.  This will often differ
     ///< from the actual process state, for instance when we've stopped in the
@@ -3305,6 +3332,8 @@ void PruneThreadPlans();
     ///< This will be the thread name given to the Private State HostThread 
when
     ///< it gets spun up.
     std::string m_thread_name;
+    
+    std::deque<lldb::thread_t> m_use_private_state_stack;
   };
 
   bool SetPrivateRunLockToStopped() {
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index b1a9a25171931..bff406ea28e5b 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1312,7 +1312,9 @@ void Process::SetPublicState(StateType new_state, bool 
restarted) {
   Log *log(GetLog(LLDBLog::State | LLDBLog::Process));
   LLDB_LOGF(log, "(plugin = %s, state = %s, restarted = %i)",
            GetPluginName().data(), StateAsCString(new_state), restarted);
-  const StateType old_state = GetPublicState();
+  // This is one instance where we don't want to obey the "who sees what state"
+  // decisions, we just want to see what's in the public state field.
+  const StateType old_state = 
m_current_private_state_thread->m_public_state.GetValue();
   m_current_private_state_thread->SetPublicState(new_state);
 
   // On the transition from Run to Stopped, we unlock the writer end of the run
@@ -1326,7 +1328,7 @@ void Process::SetPublicState(StateType new_state, bool 
restarted) {
       SetPublicRunLockToStopped();
     } else {
       const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
-      if ((old_state_is_stopped != new_state_is_stopped)) {
+      if ((old_state_is_stopped != new_state_is_stopped) || 
new_state_is_stopped && GetRunLock().IsRunning()) {
         if (new_state_is_stopped && !restarted) {
           LLDB_LOGF(log, "(plugin = %s, state = %s) -- unlocking run lock",
                    GetPluginName().data(), StateAsCString(new_state));
@@ -3931,7 +3933,7 @@ bool Process::PrivateStateThread::StartupThread() {
   return true;
 }
 
-bool Process::PrivateStateThread::IsOnThread(const HostThread &thread) const {
+bool Process::PrivateStateThread::IsOnThread(lldb::thread_t thread) const {
   return m_private_state_thread.EqualsThread(thread);
 }
 
@@ -4421,7 +4423,13 @@ bool Process::ProcessEventData::ShouldStop(Event 
*event_ptr,
         this_thread_wants_to_stop =
             stop_info_sp->GetOverriddenShouldStopValue();
       } else {
+        // PerformAction can call arbitrary Python code but we're still in
+        // ShouldStop so we haven't switched the public state yet.  So we need
+        // to let this thread see the private state:
+        
process_sp->m_current_private_state_thread->PushUsePrivateState(Host::GetCurrentThread());
         stop_info_sp->PerformAction(event_ptr);
+        process_sp->m_current_private_state_thread->PopUsePrivateState();
+
         // The stop action might restart the target.  If it does, then we
         // want to mark that in the event so that whoever is receiving it
         // will know to wait for the running event and reflect that state
@@ -4485,9 +4493,8 @@ void Process::ProcessEventData::DoOnRemoval(Event 
*event_ptr) {
   if (m_update_state != 1)
     return;
 
-  process_sp->SetPublicState(
-      m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
-
+  bool restarted = Process::ProcessEventData::GetRestartedFromEvent(event_ptr);
+  
   if (m_state == eStateStopped && !m_restarted) {
     // Let process subclasses know we are about to do a public stop and do
     // anything they might need to in order to speed up register and memory
@@ -4499,16 +4506,18 @@ void Process::ProcessEventData::DoOnRemoval(Event 
*event_ptr) {
   // than a plain interrupt (e.g. we had already stopped for a breakpoint when
   // the halt request came through) don't do the StopInfo actions, as they may
   // end up restarting the process.
-  if (m_interrupted)
-    return;
-
-  // If we're not stopped or have restarted, then skip the StopInfo actions:
-  if (m_state != eStateStopped || m_restarted) {
+  if (m_interrupted || m_state != eStateStopped || m_restarted) {
+    process_sp->SetPublicState(
+        m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
     return;
   }
 
   bool does_anybody_have_an_opinion = false;
   bool still_should_stop = ShouldStop(event_ptr, does_anybody_have_an_opinion);
+  
+  // And now tell the world about the new state:
+  process_sp->SetPublicState(
+      m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
 
   if (GetRestarted()) {
     return;
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index e9e534a57973e..fb0428fde5073 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -600,7 +600,10 @@ class StopInfoBreakpoint : public StopInfo {
               Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
               bool old_async = debugger.GetAsyncExecution();
               debugger.SetAsyncExecution(true);
-
+              ProcessSP process_sp = thread_sp->GetProcess();
+              // The callback will run commands or SB API calls, which need to
+              // see the public state as stopped, but we haven't set the public
+              // state yet.
               callback_says_stop = bp_loc_sp->InvokeCallback(&context);
 
               debugger.SetAsyncExecution(old_async);
diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py 
b/lldb/test/API/python_api/run_locker/TestRunLocker.py
index d525bbf6b406f..f763147dd7ed3 100644
--- a/lldb/test/API/python_api/run_locker/TestRunLocker.py
+++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py
@@ -1,8 +1,7 @@
 """
 Test that the run locker really does work to keep
 us from running SB API that should only be run
-while stopped.  This test is mostly concerned with
-what happens between launch and first stop.
+while stopped.
 """
 
 import lldb
@@ -13,7 +12,7 @@
 
 class TestRunLocker(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
-
+    
     @expectedFailureAll(oslist=["windows"])
     # Is flaky on Linux AArch64 buildbot.
     @skipIf(oslist=["linux"], archs=["aarch64"])
@@ -21,7 +20,7 @@ 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"])
@@ -30,34 +29,46 @@ def test_run_locker_stop_at_entry(self):
         self.build()
         self.runlocker_test(False)
 
+    def test_during_breakpoint_command(self):
+        """Test that other threads don't see the process as stopped
+        until we actually finish running the breakpoint callback. """
+        self.build()
+        self.during_breakpoint_command()
+
     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."""
+    def start_process(self, flags, bkpt_text):
+        """ Start up an async process, using flags for the launch flags
+        if it is not None.  Also, set a breakpoint before running using
+        bkpt_text as the source regex.  Returns the target, process, listener
+        and breakpoint. """
 
         target = lldbutil.run_to_breakpoint_make_target(self)
-
+        
+        bkpt = None
+        if bkpt_text:
+            bkpt = target.BreakpointCreateBySourceRegex(bkpt_text, 
self.main_source_file)
+        
         launch_info = target.GetLaunchInfo()
-        if stop_at_entry:
+        if flags:
             flags = launch_info.GetFlags()
-            launch_info.SetFlags(flags | lldb.eLaunchFlagStopAtEntry)
-
+            launch_info.SetFlags(flags | flags)
+        
         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)
-
+        
         listener = lldb.SBListener("test-run-lock-listener")
         launch_info.SetListener(listener)
         process = target.Launch(launch_info, error)
         self.assertSuccess(error, "Launched the process")
-
+        
         event = lldb.SBEvent()
-
+        
         event_result = listener.WaitForEvent(10, event)
         self.assertTrue(event_result, "timed out waiting for launch")
         state_type = lldb.SBProcess.GetStateFromEvent(event)
@@ -68,22 +79,11 @@ def runlocker_test(self, stop_at_entry):
                 event_result, "Timed out waiting for running after launching"
             )
             state_type = lldb.SBProcess.GetStateFromEvent(event)
-
+        
         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:
-            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()
-
-        # 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
-        # actual error:
+        return (target, process, listener, bkpt)
+    
+    def try_expression(self, target):
         val = target.EvaluateExpression("SomethingToCall()")
         # There was a bug [#93313] in the printing that would cause repr to 
crash, so I'm
         # testing that separately.
@@ -110,3 +110,61 @@ def runlocker_test(self, stop_at_entry):
         self.assertIn(
             "can't evaluate expressions when the process is running", 
result.GetOutput()
         )
+
+    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."""
+        flags = None
+        
+        if stop_at_entry:
+            flags = lldb.eLaunchFlagsStopAtEntry
+        
+        target, process, listener, _ = self.start_process(flags, None)
+
+        # 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:
+            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()
+
+        # 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
+        # actual error:
+        self.try_expression(target)
+
+    def during_breakpoint_command(self):
+        target, process, listener, bkpt = self.start_process(None, "sleep.1.")
+        # The process should be stopped at our breakpoint, wait for that.
+        event = lldb.SBEvent()
+        result = listener.WaitForEvent(10, event)
+        self.assertTrue(event.IsValid(), "Didn't time out waiting for 
breakpoint")
+        state_type = lldb.SBProcess.GetStateFromEvent(event)
+        self.assertState(state_type, lldb.eStateStopped, "Didn't get a stopped 
event")
+        
+        # Now add a breakpoint callback that will stall for a while, and we'll 
wait a
+        # much shorter interval and each time we wake up ensure that we still 
see the
+        # process as running, and can't do things we aren't allowed to in that 
state.
+        commands = "import time;print('About to 
sleep');time.sleep(20);print('Done sleeping')"
+
+        bkpt.SetScriptCallbackBody(commands)
+        
+        process.Continue()
+        result = listener.WaitForEvent(10, event)
+        state_type = lldb.SBProcess.GetStateFromEvent(event)
+        self.assertState(state_type, lldb.eStateRunning, "We started running")
+        counter = 0
+        while state_type == lldb.eStateRunning:
+            print("About to wait")
+            result = listener.GetNextEvent(event)
+            counter += 1
+            print(f"Woke up {counter} times")
+            if not result:
+                self.try_expression(target)
+            else:
+                state_type = lldb.SBProcess.GetStateFromEvent(event)
+        
+            
+    

>From 5f495d8fa97ff0815eb7f73847f88f273f37921c Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Mon, 2 Mar 2026 17:01:01 -0800
Subject: [PATCH 2/6] Formatting

---
 lldb/include/lldb/Host/ProcessRunLock.h       |  2 +-
 lldb/include/lldb/Target/Process.h            | 14 +++---
 lldb/source/Target/Process.cpp                | 13 +++---
 .../python_api/run_locker/TestRunLocker.py    | 45 ++++++++++---------
 4 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/lldb/include/lldb/Host/ProcessRunLock.h 
b/lldb/include/lldb/Host/ProcessRunLock.h
index f68d42f74b919..c427023ade33f 100644
--- a/lldb/include/lldb/Host/ProcessRunLock.h
+++ b/lldb/include/lldb/Host/ProcessRunLock.h
@@ -33,7 +33,7 @@ class ProcessRunLock {
   /// Set the process to running. Returns true if the process was stopped.
   /// Return false if the process was running.
   bool SetRunning();
-  
+
   bool IsRunning() { return m_running; }
 
   /// Set the process to stopped. Returns true if the process was running.
diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index 24474e721e398..8e34255cdfaba 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -3239,7 +3239,7 @@ void PruneThreadPlans();
       if (UsesPrivateState())
         return m_private_state.GetValue();
       else
-        return m_public_state.GetValue(); 
+        return m_public_state.GetValue();
     }
 
     void SetPublicState(lldb::StateType new_value) {
@@ -3285,27 +3285,27 @@ void PruneThreadPlans();
       else
         return m_public_run_lock;
     }
-    
+
     void PushUsePrivateState(lldb::thread_t new_thread) {
       m_use_private_state_stack.push_back(new_thread);
     }
-    
+
     void PopUsePrivateState() {
       // Should we be permissive here?
       if (!m_use_private_state_stack.empty())
         m_use_private_state_stack.pop_back();
     }
-    
+
     bool UsesPrivateState() const {
       return UsesPrivateState(Host::GetCurrentThread());
     }
-    
+
     bool UsesPrivateState(lldb::thread_t thread) const {
       if (m_use_private_state_stack.empty())
         return false;
       return m_use_private_state_stack.back() == thread;
     }
-    
+
     Process &m_process;
     ///< The process state that we show to client code.  This will often differ
     ///< from the actual process state, for instance when we've stopped in the
@@ -3332,7 +3332,7 @@ void PruneThreadPlans();
     ///< This will be the thread name given to the Private State HostThread 
when
     ///< it gets spun up.
     std::string m_thread_name;
-    
+
     std::deque<lldb::thread_t> m_use_private_state_stack;
   };
 
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index bff406ea28e5b..846d21c304e5c 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1314,7 +1314,8 @@ void Process::SetPublicState(StateType new_state, bool 
restarted) {
            GetPluginName().data(), StateAsCString(new_state), restarted);
   // This is one instance where we don't want to obey the "who sees what state"
   // decisions, we just want to see what's in the public state field.
-  const StateType old_state = 
m_current_private_state_thread->m_public_state.GetValue();
+  const StateType old_state =
+      m_current_private_state_thread->m_public_state.GetValue();
   m_current_private_state_thread->SetPublicState(new_state);
 
   // On the transition from Run to Stopped, we unlock the writer end of the run
@@ -1328,7 +1329,8 @@ void Process::SetPublicState(StateType new_state, bool 
restarted) {
       SetPublicRunLockToStopped();
     } else {
       const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
-      if ((old_state_is_stopped != new_state_is_stopped) || 
new_state_is_stopped && GetRunLock().IsRunning()) {
+      if ((old_state_is_stopped != new_state_is_stopped) ||
+          new_state_is_stopped && GetRunLock().IsRunning()) {
         if (new_state_is_stopped && !restarted) {
           LLDB_LOGF(log, "(plugin = %s, state = %s) -- unlocking run lock",
                    GetPluginName().data(), StateAsCString(new_state));
@@ -4426,7 +4428,8 @@ bool Process::ProcessEventData::ShouldStop(Event 
*event_ptr,
         // PerformAction can call arbitrary Python code but we're still in
         // ShouldStop so we haven't switched the public state yet.  So we need
         // to let this thread see the private state:
-        
process_sp->m_current_private_state_thread->PushUsePrivateState(Host::GetCurrentThread());
+        process_sp->m_current_private_state_thread->PushUsePrivateState(
+            Host::GetCurrentThread());
         stop_info_sp->PerformAction(event_ptr);
         process_sp->m_current_private_state_thread->PopUsePrivateState();
 
@@ -4494,7 +4497,7 @@ void Process::ProcessEventData::DoOnRemoval(Event 
*event_ptr) {
     return;
 
   bool restarted = Process::ProcessEventData::GetRestartedFromEvent(event_ptr);
-  
+
   if (m_state == eStateStopped && !m_restarted) {
     // Let process subclasses know we are about to do a public stop and do
     // anything they might need to in order to speed up register and memory
@@ -4514,7 +4517,7 @@ void Process::ProcessEventData::DoOnRemoval(Event 
*event_ptr) {
 
   bool does_anybody_have_an_opinion = false;
   bool still_should_stop = ShouldStop(event_ptr, does_anybody_have_an_opinion);
-  
+
   // And now tell the world about the new state:
   process_sp->SetPublicState(
       m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py 
b/lldb/test/API/python_api/run_locker/TestRunLocker.py
index f763147dd7ed3..07347da4da638 100644
--- a/lldb/test/API/python_api/run_locker/TestRunLocker.py
+++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py
@@ -12,7 +12,7 @@
 
 class TestRunLocker(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
-    
+
     @expectedFailureAll(oslist=["windows"])
     # Is flaky on Linux AArch64 buildbot.
     @skipIf(oslist=["linux"], archs=["aarch64"])
@@ -20,7 +20,7 @@ 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"])
@@ -31,7 +31,7 @@ def test_run_locker_stop_at_entry(self):
 
     def test_during_breakpoint_command(self):
         """Test that other threads don't see the process as stopped
-        until we actually finish running the breakpoint callback. """
+        until we actually finish running the breakpoint callback."""
         self.build()
         self.during_breakpoint_command()
 
@@ -41,34 +41,36 @@ def setUp(self):
         self.main_source_file = lldb.SBFileSpec("main.c")
 
     def start_process(self, flags, bkpt_text):
-        """ Start up an async process, using flags for the launch flags
+        """Start up an async process, using flags for the launch flags
         if it is not None.  Also, set a breakpoint before running using
         bkpt_text as the source regex.  Returns the target, process, listener
-        and breakpoint. """
+        and breakpoint."""
 
         target = lldbutil.run_to_breakpoint_make_target(self)
-        
+
         bkpt = None
         if bkpt_text:
-            bkpt = target.BreakpointCreateBySourceRegex(bkpt_text, 
self.main_source_file)
-        
+            bkpt = target.BreakpointCreateBySourceRegex(
+                bkpt_text, self.main_source_file
+            )
+
         launch_info = target.GetLaunchInfo()
         if flags:
             flags = launch_info.GetFlags()
             launch_info.SetFlags(flags | flags)
-        
+
         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)
-        
+
         listener = lldb.SBListener("test-run-lock-listener")
         launch_info.SetListener(listener)
         process = target.Launch(launch_info, error)
         self.assertSuccess(error, "Launched the process")
-        
+
         event = lldb.SBEvent()
-        
+
         event_result = listener.WaitForEvent(10, event)
         self.assertTrue(event_result, "timed out waiting for launch")
         state_type = lldb.SBProcess.GetStateFromEvent(event)
@@ -79,10 +81,10 @@ def start_process(self, flags, bkpt_text):
                 event_result, "Timed out waiting for running after launching"
             )
             state_type = lldb.SBProcess.GetStateFromEvent(event)
-        
+
         self.assertState(state_type, lldb.eStateRunning, "Didn't get a running 
event")
         return (target, process, listener, bkpt)
-    
+
     def try_expression(self, target):
         val = target.EvaluateExpression("SomethingToCall()")
         # There was a bug [#93313] in the printing that would cause repr to 
crash, so I'm
@@ -114,10 +116,10 @@ def try_expression(self, target):
     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."""
         flags = None
-        
+
         if stop_at_entry:
             flags = lldb.eLaunchFlagsStopAtEntry
-        
+
         target, process, listener, _ = self.start_process(flags, None)
 
         # We aren't checking the entry state, but just making sure
@@ -143,14 +145,16 @@ def during_breakpoint_command(self):
         self.assertTrue(event.IsValid(), "Didn't time out waiting for 
breakpoint")
         state_type = lldb.SBProcess.GetStateFromEvent(event)
         self.assertState(state_type, lldb.eStateStopped, "Didn't get a stopped 
event")
-        
+
         # Now add a breakpoint callback that will stall for a while, and we'll 
wait a
         # much shorter interval and each time we wake up ensure that we still 
see the
         # process as running, and can't do things we aren't allowed to in that 
state.
-        commands = "import time;print('About to 
sleep');time.sleep(20);print('Done sleeping')"
+        commands = (
+            "import time;print('About to sleep');time.sleep(20);print('Done 
sleeping')"
+        )
 
         bkpt.SetScriptCallbackBody(commands)
-        
+
         process.Continue()
         result = listener.WaitForEvent(10, event)
         state_type = lldb.SBProcess.GetStateFromEvent(event)
@@ -165,6 +169,3 @@ def during_breakpoint_command(self):
                 self.try_expression(target)
             else:
                 state_type = lldb.SBProcess.GetStateFromEvent(event)
-        
-            
-    

>From 9e2da9b074544f69a693e3f5cafb831f8c9b27df Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Mon, 2 Mar 2026 17:04:15 -0800
Subject: [PATCH 3/6] Silence a picky linux bot.

---
 lldb/source/Target/Process.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 846d21c304e5c..aa1ad797770b9 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1330,7 +1330,7 @@ void Process::SetPublicState(StateType new_state, bool 
restarted) {
     } else {
       const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
       if ((old_state_is_stopped != new_state_is_stopped) ||
-          new_state_is_stopped && GetRunLock().IsRunning()) {
+          (new_state_is_stopped && GetRunLock().IsRunning())) {
         if (new_state_is_stopped && !restarted) {
           LLDB_LOGF(log, "(plugin = %s, state = %s) -- unlocking run lock",
                    GetPluginName().data(), StateAsCString(new_state));

>From 3e05494c394208325aa6cd6549fc4b1fec60f1df Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Tue, 3 Mar 2026 13:16:31 -0800
Subject: [PATCH 4/6] Remove an unused calculation.  The actual usage was moved
 to another place, but the original calculation was not deleted. Fixes a
 -Werror complaint on one of the Linux bots.

---
 lldb/source/Target/Process.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index aa1ad797770b9..608fd2ad66e9d 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -4496,8 +4496,6 @@ void Process::ProcessEventData::DoOnRemoval(Event 
*event_ptr) {
   if (m_update_state != 1)
     return;
 
-  bool restarted = Process::ProcessEventData::GetRestartedFromEvent(event_ptr);
-
   if (m_state == eStateStopped && !m_restarted) {
     // Let process subclasses know we are about to do a public stop and do
     // anything they might need to in order to speed up register and memory

>From 88a9d94cc1ddc54bce534475e276c44fb3b920df Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Tue, 3 Mar 2026 17:19:48 -0800
Subject: [PATCH 5/6] Remove an unused computation of process_sp.

---
 lldb/source/Target/StopInfo.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index fb0428fde5073..3affc30b5c338 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -600,7 +600,6 @@ class StopInfoBreakpoint : public StopInfo {
               Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
               bool old_async = debugger.GetAsyncExecution();
               debugger.SetAsyncExecution(true);
-              ProcessSP process_sp = thread_sp->GetProcess();
               // The callback will run commands or SB API calls, which need to
               // see the public state as stopped, but we haven't set the public
               // state yet.

>From 7078543c07142045479cefa3b14fbae8c7f67b23 Mon Sep 17 00:00:00 2001
From: Jim Ingham <[email protected]>
Date: Wed, 4 Mar 2026 12:48:18 -0800
Subject: [PATCH 6/6] Don't use language constructs to express control flow.

---
 lldb/include/lldb/Target/Process.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/include/lldb/Target/Process.h 
b/lldb/include/lldb/Target/Process.h
index 8e34255cdfaba..90036b7a08c4d 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -3238,8 +3238,7 @@ void PruneThreadPlans();
     lldb::StateType GetPublicState() const {
       if (UsesPrivateState())
         return m_private_state.GetValue();
-      else
-        return m_public_state.GetValue();
+      return m_public_state.GetValue();
     }
 
     void SetPublicState(lldb::StateType new_value) {

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to