https://github.com/hapeeeeee updated https://github.com/llvm/llvm-project/pull/136682
>From 563cbddfe9b7da394c818a03e05924c0f7d39d5f Mon Sep 17 00:00:00 2001 From: hapeeeeee <623151...@qq.com> Date: Tue, 22 Apr 2025 11:34:38 +0800 Subject: [PATCH 1/3] [lldb] Fix crash after second run when set a previous watchpoint. --- lldb/source/Breakpoint/Watchpoint.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp index 2df848aaa0576..0fcc9b90c0ab5 100644 --- a/lldb/source/Breakpoint/Watchpoint.cpp +++ b/lldb/source/Breakpoint/Watchpoint.cpp @@ -409,6 +409,15 @@ bool Watchpoint::IsDisabledDuringEphemeralMode() { } void Watchpoint::SetEnabled(bool enabled, bool notify) { + // Whenever setting the enabled state of a watchpoint, we need to ensure + // that `m_new_value_sp` exists to avoid crash when reading old_data later. + // See https://github.com/llvm/llvm-project/issues/135590. + if (!m_new_value_sp) { + ExecutionContext exe_ctx; + m_target.GetProcessSP()->CalculateExecutionContext(exe_ctx); + CaptureWatchedValue(exe_ctx); + } + if (!enabled) { if (m_is_ephemeral) ++m_disabled_count; >From 980c9bc97011fa4fbce4f67688c3539f3d518a42 Mon Sep 17 00:00:00 2001 From: hapeeeeee <623151...@qq.com> Date: Wed, 23 Apr 2025 21:33:32 +0800 Subject: [PATCH 2/3] add testcase --- .../Makefile | 3 + .../TestReuseWatchpointAfterReExecProcess.py | 71 +++++++++++++++++++ .../main.c | 5 ++ 3 files changed, 79 insertions(+) create mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile create mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py create mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py new file mode 100644 index 0000000000000..d4b4afd538cde --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py @@ -0,0 +1,71 @@ +""" +Set a watchpoint on a variable, then kill the process and restart it with the same watchpoint. +Check whether LLDB crashes due to a dangling pointer. +""" + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestReuseWatchpointAfterReExecProcess(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def continue_and_report_stop_reason(self, process, iter_str): + process.Continue() + self.assertIn( + process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str + ) + thread = process.GetSelectedThread() + return thread.GetStopReason() + + # debugserver only gained the ability to watch larger regions + # with this patch. + def test_reuse_watchpoint_after_re_exec_process(self): + """Test watchpoint that covers a large region of memory.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "break here", self.main_source_file + ) + + frame = thread.GetFrameAtIndex(0) + var_wp = ( + frame.locals["var"][0] + .Watch(True, False, True) + ) + self.assertTrue(var_wp.IsValid()) + + # Kill the process and restart it with the same watchpoint. + process.Kill() + process = target.LaunchSimple(None, None, os.getcwd()) + bkpt = target.BreakpointCreateBySourceRegex( + "break here", self.main_source_file, None + ) + + threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) + thread = threads[0] + frame = thread.GetFrameAtIndex(0) + + var_reused_wp = ( + frame.locals["var"][0] + .Watch(True, False, True) + ) + + self.assertTrue(var_reused_wp.IsValid()) + process.Continue() + reason = self.continue_and_report_stop_reason(process, "continue to reused var wp") + self.assertEqual(reason, lldb.eStopReasonWatchpoint) + + stop_reason_watchpoint_id = ( + process.GetSelectedThread().GetStopReasonDataAtIndex(0) + ) + self.assertEqual(stop_reason_watchpoint_id, var_reused_wp.GetID()) + + # Check that the process exited, instead of crashing + process.Continue() + self.assertState(process.GetState(), lldb.eStateExited) + + \ No newline at end of file diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c new file mode 100644 index 0000000000000..8cf70d8b06d69 --- /dev/null +++ b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c @@ -0,0 +1,5 @@ +int main() { + int var; + var = 2; // break here + return 0; +} \ No newline at end of file >From 06736af2e311c693edad289c3a6f822d2de9d196 Mon Sep 17 00:00:00 2001 From: hapeeeeee <623151...@qq.com> Date: Thu, 24 Apr 2025 22:33:23 +0800 Subject: [PATCH 3/3] Add Shell Test --- .../Makefile | 3 - .../TestReuseWatchpointAfterReExecProcess.py | 71 ------------------- .../main.c | 5 -- .../ReuseWatchpointAfterReExecProcess.test | 21 ++++++ 4 files changed, 21 insertions(+), 79 deletions(-) delete mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile delete mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py delete mode 100644 lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c create mode 100644 lldb/test/Shell/Watchpoint/ReuseWatchpointAfterReExecProcess.test diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile deleted file mode 100644 index 10495940055b6..0000000000000 --- a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -C_SOURCES := main.c - -include Makefile.rules diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py deleted file mode 100644 index d4b4afd538cde..0000000000000 --- a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/TestReuseWatchpointAfterReExecProcess.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -Set a watchpoint on a variable, then kill the process and restart it with the same watchpoint. -Check whether LLDB crashes due to a dangling pointer. -""" - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class TestReuseWatchpointAfterReExecProcess(TestBase): - NO_DEBUG_INFO_TESTCASE = True - - def continue_and_report_stop_reason(self, process, iter_str): - process.Continue() - self.assertIn( - process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str - ) - thread = process.GetSelectedThread() - return thread.GetStopReason() - - # debugserver only gained the ability to watch larger regions - # with this patch. - def test_reuse_watchpoint_after_re_exec_process(self): - """Test watchpoint that covers a large region of memory.""" - self.build() - self.main_source_file = lldb.SBFileSpec("main.c") - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( - self, "break here", self.main_source_file - ) - - frame = thread.GetFrameAtIndex(0) - var_wp = ( - frame.locals["var"][0] - .Watch(True, False, True) - ) - self.assertTrue(var_wp.IsValid()) - - # Kill the process and restart it with the same watchpoint. - process.Kill() - process = target.LaunchSimple(None, None, os.getcwd()) - bkpt = target.BreakpointCreateBySourceRegex( - "break here", self.main_source_file, None - ) - - threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) - thread = threads[0] - frame = thread.GetFrameAtIndex(0) - - var_reused_wp = ( - frame.locals["var"][0] - .Watch(True, False, True) - ) - - self.assertTrue(var_reused_wp.IsValid()) - process.Continue() - reason = self.continue_and_report_stop_reason(process, "continue to reused var wp") - self.assertEqual(reason, lldb.eStopReasonWatchpoint) - - stop_reason_watchpoint_id = ( - process.GetSelectedThread().GetStopReasonDataAtIndex(0) - ) - self.assertEqual(stop_reason_watchpoint_id, var_reused_wp.GetID()) - - # Check that the process exited, instead of crashing - process.Continue() - self.assertState(process.GetState(), lldb.eStateExited) - - \ No newline at end of file diff --git a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c b/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c deleted file mode 100644 index 8cf70d8b06d69..0000000000000 --- a/lldb/test/API/functionalities/watchpoint/reuse-watchpoint-after-re-exec-process/main.c +++ /dev/null @@ -1,5 +0,0 @@ -int main() { - int var; - var = 2; // break here - return 0; -} \ No newline at end of file diff --git a/lldb/test/Shell/Watchpoint/ReuseWatchpointAfterReExecProcess.test b/lldb/test/Shell/Watchpoint/ReuseWatchpointAfterReExecProcess.test new file mode 100644 index 0000000000000..6af27856e6ee6 --- /dev/null +++ b/lldb/test/Shell/Watchpoint/ReuseWatchpointAfterReExecProcess.test @@ -0,0 +1,21 @@ +# RUN: %clangxx_host %p/Inputs/languages.cpp -g -o %t.out +# RUN: %lldb -b -o 'settings set interpreter.stop-command-source-on-error false' -s %s %t.out 2>&1 | FileCheck %s + +b main +run +# CHECK: stopped +# CHECK-NEXT: stop reason = breakpoint + +watchpoint set variable val +# CHECK: Watchpoint created: + +kill +run +# CHECK: stopped +# CHECK-NEXT: stop reason = breakpoint + +watchpoint set variable val +# CHECK: Watchpoint created: + +continue +# CHECK: Watchpoint 1 hit: \ No newline at end of file _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits