[Lldb-commits] [lldb] 4bb9022 - [lldb-dap] Migrate breakpointAssembly and instructionBreakpoint test (#211054)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 22 03:32:20 PDT 2026
Author: Ebuka Ezike
Date: 2026-07-22T11:32:15+01:00
New Revision: 4bb9022f545ceb2b01789bd86d29da495449351b
URL: https://github.com/llvm/llvm-project/commit/4bb9022f545ceb2b01789bd86d29da495449351b
DIFF: https://github.com/llvm/llvm-project/commit/4bb9022f545ceb2b01789bd86d29da495449351b.diff
LOG: [lldb-dap] Migrate breakpointAssembly and instructionBreakpoint test (#211054)
Added:
Modified:
lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
Removed:
################################################################################
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
index cbbea9ea9540b..9bc3d989ca4f6 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py
@@ -2,162 +2,116 @@
Test lldb-dap setBreakpoints request in assembly source references.
"""
-from lldbsuite.test.decorators import *
-from dap_server import Source
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWindows
+from lldbsuite.test.tools.lldb_dap.types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
-class TestDAP_setBreakpointsAssembly(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_setBreakpointsAssembly(DAPTestCaseBase):
# When using PDB, we need to have debug information to break on assembly_func,
# but this test relies on us not having debug information for that function.
@skipIfWindows
def test_can_break_in_source_references(self):
"""Tests hitting assembly source breakpoints"""
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- assmebly_func_breakpoints = self.set_function_breakpoints(["assembly_func"])
- self.continue_to_breakpoints(assmebly_func_breakpoints)
-
- assembly_func_frame = self.get_stackFrames()[0]
- self.assertIn(
- "sourceReference",
- assembly_func_frame.get("source"),
- "Expected assembly source frame",
+ session = self.build_and_create_session()
+ with session.configure(LaunchArgs(program)) as ctx:
+ [assembly_func_id] = session.resolve_function_breakpoints(["assembly_func"])
+ stop_event = session.verify_stopped_on_breakpoint(
+ assembly_func_id, after=ctx.process_event
)
- line = assembly_func_frame["line"]
+ top_frame = session.top_frame_from(stop_event).frame
+ source_reference = self.expect_not_none(
+ top_frame.source and top_frame.source.sourceReference,
+ "expected an assembly source reference",
+ )
- # Set an assembly breakpoint in the next line and check that it's hit
- source_reference = assembly_func_frame["source"]["sourceReference"]
- assembly_breakpoint_ids = self.set_source_breakpoints_assembly(
- source_reference, [line + 1]
+ # Set an assembly breakpoint on the next line and check that it's hit.
+ asm_bp_response = session.set_assembly_breakpoints(
+ source_reference, [top_frame.line + 1]
)
- self.continue_to_breakpoints(assembly_breakpoint_ids)
+ [asm_bp_id] = session.breakpoints_to_ids(asm_bp_response.body.breakpoints)
+ session.continue_to_breakpoint(asm_bp_id)
- # Continue again and verify it hits in the next function call
- self.continue_to_breakpoints(assmebly_func_breakpoints)
- self.continue_to_breakpoints(assembly_breakpoint_ids)
+ # Continue again and verify it hits in the next function call.
+ session.continue_to_breakpoint(assembly_func_id)
+ session.continue_to_breakpoint(asm_bp_id)
- # Clear the breakpoint and then check that the assembly breakpoint does not hit next time
- self.set_source_breakpoints_assembly(source_reference, [])
- self.continue_to_breakpoints(assmebly_func_breakpoints)
- self.continue_to_exit()
+ # Clear the assembly breakpoint and verify it does not hit again.
+ session.set_assembly_breakpoints(source_reference, [])
+ session.continue_to_breakpoint(assembly_func_id)
+ session.continue_to_exit()
def test_break_on_invalid_source_reference(self):
- """Tests hitting assembly source breakpoints"""
+ """Tests setting breakpoints on invalid source references fails cleanly."""
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Verify that setting a breakpoint on an invalid source reference fails
- response = self.dap_server.request_setBreakpoints(
- Source.build(source_reference=-1), [1]
- )
- self.assertIsNotNone(response)
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- breakpoint = breakpoints[0]
- self.assertFalse(
- breakpoint["verified"], "Expected breakpoint to not be verified"
- )
- self.assertIn("message", breakpoint, "Expected message to be present")
- self.assertEqual(
- breakpoint["message"],
- "Invalid sourceReference.",
- )
+ session = self.build_and_create_session()
+ session.launch(LaunchArgs(program))
- # Verify that setting a breakpoint on a source reference that is not created fails
- response = self.dap_server.request_setBreakpoints(
- Source.build(source_reference=200), [1]
- )
- self.assertIsNotNone(response)
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- break_point = breakpoints[0]
- self.assertFalse(
- break_point["verified"], "Expected breakpoint to not be verified"
- )
- self.assertIn("message", break_point, "Expected message to be present")
- self.assertEqual(
- break_point["message"],
- "Invalid sourceReference.",
- )
+ # Verify that setting a breakpoint on an invalid source reference or
+ # a source reference not created fails.
+ for bad_ref in (-1, 200):
+ response = session.set_assembly_breakpoints(bad_ref, [1])
+ [bp] = response.body.breakpoints
+ self.assertFalse(bp.verified, "expected breakpoint to not be verified")
+ self.assertEqual(bp.message, "Invalid sourceReference.")
@skipIfWindows
def test_persistent_assembly_breakpoint(self):
- """Tests that assembly breakpoints are working persistently across sessions"""
+ """Tests that assembly breakpoints persist across sessions."""
self.build()
program = self.getBuildArtifact("a.out")
- self.create_debug_adapter()
-
- # Run the first session and set a persistent assembly breakpoint
- try:
- self.dap_server.request_initialize()
- self.dap_server.request_launch(program)
- self.dap_server.wait_for_event(["initialized"])
-
- assembly_func_breakpoints = self.set_function_breakpoints(["assembly_func"])
- self.continue_to_breakpoints(assembly_func_breakpoints)
- assembly_func_frame = self.get_stackFrames()[0]
- source_reference = assembly_func_frame["source"]["sourceReference"]
-
- # Set an assembly breakpoint in the middle of the assembly function
- persistent_breakpoint_line = 4
- persistent_breakpoint_ids = self.set_source_breakpoints_assembly(
- source_reference, [persistent_breakpoint_line]
- )
+ # Session 1: set the persistent assembly breakpoint.
+ session = self.create_session(disconnect_automatically=False)
+ with session.configure(LaunchArgs(program)) as ctx:
+ function_bp_ids = session.resolve_function_breakpoints(["assembly_func"])
+ stop_event = session.verify_stopped_on_breakpoint(
+ function_bp_ids, after=ctx.process_event
+ )
- self.assertEqual(
- len(persistent_breakpoint_ids),
- 1,
- "Expected one assembly breakpoint to be set",
- )
+ top_frame = session.top_frame_from(stop_event).frame
+ source = self.expect_not_none(top_frame.source)
+ source_reference = self.expect_not_none(source.sourceReference)
- persistent_breakpoint_source = self.dap_server.resolved_breakpoints[
- persistent_breakpoint_ids[0]
- ]["source"]
- self.assertIn(
- "adapterData",
- persistent_breakpoint_source,
- "Expected assembly breakpoint to have persistent information",
- )
- self.assertIn(
- "persistenceData",
- persistent_breakpoint_source["adapterData"],
- "Expected assembly breakpoint to have persistent information",
- )
+ persistent_breakpoint_line = 4
+ response = session.set_assembly_breakpoints(
+ source_reference, [persistent_breakpoint_line]
+ )
+ [persistent_bp] = response.body.breakpoints
+ persistent_source = self.expect_not_none(
+ persistent_bp.source, "expected resolved breakpoint to carry a source"
+ )
+ adapter_data = self.expect_not_none(
+ persistent_source.adapterData,
+ "expected assembly breakpoint to carry persistence info",
+ )
+ self.assertIn(
+ "persistenceData",
+ adapter_data,
+ "expected adapterData to include persistenceData",
+ )
- self.continue_to_breakpoints(persistent_breakpoint_ids)
- finally:
- self.dap_server.request_disconnect(terminateDebuggee=True)
- self.dap_server.terminate()
-
- # Restart the session and verify the breakpoint is still there
- self.create_debug_adapter()
- try:
- self.dap_server.request_initialize()
- self.dap_server.request_launch(program)
- self.dap_server.wait_for_event(["initialized"])
-
- new_session_breakpoints_ids = self.set_source_breakpoints_from_source(
- Source(persistent_breakpoint_source),
- [persistent_breakpoint_line],
- )
+ session.continue_to_breakpoint(self.expect_not_none(persistent_bp.id))
+ session.disconnect(terminateDebuggee=True)
+ session.stop()
- self.assertEqual(
- len(new_session_breakpoints_ids),
- 1,
- "Expected one breakpoint to be set in the new session",
+ # Session 2: replay the persisted source and verify the breakpoint hits.
+ adapter = self.create_stdio_debug_adapter()
+ session2 = self.create_session(adapter=adapter)
+ with session2.configure(LaunchArgs(program)) as ctx:
+ response = session2.set_assembly_breakpoints(
+ persistent_source, [persistent_breakpoint_line]
)
+ [new_bp_id] = session2.breakpoints_to_ids(response.body.breakpoints)
- self.continue_to_breakpoints(new_session_breakpoints_ids)
- current_line = self.get_stackFrames()[0]["line"]
- self.assertEqual(
- current_line,
- persistent_breakpoint_line,
- "Expected to hit the persistent assembly breakpoint at the same line",
- )
- finally:
- self.dap_server.request_disconnect(terminateDebuggee=True)
- self.dap_server.terminate()
+ stop_event = session2.verify_stopped_on_breakpoint(
+ new_bp_id, after=ctx.process_event
+ )
+ top_frame = session2.top_frame_from(stop_event).frame
+ self.assertEqual(
+ top_frame.line,
+ persistent_breakpoint_line,
+ "expected to hit the persistent assembly breakpoint at the same line",
+ )
diff --git a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
index 8bb9ea2be5a9f..9438871bd6764 100644
--- a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
+++ b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
@@ -1,99 +1,79 @@
-from dap_server import Source
-import shutil
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-import lldbdap_testcase
-import os
-import lldb
+"""
+Test lldb-dap instruction breakpoints.
+"""
+import os
-class TestDAP_InstructionBreakpointTestCase(lldbdap_testcase.DAPTestCaseBase):
- NO_DEBUG_INFO_TESTCASE = True
+from lldbsuite.test.decorators import 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
- def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
- self.main_basename = "main-copy.cpp"
- self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
+class TestDAP_InstructionBreakpointTestCase(DAPTestCaseBase):
+ NO_DEBUG_INFO_TESTCASE = True
@skipIfWindows
def test_instruction_breakpoint(self):
- self.build()
- self.instruction_breakpoint_test()
-
- def instruction_breakpoint_test(self):
- """Sample test to ensure SBFrame::Disassemble produces SOME output"""
- # Create a target by the debugger.
- target = self.createTestTarget()
+ """Set a source breakpoint, then use the disassembly to set an
+ instruction breakpoint on the next instruction and verify we hit it."""
+ program = self.getBuildArtifact("a.out")
+ session = self.build_and_create_session()
+ main_basename = "main-copy.cpp"
+ main_path = os.path.realpath(self.getBuildArtifact(main_basename))
main_line = line_number("main.cpp", "breakpoint 1")
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ # Set a source breakpoint and check it was resolved against the
+ # renamed source file.
+ with session.configure(LaunchArgs(program)) as ctx:
+ response = session.set_source_breakpoints(main_path, [main_line])
+ [source_bp] = response.body.breakpoints
+ self.assertTrue(source_bp.verified, "breakpoint is not verified")
+ self.assertEqual(source_bp.line, main_line, "incorrect breakpoint line")
- # Set source breakpoint 1
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), [main_line]
- )
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- breakpoint = breakpoints[0]
- self.assertEqual(
- breakpoint["line"], main_line, "incorrect breakpoint source line"
- )
- self.assertTrue(breakpoint["verified"], "breakpoint is not verified")
- self.assertEqual(
- self.main_basename, breakpoint["source"]["name"], "incorrect source name"
- )
- self.assertEqual(
- self.main_path, breakpoint["source"]["path"], "incorrect source file path"
- )
- other_breakpoint_id = breakpoint["id"]
+ bp_source = self.expect_not_none(source_bp.source)
+ self.assertEqual(bp_source.name, main_basename, "incorrect source name")
+ self.assertEqual(bp_source.path, main_path, "incorrect source path")
- # Continue and then verifiy the breakpoint
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([other_breakpoint_id])
+ source_bp_id = self.expect_not_none(source_bp.id)
- # now we check the stack trace making sure that we got mapped source paths
- frames = self.dap_server.request_stackTrace()["body"]["stackFrames"]
- intstructionPointerReference = []
- setIntstructionBreakpoints = []
- intstructionPointerReference.append(frames[0]["instructionPointerReference"])
- self.assertEqual(
- frames[0]["source"]["name"], self.main_basename, "incorrect source name"
+ # Run to the source breakpoint, the stack frame should also report
+ # the renamed source.
+ stop_event = session.verify_stopped_on_breakpoint(
+ source_bp_id, after=ctx.process_event
)
+ top_frame_ctx = session.top_frame_from(stop_event)
+ top_frame = top_frame_ctx.frame
+
+ frame_source = self.expect_not_none(top_frame.source)
+ self.assertEqual(frame_source.name, main_basename, "incorrect source name")
+ self.assertEqual(frame_source.path, main_path, "incorrect source path")
+
+ # Disassemble at the current PC and use the address of the following
+ # instruction as an instruction breakpoint target.
+ disasm = top_frame_ctx.disassemble()
+ current_inst, next_inst = disasm[0], disasm[1]
+
self.assertEqual(
- frames[0]["source"]["path"], self.main_path, "incorrect source file path"
+ current_inst.address,
+ top_frame.instructionPointerReference,
+ "disassembly does not begin at the current instruction",
)
+ self.assertGreater(len(next_inst.address), 2)
+ self.assertNotEqual(next_inst.presentationHint, "invalid")
- # Check disassembly view
- disassembled_instructions, instruction = self.disassemble(frameIndex=0)
+ bp_response = session.set_instruction_breakpoints([next_inst.address])
+ [inst_bp] = bp_response.body.breakpoints
self.assertEqual(
- instruction["address"],
- intstructionPointerReference[0],
- "current breakpoint reference is not in the disaasembly view",
+ inst_bp.instructionReference,
+ next_inst.address,
+ "instruction breakpoint was not resolved to the expected address",
)
- # Get next instruction address to set instruction breakpoint
- instruction_addr_list = list(disassembled_instructions.keys())
- index = instruction_addr_list.index(intstructionPointerReference[0])
- if len(instruction_addr_list) >= (index + 1):
- next_inst_addr = instruction_addr_list[index + 1]
- if len(next_inst_addr) > 2:
- setIntstructionBreakpoints.append(next_inst_addr)
- instruction_breakpoint_response = (
- self.dap_server.request_setInstructionBreakpoints(
- setIntstructionBreakpoints
- )
- )
- inst_breakpoints = instruction_breakpoint_response["body"][
- "breakpoints"
- ]
- self.assertEqual(
- inst_breakpoints[0]["instructionReference"],
- next_inst_addr,
- "Instruction breakpoint has not been resolved or failed to relocate the instruction breakpoint",
- )
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([inst_breakpoints[0]["id"]])
+ inst_bp_id = self.expect_not_none(inst_bp.id)
+ session.continue_to_breakpoint(inst_bp_id)
+
+ session.set_source_breakpoints(main_path, [])
+ session.set_instruction_breakpoints([])
+ session.continue_to_exit(exitCode=3)
More information about the lldb-commits
mailing list