[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