llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Sergei Druzhkov (DrSergei) <details> <summary>Changes</summary> We should not delete watchpoints created via LLDB console when processing DAP `setDataBreakpoints` request. --- Full diff: https://github.com/llvm/llvm-project/pull/215228.diff 4 Files Affected: - (modified) lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py (+41) - (modified) lldb/tools/lldb-dap/DAP.h (+1) - (modified) lldb/tools/lldb-dap/Handler/SetDataBreakpointsRequestHandler.cpp (+7-1) - (modified) lldb/tools/lldb-dap/Watchpoint.h (+2) ``````````diff diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py index 225a947674351..bad48b0ffbf0f 100644 --- a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py +++ b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py @@ -182,6 +182,47 @@ def test_functionality(self): stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_cond.id)) self.assertEqual(session.top_frame_from(stop_event).locals["x"].value, "10") + @skipIfWindows + def test_console_watchpoint_preserved(self): + """Test setDataBreakpoints must not delete watchpoints created via the console.""" + source = "main.cpp" + program = self.getBuildArtifact("a.out") + session = self.build_and_create_session() + first_loop_break_line = line_number(source, "// first loop breakpoint") + with session.configure(LaunchArgs(program)) as ctx: + session.resolve_source_breakpoints(source, [first_loop_break_line]) + stop_event = session.verify_stopped_on_breakpoint(after=ctx.process_event) + top_frame = session.top_frame_from(stop_event) + + # Create a watchpoint via the LLDB console. + resp_body = session.evaluate("`watchpoint set variable x", context="repl") + session.verify_evaluate(resp_body, matches=r".*Watchpoint created.*") + resp_body = session.evaluate("`watchpoint list", context="repl") + session.verify_evaluate(resp_body, matches=r".*Watchpoint 1:.*") + + # Set a data breakpoint via DAP. + arr = top_frame.locals["arr"] + arr_var_ref = self.expect_not_none(arr.variablesReference) + response_arr_2 = session.data_breakpoint_info( + "[2]", arr_var_ref, top_frame.frame.id + ) + arr_2_data_id = self.expect_not_none(response_arr_2.body.dataId) + set_response = session.set_data_breakpoints( + [DataBreakpoint(dataId=arr_2_data_id, accessType="write")] + ) + [bp_arr_2] = set_response.body.breakpoints + self.assertTrue(bp_arr_2.verified) + + resp_body = session.evaluate("`watchpoint list", context="repl") + session.verify_evaluate(resp_body, matches=r".*Watchpoint 1:.*") + + session.set_data_breakpoints([]) + resp_body = session.evaluate("`watchpoint list", context="repl") + session.verify_evaluate(resp_body, matches=r".*Watchpoint 1:.*") + + session.evaluate("`watchpoint delete 1", context="repl") + session.continue_to_exit() + @skipIfWindows def test_bytes(self): """Tests setting data breakpoints on memory range.""" diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 3e2b1d4782147..c09b149ae3f53 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -107,6 +107,7 @@ struct DAP final : public DAPTransport::MessageHandler { FunctionBreakpointMap function_breakpoints; InstructionBreakpointMap instruction_breakpoints; std::vector<ExceptionBreakpoint> exception_breakpoints; + std::vector<lldb::watch_id_t> data_breakpoints; /// Map step in target id to list of function targets that user can choose. llvm::DenseMap<lldb::addr_t, std::string> step_in_targets; diff --git a/lldb/tools/lldb-dap/Handler/SetDataBreakpointsRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetDataBreakpointsRequestHandler.cpp index 1caaa23bf06f6..0540dfcd9d255 100644 --- a/lldb/tools/lldb-dap/Handler/SetDataBreakpointsRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/SetDataBreakpointsRequestHandler.cpp @@ -25,7 +25,10 @@ SetDataBreakpointsRequestHandler::Run( const protocol::SetDataBreakpointsArguments &args) const { std::vector<protocol::Breakpoint> response_breakpoints; - dap.target.DeleteAllWatchpoints(); + for (lldb::watch_id_t watch_id : dap.data_breakpoints) + dap.target.DeleteWatchpoint(watch_id); + dap.data_breakpoints.clear(); + std::vector<Watchpoint> watchpoints; for (const auto &bp : args.breakpoints) watchpoints.emplace_back(dap, bp); @@ -38,6 +41,9 @@ SetDataBreakpointsRequestHandler::Run( if (addresses.count(iter->GetAddress()) == 0) { iter->SetWatchpoint(); addresses.insert(iter->GetAddress()); + if (lldb::watch_id_t watch_id = iter->GetID(); + watch_id != LLDB_INVALID_WATCH_ID) + dap.data_breakpoints.push_back(watch_id); } } for (auto wp : watchpoints) diff --git a/lldb/tools/lldb-dap/Watchpoint.h b/lldb/tools/lldb-dap/Watchpoint.h index d943e1218bdcd..f73b89e674329 100644 --- a/lldb/tools/lldb-dap/Watchpoint.h +++ b/lldb/tools/lldb-dap/Watchpoint.h @@ -34,6 +34,8 @@ class Watchpoint : public BreakpointBase { lldb::addr_t GetAddress() const { return m_addr; } + lldb::watch_id_t GetID() { return m_wp.GetID(); } + protected: lldb::addr_t m_addr; size_t m_size; `````````` </details> https://github.com/llvm/llvm-project/pull/215228 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
