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