[Lldb-commits] [lldb] [lldb][gdb-remote] Mark thread as stopped in RefreshStateAfterStop (PR #201605)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 5 07:27:37 PDT 2026


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/201605

>From 0821514e7df7d045d4861c61242604c45865d077 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 15:33:16 +0100
Subject: [PATCH 1/6] [lldb][gdb-remote] Mark thread as stopped in
 RefreshStateAfterStop

---
 lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index c0171734343a6..86c9843eeedd8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -271,6 +271,9 @@ void ThreadGDBRemote::WillResume(StateType resume_state) {
 }
 
 void ThreadGDBRemote::RefreshStateAfterStop() {
+  // Mark this thread as stopped. ThreadList::DidStop only transitions
+  // threads from a running state to stopped.
+  SetState(eStateStopped);
   // Invalidate all registers in our register context. We don't set "force" to
   // true because the stop reply packet might have had some register values
   // that were expedited and these will already be copied into the register

>From c88bd7f377975063a0a909f8ff212119fea21e27 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 16:09:52 +0100
Subject: [PATCH 2/6] fixup! [lldb][gdb-remote] Mark thread as stopped in
 RefreshStateAfterStop

---
 .../thread/break_after_join/TestBreakAfterJoin.py  | 13 -------------
 .../thread/multi_break/TestMultipleBreakpoints.py  | 13 -------------
 .../thread/state/TestThreadStates.py               | 14 --------------
 3 files changed, 40 deletions(-)

diff --git a/lldb/test/API/functionalities/thread/break_after_join/TestBreakAfterJoin.py b/lldb/test/API/functionalities/thread/break_after_join/TestBreakAfterJoin.py
index 0e80d8b7a11fb..c246808f1bb30 100644
--- a/lldb/test/API/functionalities/thread/break_after_join/TestBreakAfterJoin.py
+++ b/lldb/test/API/functionalities/thread/break_after_join/TestBreakAfterJoin.py
@@ -17,19 +17,6 @@ def setUp(self):
         # Find the line number for our breakpoint.
         self.breakpoint = line_number("main.cpp", "// Set breakpoint here")
 
-    @expectedFailureAll(
-        oslist=["linux"],
-        bugnumber="llvm.org/pr15824 thread states not properly maintained",
-    )
-    @expectedFailureAll(
-        oslist=lldbplatformutil.getDarwinOSTriples(),
-        bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>",
-    )
-    @expectedFailureAll(
-        oslist=["freebsd"],
-        bugnumber="llvm.org/pr18190 thread states not properly maintained",
-    )
-    @expectedFailureNetBSD
     def test(self):
         """Test breakpoint handling after a thread join."""
         self.build()
diff --git a/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.py b/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.py
index 9c9f7f7acdb04..fe30138f78157 100644
--- a/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.py
+++ b/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.py
@@ -17,20 +17,7 @@ def setUp(self):
         # Find the line number for our breakpoint.
         self.breakpoint = line_number("main.cpp", "// Set breakpoint here")
 
-    @expectedFailureAll(
-        oslist=["linux"],
-        bugnumber="llvm.org/pr15824 thread states not properly maintained",
-    )
-    @expectedFailureAll(
-        oslist=lldbplatformutil.getDarwinOSTriples(),
-        bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>",
-    )
-    @expectedFailureAll(
-        oslist=["freebsd"],
-        bugnumber="llvm.org/pr18190 thread states not properly maintained",
-    )
     @skipIfWindows  # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373
-    @expectedFailureNetBSD
     def test(self):
         """Test simultaneous breakpoints in multiple threads."""
         self.build()
diff --git a/lldb/test/API/functionalities/thread/state/TestThreadStates.py b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
index 6eeff07955733..f2b19959ea6e4 100644
--- a/lldb/test/API/functionalities/thread/state/TestThreadStates.py
+++ b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
@@ -11,16 +11,6 @@
 
 
 class ThreadStateTestCase(TestBase):
-    @expectedFailureAll(
-        oslist=["linux"],
-        bugnumber="llvm.org/pr15824 thread states not properly maintained",
-    )
-    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
-    @expectedFailureAll(
-        oslist=["freebsd"],
-        bugnumber="llvm.org/pr18190 thread states not properly maintained",
-    )
-    @expectedFailureNetBSD
     def test_state_after_breakpoint(self):
         """Test thread state after breakpoint."""
         self.build()
@@ -48,13 +38,10 @@ def test_state_after_expression(self):
         self.build()
         self.thread_state_after_expression_test()
 
-    # thread states not properly maintained
-    @unittest.expectedFailure  # llvm.org/pr15824 and <rdar://problem/28557237>
     @expectedFailureAll(
         oslist=["windows"],
         bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
     )
-    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
     @expectedFailureNetBSD
     def test_process_state(self):
         """Test thread states (comprehensive)."""
@@ -190,7 +177,6 @@ def thread_state_after_expression_test(self):
         oslist=["windows"],
         bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
     )
-    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
     @no_debug_info_test
     def test_process_interrupt(self):
         """Test process interrupt and continue."""

>From a1498c416dd75dcc02bd486baf7098b42328c537 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 17:00:18 +0100
Subject: [PATCH 3/6] fixup! [lldb][gdb-remote] Mark thread as stopped in
 RefreshStateAfterStop

---
 .../functionalities/thread/state/TestThreadStates.py   | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lldb/test/API/functionalities/thread/state/TestThreadStates.py b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
index f2b19959ea6e4..1de0445668b86 100644
--- a/lldb/test/API/functionalities/thread/state/TestThreadStates.py
+++ b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
@@ -27,17 +27,15 @@ def test_state_after_continue(self):
 
     @skipIfDarwin  # 'llvm.org/pr23669', cause Python crash randomly
     @expectedFailureDarwin("llvm.org/pr23669")
-    @expectedFailureNetBSD
     # This actually passes on Windows on Arm but it's hard to describe that
     # and xfail it everywhere else.
     @skipIfWindows
-    # thread states not properly maintained
-    @unittest.expectedFailure  # llvm.org/pr16712
     def test_state_after_expression(self):
         """Test thread state after expression."""
         self.build()
         self.thread_state_after_expression_test()
 
+    @skipIfDarwin  # rdar://28557237
     @expectedFailureAll(
         oslist=["windows"],
         bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
@@ -274,7 +272,7 @@ def thread_states_test(self):
         # Stop the process
         self.runCmd("process interrupt")
 
-        self.assertStopReason(thread.GetState(), lldb.eStopReasonSignal)
+        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
 
         # Check the thread state
         self.assertTrue(
@@ -297,12 +295,12 @@ def thread_states_test(self):
             "Thread state is 'suspended' after expression evaluation.",
         )
 
-        self.assertStopReason(thread.GetState(), lldb.eStopReasonSignal)
+        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
 
         # Run to breakpoint 2
         self.runCmd("continue")
 
-        self.assertStopReason(thread.GetState(), lldb.eStopReasonBreakpoint)
+        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonBreakpoint)
 
         # Make sure both threads are stopped
         self.assertTrue(

>From 1137fafe19dd8fd22577d1b4840a76769f6f5ccf Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 17:23:00 +0100
Subject: [PATCH 4/6] fixup! [lldb][gdb-remote] Mark thread as stopped in
 RefreshStateAfterStop

---
 .../test/API/functionalities/thread/state/TestThreadStates.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lldb/test/API/functionalities/thread/state/TestThreadStates.py b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
index 1de0445668b86..406f4e17462f3 100644
--- a/lldb/test/API/functionalities/thread/state/TestThreadStates.py
+++ b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
@@ -36,6 +36,10 @@ def test_state_after_expression(self):
         self.thread_state_after_expression_test()
 
     @skipIfDarwin  # rdar://28557237
+    @expectedFailureAll(
+        oslist=["linux"],
+        bugnumber="llvm.org/pr15824 process interrupt stop reason is trace instead of signal",
+    )
     @expectedFailureAll(
         oslist=["windows"],
         bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",

>From 58dedeb6d6acfaf6c26348f34337ac4e473d4531 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 17:36:33 +0100
Subject: [PATCH 5/6] skip test

---
 .../API/functionalities/thread/state/TestThreadStates.py     | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/lldb/test/API/functionalities/thread/state/TestThreadStates.py b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
index 406f4e17462f3..6198e0baf1c29 100644
--- a/lldb/test/API/functionalities/thread/state/TestThreadStates.py
+++ b/lldb/test/API/functionalities/thread/state/TestThreadStates.py
@@ -36,10 +36,7 @@ def test_state_after_expression(self):
         self.thread_state_after_expression_test()
 
     @skipIfDarwin  # rdar://28557237
-    @expectedFailureAll(
-        oslist=["linux"],
-        bugnumber="llvm.org/pr15824 process interrupt stop reason is trace instead of signal",
-    )
+    @skipIfLinux  # llvm.org/pr15824 process interrupt stop reason is trace instead of signal sometimes
     @expectedFailureAll(
         oslist=["windows"],
         bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",

>From 7ceb67e0e58210e87bd7edf74c2e93c34cb6ba0d Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 5 Jun 2026 15:27:13 +0100
Subject: [PATCH 6/6] move logic in RefreshAfterStop

---
 .../Plugins/Process/Windows/Common/TargetThreadWindows.cpp    | 1 -
 lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp    | 3 ---
 lldb/source/Target/ThreadList.cpp                             | 4 +++-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
index b2131a5ee7b13..b65c26cb19709 100644
--- a/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
@@ -39,7 +39,6 @@ TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
 
 void TargetThreadWindows::RefreshStateAfterStop() {
   ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
-  SetState(eStateStopped);
   GetRegisterContext()->InvalidateIfNeeded(false);
 }
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 86c9843eeedd8..c0171734343a6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -271,9 +271,6 @@ void ThreadGDBRemote::WillResume(StateType resume_state) {
 }
 
 void ThreadGDBRemote::RefreshStateAfterStop() {
-  // Mark this thread as stopped. ThreadList::DidStop only transitions
-  // threads from a running state to stopped.
-  SetState(eStateStopped);
   // Invalidate all registers in our register context. We don't set "force" to
   // true because the stop reply packet might have had some register values
   // that were expedited and these will already be copied into the register
diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp
index 6f7c9e2e3bea3..7d2feffeca11d 100644
--- a/lldb/source/Target/ThreadList.cpp
+++ b/lldb/source/Target/ThreadList.cpp
@@ -482,8 +482,10 @@ void ThreadList::RefreshStateAfterStop() {
       "a thread.");
 
   collection::iterator pos, end = m_threads.end();
-  for (pos = m_threads.begin(); pos != end; ++pos)
+  for (pos = m_threads.begin(); pos != end; ++pos) {
+    (*pos)->SetState(eStateStopped);
     (*pos)->RefreshStateAfterStop();
+  }
 }
 
 void ThreadList::DiscardThreadPlans() {



More information about the lldb-commits mailing list