[Lldb-commits] [lldb] [lldb-dap] Migrate setDataBreakpoint and Locations test (PR #213269)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 31 06:50:19 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Ebuka Ezike (da-viper)
<details>
<summary>Changes</summary>
Drop the raw line number when matching the expected location.
---
Patch is 30.94 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213269.diff
3 Files Affected:
- (modified) lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py (+195-214)
- (modified) lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py (+53-67)
- (modified) lldb/test/API/tools/lldb-dap/locations/main.cpp (+8-8)
``````````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 b26618df7800c..225a947674351 100644
--- a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
@@ -2,251 +2,232 @@
Test lldb-dap dataBreakpointInfo and setDataBreakpoints requests
"""
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWasm, skipIfWindows
+from lldbsuite.test.lldbtest import line_number
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.types import DataBreakpoint, LaunchArgs
- at skipIfWasm # data breakpoints map to watchpoints
-class TestDAP_setDataBreakpoints(lldbdap_testcase.DAPTestCaseBase):
- def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
- self.accessTypes = ["read", "write", "readWrite"]
+ at skipIfWasm # data breakpoints map to watchpoints.
+class TestDAP_setDataBreakpoints(DAPTestCaseBase):
+ ACCESS_TYPES = ["read", "write", "readWrite"]
@skipIfWindows
def test_duplicate_start_addresses(self):
"""Test setDataBreakpoints with multiple watchpoints starting at the same addresses."""
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ session = self.build_and_create_session()
source = "main.cpp"
first_loop_break_line = line_number(source, "// first loop breakpoint")
- self.set_source_breakpoints(source, [first_loop_break_line])
- self.continue_to_next_stop()
- self.dap_server.get_stackFrame()
- # Test setting write watchpoint using expressions: &x, arr+2
- response_x = self.dap_server.request_dataBreakpointInfo(0, "&x")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(0, "arr+2")
- # Test response from dataBreakpointInfo request.
- self.assertEqual(response_x["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEqual(response_arr_2["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_arr_2["body"]["accessTypes"], self.accessTypes)
- # The first one should be overwritten by the third one as they start at
- # the same address. This is indicated by returning {verified: False} for
- # the first one.
- dataBreakpoints = [
- {"dataId": response_x["body"]["dataId"], "accessType": "read"},
- {"dataId": response_arr_2["body"]["dataId"], "accessType": "write"},
- {"dataId": response_x["body"]["dataId"], "accessType": "write"},
+ 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)
+
+ # Verify write watchpoints on expressions `&x` and `arr+2`.
+ top_frame_id = session.top_frame_from(stop_event).frame.id
+ response_x = session.data_breakpoint_info("&x", 0, top_frame_id)
+ response_arr_2 = session.data_breakpoint_info("arr+2", 0, top_frame_id)
+
+ x_data_id = self.expect_not_none(response_x.body.dataId)
+ arr_2_data_id = self.expect_not_none(response_arr_2.body.dataId)
+ self.assertEqual(x_data_id.split("/")[1], "4")
+ self.assertEqual(response_x.body.accessTypes, self.ACCESS_TYPES)
+ self.assertEqual(arr_2_data_id.split("/")[1], "4")
+ self.assertEqual(response_arr_2.body.accessTypes, self.ACCESS_TYPES)
+
+ # The first breakpoint should be overwritten by the third breakpoint because
+ # they share the same starting address. The debug adapter indicates this by
+ # returning a breakpoint that is not verified for the first breakpoint.
+ data_breakpoints = [
+ DataBreakpoint(dataId=x_data_id, accessType="read"),
+ DataBreakpoint(dataId=arr_2_data_id, accessType="write"),
+ DataBreakpoint(dataId=x_data_id, accessType="write"),
]
- set_response = self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- breakpoints = set_response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 3)
- self.assertFalse(breakpoints[0]["verified"])
- self.assertTrue(breakpoints[1]["verified"])
- self.assertTrue(breakpoints[2]["verified"])
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[2]["id"]])
- x_val = self.dap_server.get_local_variable_value("x")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(x_val, "2")
- self.assertEqual(i_val, "1")
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[1]["id"]])
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(arr_2["value"], "42")
- self.assertEqual(i_val, "2")
+ set_response = session.set_data_breakpoints(data_breakpoints)
+ [bp_x_read, bp_arr_2, bp_x_write] = set_response.body.breakpoints
+ self.assertFalse(bp_x_read.verified)
+ self.assertTrue(bp_arr_2.verified)
+ self.assertTrue(bp_x_write.verified)
+
+ # Hit the write watchpoint on `x` at i == 1.
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_x_write.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["x"].value, "2")
+ self.assertEqual(top_frame.locals["i"].value, "1")
+
+ # Hit the write watchpoint on `arr[2]` at i == 2.
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_arr_2.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["arr"]["[2]"].value, "42")
+ self.assertEqual(top_frame.locals["i"].value, "2")
+
+ session.set_data_breakpoints([])
+ session.continue_to_exit()
@skipIfWindows
def test_expression(self):
"""Tests setting data breakpoints on expression."""
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
source = "main.cpp"
+ program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session()
first_loop_break_line = line_number(source, "// first loop breakpoint")
- self.set_source_breakpoints(source, [first_loop_break_line])
- self.continue_to_next_stop()
- self.dap_server.get_stackFrame()
- # Test setting write watchpoint using expressions: &x, arr+2
- response_x = self.dap_server.request_dataBreakpointInfo(0, "&x")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(0, "arr+2")
- # Test response from dataBreakpointInfo request.
- self.assertEqual(response_x["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEqual(response_arr_2["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_arr_2["body"]["accessTypes"], self.accessTypes)
- dataBreakpoints = [
- {"dataId": response_x["body"]["dataId"], "accessType": "write"},
- {"dataId": response_arr_2["body"]["dataId"], "accessType": "write"},
+ 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)
+
+ # Verify write watchpoints on expressions `&x` and `arr+2`.
+ top_frame_id = session.top_frame_from(stop_event).frame.id
+ response_x = session.data_breakpoint_info("&x", 0, top_frame_id)
+ response_arr_2 = session.data_breakpoint_info("arr+2", 0, top_frame_id)
+
+ x_data_id = self.expect_not_none(response_x.body.dataId)
+ arr_2_data_id = self.expect_not_none(response_arr_2.body.dataId)
+ self.assertEqual(x_data_id.split("/")[1], "4")
+ self.assertEqual(response_x.body.accessTypes, self.ACCESS_TYPES)
+ self.assertEqual(arr_2_data_id.split("/")[1], "4")
+ self.assertEqual(response_arr_2.body.accessTypes, self.ACCESS_TYPES)
+
+ data_breakpoints = [
+ DataBreakpoint(dataId=x_data_id, accessType="write"),
+ DataBreakpoint(dataId=arr_2_data_id, accessType="write"),
]
- set_response = self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- breakpoints = set_response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 2)
- self.assertTrue(breakpoints[0]["verified"])
- self.assertTrue(breakpoints[1]["verified"])
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[0]["id"]])
- x_val = self.dap_server.get_local_variable_value("x")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(x_val, "2")
- self.assertEqual(i_val, "1")
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[1]["id"]])
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(arr_2["value"], "42")
- self.assertEqual(i_val, "2")
+ set_response = session.set_data_breakpoints(data_breakpoints)
+ [bp_x, bp_arr_2] = set_response.body.breakpoints
+ self.assertTrue(bp_x.verified)
+ self.assertTrue(bp_arr_2.verified)
+
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_x.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["x"].value, "2")
+ self.assertEqual(top_frame.locals["i"].value, "1")
+
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_arr_2.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["arr"]["[2]"].value, "42")
+ self.assertEqual(top_frame.locals["i"].value, "2")
+
+ session.set_data_breakpoints([])
+ session.continue_to_exit()
@skipIfWindows
def test_functionality(self):
"""Tests setting data breakpoints on variable."""
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
source = "main.cpp"
+ program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session()
first_loop_break_line = line_number(source, "// first loop breakpoint")
- first_bp_ids = self.set_source_breakpoints(source, [first_loop_break_line])
- self.assertEqual(len(first_bp_ids), 1)
- self.continue_to_next_stop()
- self.dap_server.get_local_variables()
- locals_ref = self.get_locals_scope_reference()
- self.assertIsNotNone(locals_ref, "Failed to get locals scope reference")
- # Test write watchpoints on x, arr[2]
- response_x = self.dap_server.request_dataBreakpointInfo(locals_ref, "x")
- arr = self.dap_server.get_local_variable("arr")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(
- arr["variablesReference"], "[2]"
- )
-
- # Test response from dataBreakpointInfo request.
- self.assertEqual(response_x["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEqual(response_arr_2["body"]["dataId"].split("/")[1], "4")
- self.assertEqual(response_arr_2["body"]["accessTypes"], self.accessTypes)
- dataBreakpoints = [
- {"dataId": response_x["body"]["dataId"], "accessType": "write"},
- {"dataId": response_arr_2["body"]["dataId"], "accessType": "write"},
+ 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_ctx = session.top_frame_from(stop_event)
+ frame_id = top_frame_ctx.frame.id
+ locals_ref = top_frame_ctx.locals.variablesReference
+
+ # Verify write watchpoints on x and arr[2].
+ response_x = session.data_breakpoint_info("x", locals_ref, frame_id)
+ arr = top_frame_ctx.locals["arr"]
+ arr_var_ref = self.expect_not_none(arr.variablesReference)
+ response_arr_2 = session.data_breakpoint_info("[2]", arr_var_ref, frame_id)
+
+ x_data_id = self.expect_not_none(response_x.body.dataId)
+ arr_2_data_id = self.expect_not_none(response_arr_2.body.dataId)
+ self.assertEqual(x_data_id.split("/")[1], "4")
+ self.assertEqual(response_x.body.accessTypes, self.ACCESS_TYPES)
+ self.assertEqual(arr_2_data_id.split("/")[1], "4")
+ self.assertEqual(response_arr_2.body.accessTypes, self.ACCESS_TYPES)
+
+ data_breakpoints = [
+ DataBreakpoint(dataId=x_data_id, accessType="write"),
+ DataBreakpoint(dataId=arr_2_data_id, accessType="write"),
]
- set_response = self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- breakpoints = set_response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 2)
- self.assertTrue(breakpoints[0]["verified"])
- self.assertTrue(breakpoints[1]["verified"])
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[0]["id"]])
- x_val = self.dap_server.get_local_variable_value("x")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(x_val, "2")
- self.assertEqual(i_val, "1")
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[1]["id"]])
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEqual(arr_2["value"], "42")
- self.assertEqual(i_val, "2")
- self.dap_server.request_setDataBreakpoint([])
-
- # Verify breakpoints are unique.
- all_breakpoints = set(
- [first_bp_ids[0], breakpoints[0]["id"], breakpoints[1]["id"]]
- )
- self.assertEqual(
- len(all_breakpoints), 3, f"found breakpoints {all_breakpoints}"
- )
+ set_response = session.set_data_breakpoints(data_breakpoints)
+ [bp_x, bp_arr_2] = set_response.body.breakpoints
+ self.assertTrue(bp_x.verified)
+ self.assertTrue(bp_arr_2.verified)
+
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_x.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["x"].value, "2")
+ self.assertEqual(top_frame.locals["i"].value, "1")
- # Test hit condition
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_arr_2.id))
+ top_frame = session.top_frame_from(stop_event)
+ self.assertEqual(top_frame.locals["arr"]["[2]"].value, "42")
+ self.assertEqual(top_frame.locals["i"].value, "2")
+
+ session.set_data_breakpoints([])
+
+ # Verify hit condition: skip past the second-loop breakpoint until `x`
+ # has been written twice, then verify we stop with x == 3.
second_loop_break_line = line_number(source, "// second loop breakpoint")
- breakpoint_ids = self.set_source_breakpoints(source, [second_loop_break_line])
- self.continue_to_breakpoints(breakpoint_ids)
- dataBreakpoints = [
- {
- "dataId": response_x["body"]["dataId"],
- "accessType": "write",
- "hitCondition": "2",
- }
- ]
- set_response = self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- breakpoints = set_response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- self.assertTrue(breakpoints[0]["verified"])
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[0]["id"]])
- x_val = self.dap_server.get_local_variable_value("x")
- self.assertEqual(x_val, "3")
-
- # Test condition
- dataBreakpoints = [
- {
- "dataId": response_x["body"]["dataId"],
- "accessType": "write",
- "condition": "x==10",
- }
- ]
- set_response = self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- breakpoints = set_response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- self.assertTrue(breakpoints[0]["verified"])
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([breakpoints[0]["id"]])
- x_val = self.dap_server.get_local_variable_value("x")
- self.assertEqual(x_val, "10")
+ breakpoint_ids = session.resolve_source_breakpoints(
+ source, [second_loop_break_line]
+ )
+ session.continue_to_any_breakpoint(breakpoint_ids)
+ set_response = session.set_data_breakpoints(
+ [DataBreakpoint(dataId=x_data_id, accessType="write", hitCondition="2")]
+ )
+ [bp_hit] = set_response.body.breakpoints
+ self.assertTrue(bp_hit.verified)
+ stop_event = session.continue_to_breakpoint(self.expect_not_none(bp_hit.id))
+ self.assertEqual(session.top_frame_from(stop_event).locals["x"].value, "3")
+
+ # Test condition: only stop when the write makes x == 10.
+ set_response = session.set_data_breakpoints(
+ [DataBreakpoint(dataId=x_data_id, accessType="write", condition="x==10")]
+ )
+ [bp_cond] = set_response.body.breakpoints
+ self.assertTrue(bp_cond.verified)
+ 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_bytes(self):
"""Tests setting data breakpoints on memory range."""
+ source = self.getSourcePath("main.cpp")
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- source = "main.cpp"
+ session = self.build_and_create_session()
first_loop_break_line = line_number(source, "// first loop breakpoint")
- self.set_source_breakpoints(source, [first_loop_break_line])
- self.continue_to_next_stop()
- # Test write watchpoints on x, arr[2]
- x = self.dap_server.get_local_variable("x")
- response_x = self.dap_server.request_dataBreakpointInfo(
- 0, x["memoryReference"], 4
- )
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(
- 0, arr_2["memoryReference"], 4
+ 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)
+
+ # Set write watchpoints on x and arr[2] using their memory references.
+ top_frame = session.top_frame_from(stop_event)
+ x_memory_reference = self.expect_not_none(top_frame.locals["x"].memoryReference)
+ arr_2_mem_ref = self.expect_not_none(
+ top_frame.locals["arr"]["[2]"].memoryReference
)
-
- # Test response from dataBreakpointInfo request.
- self.assertEqual(
- response_x["body"]["dataId"].split("/"), [x["memoryReference"][2:], "4"]
- )
- self.assertEqual(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEqual(
- response_arr_2["body"]["dataId"].split("/"),
- [arr_2["memoryReference"][2:], "4"],
+ response_x = session.data_breakpoint_info_as_address(x_memory_reference, 4)
+ response_arr_2 = session.data_breakpoint_info_as_address(arr_2_mem_ref, 4)
+
+ x_data_id = self.expect_not_none(response_x.body.dataId)
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/213269
More information about the lldb-commits
mailing list