https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/213269
Drop the raw line number when matching the expected location. >From f13dd60ccd702100dfe8fa6c9a2eb6b4a78d3152 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike <[email protected]> Date: Fri, 31 Jul 2026 14:01:45 +0100 Subject: [PATCH] [lldb-dap] Mirgate setDataBreakpoint and Locations test Drop the raw line number when matching the expected location. --- .../TestDAP_setDataBreakpoints.py | 409 +++++++++--------- .../lldb-dap/locations/TestDAP_locations.py | 120 +++-- .../API/tools/lldb-dap/locations/main.cpp | 16 +- 3 files changed, 256 insertions(+), 289 deletions(-) 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 -@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"] +@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) + arr_2_data_id = self.expect_not_none(response_arr_2.body.dataId) + self.assertEqual(x_data_id.split("/"), [x_memory_reference[2:], "4"]) + self.assertEqual(response_x.body.accessTypes, self.ACCESS_TYPES) + self.assertEqual(arr_2_data_id.split("/"), [arr_2_mem_ref[2:], "4"]) + self.assertEqual(response_arr_2.body.accessTypes, self.ACCESS_TYPES) + + set_response = session.set_data_breakpoints( + [ + DataBreakpoint(dataId=x_data_id, accessType="write"), + DataBreakpoint(dataId=arr_2_data_id, accessType="write"), + ] ) - 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"}, - ] - 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([]) + [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() diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py index 2a079a7f70383..d2c921fbf39a8 100644 --- a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -2,21 +2,13 @@ Test lldb-dap locations request """ +from lldbsuite.test.decorators import skipIf, skipIfWindows +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase +from lldbsuite.test.tools.lldb_dap.types import LaunchArgs -import dap_server -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil -import lldbdap_testcase -import os - -class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): - def verify_location(self, location_reference: str, filename: str, line: int): - response = self.dap_server.request_locations(location_reference) - self.assertTrue(response["success"]) - self.assertTrue(response["body"]["source"]["path"].endswith(filename)) - self.assertEqual(response["body"]["line"], line) +class TestDAP_locations(DAPTestCaseBase): @skipIfWindows @skipIf( @@ -27,68 +19,62 @@ def test_locations(self): Tests the 'locations' request. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) - source = "main.cpp" - self.source_path = os.path.join(os.getcwd(), source) - self.set_source_breakpoints( - source, - [line_number(source, "break here")], - ) - self.continue_to_next_stop() + session = self.build_and_create_session() + source = self.getSourcePath("main.cpp") + with session.configure(LaunchArgs(program)) as ctx: + session.resolve_source_breakpoints( + source, [line_number(source, "break here")] + ) + stop_event = session.verify_stopped_on_breakpoint(after=ctx.process_event) - locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + top_frame = session.top_frame_from(stop_event) + top_frame_locals = top_frame.locals - # var1 has a declarationLocation but no valueLocation - declaration_location_reference = locals["var1"].get( - "declarationLocationReference" - ) - self.assertIsNotNone(declaration_location_reference) - self.verify_location(declaration_location_reference, "main.cpp", 11) - value_location_reference = locals["var1"].get("valueLocationReference") - self.assertIsNone(value_location_reference) + # var1 has a declarationLocation but no valueLocation. + var1 = top_frame_locals["var1"].variable + decl_ref = self.expect_not_none(var1.declarationLocationReference) + session.verify_location(decl_ref, "main.cpp", line_number(source, "var1 decl")) + self.assertIsNone(var1.valueLocationReference) - # func_ptr has both a declaration and a valueLocation - declaration_location_reference = locals["func_ptr"].get( - "declarationLocationReference" + # func_ptr has both a declaration and a valueLocation. + func_ptr = top_frame_locals["func_ptr"].variable + decl_ref = self.expect_not_none(func_ptr.declarationLocationReference) + session.verify_location( + decl_ref, "main.cpp", line_number(source, "func_ptr decl") ) - self.assertIsNotNone(declaration_location_reference) - self.verify_location(declaration_location_reference, "main.cpp", 12) - value_location_reference = locals["func_ptr"].get("valueLocationReference") - self.assertIsNotNone(value_location_reference) - self.verify_location(value_location_reference, "main.cpp", 3) - - # func_ref has both a declaration and a valueLocation - declaration_location_reference = locals["func_ref"].get( - "declarationLocationReference" + value_ref = self.expect_not_none(func_ptr.valueLocationReference) + session.verify_location( + value_ref, "main.cpp", line_number(source, "greet decl") ) - self.assertIsNotNone(declaration_location_reference) - self.verify_location(declaration_location_reference, "main.cpp", 13) - value_location_reference = locals["func_ref"].get("valueLocationReference") - self.assertIsNotNone(value_location_reference) - self.verify_location(value_location_reference, "main.cpp", 3) - # member_ptr has both a declaration and a valueLocation - declaration_location_reference = locals["member_ptr"].get( - "declarationLocationReference" + # func_ref has both a declaration and a valueLocation. + func_ref = top_frame_locals["func_ref"].variable + decl_ref = self.expect_not_none(func_ref.declarationLocationReference) + session.verify_location( + decl_ref, "main.cpp", line_number(source, "func_ref decl") + ) + value_ref = self.expect_not_none(func_ref.valueLocationReference) + session.verify_location( + value_ref, "main.cpp", line_number(source, "greet decl") ) - self.assertIsNotNone(declaration_location_reference) - self.verify_location(declaration_location_reference, "main.cpp", 14) - value_location_reference = locals["member_ptr"].get("valueLocationReference") - self.assertIsNotNone(value_location_reference) - self.verify_location(value_location_reference, "main.cpp", 6) - # virtual_member_ptr has a declarationLocation but no valueLocation - declaration_location_reference = locals["virtual_member_ptr"].get( - "declarationLocationReference" + # member_ptr has both a declaration and a valueLocation. + member_ptr = top_frame_locals["member_ptr"].variable + decl_ref = self.expect_not_none(member_ptr.declarationLocationReference) + session.verify_location( + decl_ref, "main.cpp", line_number(source, "member_ptr decl") ) - self.assertIsNotNone(declaration_location_reference) - self.verify_location(declaration_location_reference, "main.cpp", 15) - value_location_reference = locals["virtual_member_ptr"].get( - "valueLocationReference" + value_ref = self.expect_not_none(member_ptr.valueLocationReference) + session.verify_location(value_ref, "main.cpp", line_number(source, "foo decl")) + + # virtual_member_ptr has a declarationLocation but no valueLocation. + virtual_member_ptr = top_frame_locals["virtual_member_ptr"].variable + decl_ref = self.expect_not_none(virtual_member_ptr.declarationLocationReference) + session.verify_location( + decl_ref, "main.cpp", line_number(source, "virtual_member_ptr decl") ) - self.assertIsNone(value_location_reference) + self.assertIsNone(virtual_member_ptr.valueLocationReference) - # `evaluate` responses for function pointers also have locations associated - eval_res = self.dap_server.request_evaluate("greet") - self.assertTrue(eval_res["success"]) - self.assertIn("valueLocationReference", eval_res["body"].keys()) + # `evaluate` responses for function pointers also have locations associated. + eval_body = top_frame.evaluate("greet") + self.assertIsNotNone(eval_body.valueLocationReference) diff --git a/lldb/test/API/tools/lldb-dap/locations/main.cpp b/lldb/test/API/tools/lldb-dap/locations/main.cpp index 1739fe4f00c96..19b20228edf2b 100644 --- a/lldb/test/API/tools/lldb-dap/locations/main.cpp +++ b/lldb/test/API/tools/lldb-dap/locations/main.cpp @@ -1,17 +1,17 @@ int g = 0; -void greet() { g++; } +void greet() { g++; } // greet decl struct Test { - void foo() {} + void foo() {} // foo decl virtual void bar() {} }; int main(void) { - int var1 = 1; - void (*func_ptr)() = &greet; - void (&func_ref)() = greet; - auto member_ptr = &Test::foo; - auto virtual_member_ptr = &Test::bar; - return 0; // break here + int var1 = 1; // var1 decl + void (*func_ptr)() = &greet; // func_ptr decl + void (&func_ref)() = greet; // func_ref decl + auto member_ptr = &Test::foo; // member_ptr decl + auto virtual_member_ptr = &Test::bar; // virtual_member_ptr decl + return 0; // break here } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
