jarin created this revision.
jarin added a reviewer: jingham.
jarin added a project: LLDB.
Herald added a subscriber: lldb-commits.

This patch makes the stop reason reset logic similar to MacOS' debugserver, 
where exceptions are reset for all threads when resuming process for stepping 
or continuing (see MachThreadList::ProcessWillResume 
<https://github.com/llvm/llvm-project/blob/96f3ea0d21b48ca088355db10d4d1a2e9bc9f884/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp#L433>
 and MachThread::ThreadWillResume 
<https://github.com/llvm/llvm-project/blob/96f3ea0d21b48ca088355db10d4d1a2e9bc9f884/lldb/tools/debugserver/source/MacOSX/MachThread.cpp#L363>).

Resetting stop reasons on resume fixes problems where LLDB spuriously reports 
SIGTRAP signal stop reason for deleted breakpoints (both internal and public) 
and where  LLDB stops on an internal breakpoint while stepping over while a 
breakpoint is hit in another thread. See PR45642 
<https://bugs.llvm.org/show_bug.cgi?id=45642> for details.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79308

Files:
  lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
  lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
  lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
  lldb/test/API/functionalities/thread/break_step_other/Makefile
  
lldb/test/API/functionalities/thread/break_step_other/TestThreadBreakStepOther.py
  lldb/test/API/functionalities/thread/break_step_other/main.cpp

Index: lldb/test/API/functionalities/thread/break_step_other/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/thread/break_step_other/main.cpp
@@ -0,0 +1,20 @@
+#include <thread>
+
+volatile int g_test = 0;
+
+void thread_func () {
+    g_test = 0;  // break here
+
+    while (true) {
+      g_test++;
+    }
+}
+
+int main () {
+    std::thread thread_1(thread_func);
+    std::thread thread_2(thread_func);
+
+    thread_1.join();
+    thread_2.join();
+    return 0;
+}
Index: lldb/test/API/functionalities/thread/break_step_other/TestThreadBreakStepOther.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/thread/break_step_other/TestThreadBreakStepOther.py
@@ -0,0 +1,68 @@
+"""
+Test stop reasons after hitting and deleting a breakpoint and
+stepping another thread. Scenario:
+  - run two threads
+  - stop one thread at a breakpoint
+  - delete the breakpoint
+  - single step the other thread
+The thread stopped at the deleted breakpoint should have stop reason
+'none'.
+"""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ThreadBreakStepOtherTestCase(TestBase):
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_hit_breakpoint_delete_step_other_thread(self):
+        self.main_source_file = lldb.SBFileSpec("main.cpp")
+        self.build()
+        (target, process, thread, breakpoint) = lldbutil.run_to_source_breakpoint(
+            self, "// break here", self.main_source_file, only_one_thread = False)
+
+        # Make sure both threads reach the breakpoint so that we are
+        # sure both threads started. Also remember the thread that is
+        # stopped at the breakpoint and the other thread.
+        stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
+            process, breakpoint)
+        if len(stopped_threads) == 1:
+            other_thread = stopped_threads[0]
+            process.Continue()
+            stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
+                process, breakpoint)
+            self.assertEquals(
+                1,
+                len(stopped_threads),
+                "only one thread expected stopped at breakpoint")
+            breakpoint_thread = stopped_threads[0]
+        else:
+            self.assertEquals(
+                2,
+                len(stopped_threads),
+                "unexpected number of threads stopped at breakpoint")
+            other_thread = stopped_threads[0]
+            breakpoint_thread = stopped_threads[1]
+
+        target.BreakpointDelete(breakpoint.GetID())
+
+        other_thread.StepInstruction(False)
+
+        reason = other_thread.GetStopReason()
+        self.assertEqual(
+            lldb.eStopReasonPlanComplete,
+            reason,
+            "Expected thread stop reason 'plancomplete', but got '%s'" %
+            lldbutil.stop_reason_to_str(reason))
+
+        reason = breakpoint_thread.GetStopReason()
+        self.assertEqual(
+            lldb.eStopReasonNone,
+            reason,
+            "Expected thread stop reason 'none', but got '%s'" %
+            lldbutil.stop_reason_to_str(reason))
Index: lldb/test/API/functionalities/thread/break_step_other/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/thread/break_step_other/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include Makefile.rules
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -94,6 +94,8 @@
 
   void SetStopped();
 
+  void ResetStopReason();
+
   // Member Variables
   lldb::StateType m_state;
   ThreadStopInfo m_stop_info;
Index: lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -396,7 +396,10 @@
 
 void NativeThreadLinux::SetStoppedWithNoReason() {
   SetStopped();
+  ResetStopReason();
+}
 
+void NativeThreadLinux::ResetStopReason() {
   m_stop_info.reason = StopReason::eStopReasonNone;
   m_stop_info.details.signal.signo = 0;
 }
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1062,6 +1062,8 @@
     if (action == nullptr) {
       LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
                thread->GetID());
+      // Make sure we reset the stop reason for all the threads.
+      static_cast<NativeThreadLinux &>(*thread).ResetStopReason();
       continue;
     }
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to