[Lldb-commits] [lldb] [lldb-dap] Migrate lldb-dap tests in `lldb-dap/breakpoint` (PR #208166)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 14 14:50:44 PDT 2026
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/208166
>From fec536f3102b714c47b770c251ed135ce87989f4 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 7 Jul 2026 17:30:40 +0100
Subject: [PATCH 1/3] [lldb-dap] Migrate lldb-dap tests in
`lldb-dap/breakpoint`
migrate breakpointLocations, logpoints, setBreakpoints
exceptionBreakpoints and functionBreakpoints test
---
.../breakpoint/TestDAP_breakpointLocations.py | 121 ++---
.../lldb-dap/breakpoint/TestDAP_logpoints.py | 310 +++++-------
.../breakpoint/TestDAP_setBreakpoints.py | 477 +++++++++---------
.../TestDAP_setExceptionBreakpoints.py | 35 +-
.../TestDAP_setFunctionBreakpoints.py | 189 ++++---
5 files changed, 531 insertions(+), 601 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
index 1fe5f8b9e2adc..f97b4b403b063 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
@@ -2,88 +2,77 @@
Test lldb-dap breakpointLocations request
"""
-
-import dap_server
-import shutil
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-import lldbdap_testcase
import os
+from lldbsuite.test.decorators import (
+ skipIfTargetDoesNotSupportSharedLibraries,
+ skipIfWindows,
+)
+from lldbsuite.test.lldbtest import line_number
+from lldbsuite.test.tools.lldb_dap.dap_types import BreakpointLocation, LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
- at skipIfTargetDoesNotSupportSharedLibraries()
-class TestDAP_breakpointLocations(lldbdap_testcase.DAPTestCaseBase):
- 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))
+ at skipIfTargetDoesNotSupportSharedLibraries()
+class TestDAP_breakpointLocations(DAPTestCaseBase):
@skipIfWindows
def test_column_breakpoints(self):
"""Test retrieving the available breakpoint locations."""
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program, stopOnEntry=True)
- loop_line = line_number(self.main_path, "// break loop")
- self.dap_server.request_continue()
+ session = self.build_and_create_session()
+ main_path = os.path.realpath(self.getBuildArtifact("main-copy.cpp"))
- # Ask for the breakpoint locations based only on the line number
- response = self.dap_server.request_breakpointLocations(
- self.main_path, loop_line
- )
- self.assertTrue(response["success"])
- self.assertEqual(
- response["body"]["breakpoints"],
- [
- {"line": loop_line, "column": 9},
- {"line": loop_line, "column": 13},
- {"line": loop_line, "column": 20},
- {"line": loop_line, "column": 23},
- {"line": loop_line, "column": 25},
- {"line": loop_line, "column": 34},
- {"line": loop_line, "column": 37},
- {"line": loop_line, "column": 39},
- {"line": loop_line, "column": 51},
- ],
- )
+ process_event = session.launch(LaunchArgs(program, stopOnEntry=True))
+ session.verify_stopped_on_entry(after=process_event)
- # Ask for the breakpoint locations for a column range
- response = self.dap_server.request_breakpointLocations(
- self.main_path,
- loop_line,
- column=24,
- end_column=46,
- )
- self.assertTrue(response["success"])
- self.assertEqual(
- response["body"]["breakpoints"],
- [
- {"line": loop_line, "column": 25},
- {"line": loop_line, "column": 34},
- {"line": loop_line, "column": 37},
- {"line": loop_line, "column": 39},
- ],
+ # Ask for the breakpoint locations based only on the line number.
+ loop_line = line_number(main_path, "// break loop")
+ response = session.get_breakpoint_locations(main_path, loop_line)
+ breakpoint_locations = response.body.breakpoints
+
+ expected_locations = [
+ BreakpointLocation(line=loop_line, column=9),
+ BreakpointLocation(line=loop_line, column=13),
+ BreakpointLocation(line=loop_line, column=20),
+ BreakpointLocation(line=loop_line, column=23),
+ BreakpointLocation(line=loop_line, column=25),
+ BreakpointLocation(line=loop_line, column=34),
+ BreakpointLocation(line=loop_line, column=37),
+ BreakpointLocation(line=loop_line, column=39),
+ BreakpointLocation(line=loop_line, column=51),
+ ]
+ self.assertEqual(breakpoint_locations, expected_locations)
+
+ # Ask for the breakpoint locations for a column range.
+ response = session.get_breakpoint_locations(
+ main_path, loop_line, column=24, endColumn=46
)
+ breakpoint_locations = response.body.breakpoints
+ expected_locations = [
+ BreakpointLocation(line=loop_line, column=25),
+ BreakpointLocation(line=loop_line, column=34),
+ BreakpointLocation(line=loop_line, column=37),
+ BreakpointLocation(line=loop_line, column=39),
+ ]
+ self.assertEqual(breakpoint_locations, expected_locations)
- # Ask for the breakpoint locations for a range of line numbers
- response = self.dap_server.request_breakpointLocations(
- self.main_path,
- line=loop_line,
- end_line=loop_line + 2,
- column=39,
+ # Ask for the breakpoint locations for a range of line numbers.
+ response = session.get_breakpoint_locations(
+ main_path, line=loop_line, column=39, endLine=loop_line + 2
)
self.maxDiff = None
- self.assertTrue(response["success"])
# On some systems, there is an additional breakpoint available
# at loop_line + 1, column 3, i.e. at the end of the loop. To make
# this test more portable, only check that all expected breakpoints
# are presented, but also accept additional breakpoints.
- expected_breakpoints = [
- {"column": 39, "line": loop_line},
- {"column": 51, "line": loop_line},
- {"column": 3, "line": loop_line + 2},
- {"column": 18, "line": loop_line + 2},
+ expected_locations = [
+ BreakpointLocation(line=loop_line, column=39),
+ BreakpointLocation(line=loop_line, column=51),
+ BreakpointLocation(line=loop_line + 2, column=3),
+ BreakpointLocation(line=loop_line + 2, column=18),
]
- for bp in expected_breakpoints:
- self.assertIn(bp, response["body"]["breakpoints"])
+ breakpoint_locations = response.body.breakpoints
+ for bp in expected_locations:
+ self.assertIn(bp, breakpoint_locations)
+
+ session.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
index d633f0b9ffde4..71c7c0cf9097c 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
@@ -2,109 +2,95 @@
Test lldb-dap logpoints feature.
"""
-
-import dap_server
-import shutil
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-import lldbdap_testcase
import os
+from lldbsuite.test.decorators import (
+ skipIfTargetDoesNotSupportSharedLibraries,
+ skipIfWindows,
+)
+from lldbsuite.test.lldbtest import line_number
+from lldbsuite.test.tools.lldb_dap.dap_types import (
+ LaunchArgs,
+ SourceBreakpoint,
+ StoppedEvent,
+)
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.session_helpers import DAPTestSession
+
@skipIfTargetDoesNotSupportSharedLibraries()
-class TestDAP_logpoints(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_logpoints(DAPTestCaseBase):
def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
+ DAPTestCaseBase.setUp(self)
self.main_basename = "main-copy.cpp"
self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
- @skipIfWindows
- def test_logmessage_basic(self):
- """Tests breakpoint logmessage basic functionality."""
+ def stop_at_before_loop_line(self, session: DAPTestSession) -> StoppedEvent:
+ """Launch, set a breakpoint at 'before loop' line and stop there"""
before_loop_line = line_number("main.cpp", "// before loop")
- loop_line = line_number("main.cpp", "// break loop")
- after_loop_line = line_number("main.cpp", "// after loop")
-
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set a breakpoint at a line before loop
- before_loop_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [before_loop_line]
- )
- self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
-
- self.dap_server.request_continue()
+ with session.configure(LaunchArgs(program)) as ctx:
+ [bp] = session.resolve_source_breakpoints(
+ self.main_path, [before_loop_line]
+ )
- # Verify we hit the breakpoint before loop line
- self.verify_breakpoint_hit(before_loop_breakpoint_ids)
+ return session.verify_stopped_on_breakpoint(bp, after=ctx.process_event)
- # Swallow old console output
- self.get_console()
+ @skipIfWindows
+ def test_logMessage_basic(self):
+ """Tests breakpoint logMessage basic functionality."""
+ session = self.build_and_create_session()
+ initial_stop = self.stop_at_before_loop_line(session)
+ source = self.getSourcePath("main.cpp")
+ loop_line = line_number(source, "// break loop")
+ after_loop_line = line_number(source, "// after loop")
# Set two breakpoints:
- # 1. First at the loop line with logMessage
- # 2. Second guard breakpoint at a line after loop
+ # 1. First at the loop line with logMessage.
+ # 2. Second guard breakpoint at a line after loop.
logMessage_prefix = "This is log message for { -- "
logMessage = logMessage_prefix + "{i + 3}, {message}"
- [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
+ [_, post_loop_breakpoint_id] = session.resolve_source_breakpoints(
self.main_path,
- [loop_line, after_loop_line],
- [{"logMessage": logMessage}, {}],
+ [
+ SourceBreakpoint(loop_line, logMessage=logMessage),
+ SourceBreakpoint(after_loop_line),
+ ],
)
- # Continue to trigger the breakpoint with log messages
- self.dap_server.request_continue()
+ # Continue and verify we hit the breakpoint after loop line.
+ post_loop_stop = session.continue_to_breakpoint(post_loop_breakpoint_id)
- # Verify we hit the breakpoint after loop line
- self.verify_breakpoint_hit([post_loop_breakpoint_id])
-
- output = self.get_console()
- lines = output.splitlines()
- logMessage_output = []
- for line in lines:
- if line.startswith(logMessage_prefix):
- logMessage_output.append(line)
-
- # Verify logMessage count
- loop_count = 10
- self.assertEqual(len(logMessage_output), loop_count)
+ captured = session.collect_console(after=initial_stop, until=post_loop_stop)
+ logMessage_output = [
+ line
+ for line in captured.seen_texts.splitlines()
+ if line.startswith(logMessage_prefix)
+ ]
+ # Verify logMessage count.
+ self.assertEqual(len(logMessage_output), 10)
message_addr_pattern = r"\b0x[0-9A-Fa-f]+\b"
message_content = '"Hello from main!"'
- # Verify log message match
+
+ # Verify logMessage match.
for idx, logMessage_line in enumerate(logMessage_output):
result = idx + 3
- reg_str = (
- f"{logMessage_prefix}{result}, {message_addr_pattern} {message_content}"
+ self.assertRegex(
+ logMessage_line,
+ f"{logMessage_prefix}{result}, {message_addr_pattern} {message_content}",
)
- self.assertRegex(logMessage_line, reg_str)
+ session.continue_to_exit()
@skipIfWindows
def test_logmessage_advanced(self):
"""Tests breakpoint logmessage functionality for complex expression."""
- before_loop_line = line_number("main.cpp", "// before loop")
- loop_line = line_number("main.cpp", "// break loop")
- after_loop_line = line_number("main.cpp", "// after loop")
-
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set a breakpoint at a line before loop
- before_loop_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [before_loop_line]
- )
- self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
-
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint before loop line
- self.verify_breakpoint_hit(before_loop_breakpoint_ids)
-
- # Swallow old console output
- self.get_console()
+ session = self.build_and_create_session()
+ initial_stop = self.stop_at_before_loop_line(session)
+ source = self.getSourcePath("main.cpp")
+ before_loop_line = line_number(source, "// break loop")
+ after_loop_line = line_number(source, "// after loop")
# Set two breakpoints:
# 1. First at the loop line with logMessage
@@ -114,91 +100,64 @@ def test_logmessage_advanced(self):
logMessage_prefix
+ "{int y = 0; if (i % 3 == 0) { y = i + 3;} else {y = i * 3;} y}"
)
- [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
+ [_, post_loop_breakpoint_id] = session.resolve_source_breakpoints(
self.main_path,
- [loop_line, after_loop_line],
- [{"logMessage": logMessage}, {}],
+ [
+ SourceBreakpoint(before_loop_line, logMessage=logMessage),
+ SourceBreakpoint(after_loop_line),
+ ],
)
- # Continue to trigger the breakpoint with log messages
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint after loop line
- self.verify_breakpoint_hit([post_loop_breakpoint_id])
-
- output = self.get_console()
- lines = output.splitlines()
- logMessage_output = []
- for line in lines:
- if line.startswith(logMessage_prefix):
- logMessage_output.append(line)
-
- # Verify logMessage count
- loop_count = 10
- self.assertEqual(len(logMessage_output), loop_count)
-
- # Verify log message match
+ post_loop_stop = session.continue_to_breakpoint(post_loop_breakpoint_id)
+ captured = session.collect_console(after=initial_stop, until=post_loop_stop)
+ logMessage_output = [
+ line
+ for line in captured.seen_texts.splitlines()
+ if line.startswith(logMessage_prefix)
+ ]
+ # Verify logMessage count.
+ self.assertEqual(len(logMessage_output), 10)
+
+ # Verify logMessage match.
for idx, logMessage_line in enumerate(logMessage_output):
result = idx + 3 if idx % 3 == 0 else idx * 3
self.assertEqual(logMessage_line, logMessage_prefix + str(result))
@skipIfWindows
def test_logmessage_format(self):
- """
- Tests breakpoint logmessage functionality with format.
- """
- before_loop_line = line_number("main.cpp", "// before loop")
- loop_line = line_number("main.cpp", "// break loop")
- after_loop_line = line_number("main.cpp", "// after loop")
-
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set a breakpoint at a line before loop
- before_loop_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [before_loop_line]
- )
- self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
-
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint before loop line
- self.verify_breakpoint_hit(before_loop_breakpoint_ids)
-
- # Swallow old console output
- self.get_console()
+ """Tests breakpoint logmessage functionality with format."""
+ session = self.build_and_create_session()
+ initial_stop = self.stop_at_before_loop_line(session)
+ source = self.getSourcePath("main.cpp")
+ loop_line = line_number(source, "// break loop")
+ after_loop_line = line_number(source, "// after loop")
# Set two breakpoints:
- # 1. First at the loop line with logMessage
- # 2. Second guard breakpoint at a line after loop
+ # 1. First at the loop line with logMessage.
+ # 2. Second guard breakpoint at a line after loop.
logMessage_prefix = "This is log message for -- "
logMessage_with_format = "part1\tpart2\bpart3\x64part4"
logMessage_with_format_raw = r"part1\tpart2\bpart3\x64part4"
logMessage = logMessage_prefix + logMessage_with_format_raw + "{i - 1}"
- [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
+ [_, post_loop_breakpoint_id] = session.resolve_source_breakpoints(
self.main_path,
- [loop_line, after_loop_line],
- [{"logMessage": logMessage}, {}],
+ [
+ SourceBreakpoint(loop_line, logMessage=logMessage),
+ SourceBreakpoint(after_loop_line),
+ ],
)
- # Continue to trigger the breakpoint with log messages
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint after loop line
- self.verify_breakpoint_hit([post_loop_breakpoint_id])
-
- output = self.get_console()
- lines = output.splitlines()
- logMessage_output = []
- for line in lines:
- if line.startswith(logMessage_prefix):
- logMessage_output.append(line)
-
- # Verify logMessage count
- loop_count = 10
- self.assertEqual(len(logMessage_output), loop_count)
-
- # Verify log message match
+ post_loop_stop = session.continue_to_breakpoint(post_loop_breakpoint_id)
+ captured = session.collect_console(after=initial_stop, until=post_loop_stop)
+ logMessage_output = [
+ line
+ for line in captured.seen_texts.splitlines()
+ if line.startswith(logMessage_prefix)
+ ]
+ # Verify logMessage count.
+ self.assertEqual(len(logMessage_output), 10)
+
+ # Verify logMessage match.
for idx, logMessage_line in enumerate(logMessage_output):
result = idx - 1
self.assertEqual(
@@ -208,64 +167,41 @@ def test_logmessage_format(self):
@skipIfWindows
def test_logmessage_format_failure(self):
- """
- Tests breakpoint logmessage format with parsing failure.
- """
- before_loop_line = line_number("main.cpp", "// before loop")
- loop_line = line_number("main.cpp", "// break loop")
- after_loop_line = line_number("main.cpp", "// after loop")
-
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set a breakpoint at a line before loop
- before_loop_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [before_loop_line]
- )
- self.assertEqual(len(before_loop_breakpoint_ids), 1, "expect one breakpoint")
-
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint before loop line
- self.verify_breakpoint_hit(before_loop_breakpoint_ids)
-
- # Swallow old console output
- self.get_console()
+ """Tests breakpoint logmessage format with parsing failure."""
+ session = self.build_and_create_session()
+ initial_stop = self.stop_at_before_loop_line(session)
+ source = self.getSourcePath("main.cpp")
+ loop_line = line_number(source, "// break loop")
+ after_loop_line = line_number(source, "// after loop")
# Set two breakpoints:
- # 1. First at the loop line with logMessage
- # 2. Second guard breakpoint at a line after loop
+ # 1. First at the loop line with logMessage.
+ # 2. Second guard breakpoint at a line after loop.
logMessage_prefix = "This is log message for -- "
# log message missing hex number.
- logMessage_with_format_raw = r"part1\x"
- logMessage = logMessage_prefix + logMessage_with_format_raw
- [loop_breakpoint_id, post_loop_breakpoint_id] = self.set_source_breakpoints(
+ logMessage = logMessage_prefix + r"part1\x"
+ [loop_breakpoint_id, _] = session.resolve_source_breakpoints(
self.main_path,
- [loop_line, after_loop_line],
- [{"logMessage": logMessage}, {}],
+ [
+ SourceBreakpoint(loop_line, logMessage=logMessage),
+ SourceBreakpoint(after_loop_line),
+ ],
)
- # Continue to trigger the breakpoint with log messages
- self.dap_server.request_continue()
-
- # Verify we hit logpoint breakpoint if it's format has error.
- self.verify_breakpoint_hit([loop_breakpoint_id])
-
- output = self.get_console()
- lines = output.splitlines()
+ # The adapter emits the format error to the console during
+ # setBreakpoints and falls back to a real stop at the loop breakpoint
+ # when execution resumes.
+ loop_stop_event = session.continue_to_breakpoint(loop_breakpoint_id)
+ captured = session.collect_console(after=initial_stop, until=loop_stop_event)
failure_prefix = "Log message has error:"
- logMessage_output = []
- logMessage_failure_output = []
- for line in lines:
- if line.startswith(logMessage_prefix):
- logMessage_output.append(line)
- elif line.startswith(failure_prefix):
- logMessage_failure_output.append(line)
-
- # Verify logMessage failure message
+ logMessage_failure_output = [
+ line.strip()
+ for line in captured.seen_texts.splitlines()
+ if line.startswith(failure_prefix)
+ ]
self.assertEqual(len(logMessage_failure_output), 1)
self.assertEqual(
- logMessage_failure_output[0].strip(),
+ logMessage_failure_output[0],
failure_prefix + " missing hex number following '\\x'",
)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index 2c0b9c5f6e07f..66281576563f3 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -2,26 +2,32 @@
Test lldb-dap setBreakpoints request
"""
-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 shutil
+from typing import Dict
+
+from lldbsuite.test.decorators import skipIfWasm, skipIfWindows
+from lldbsuite.test.lldbtest import line_number
+from lldbsuite.test.tools.lldb_dap.dap_types import (
+ DAPTestGetTargetBreakpointsArgs,
+ LaunchArgs,
+ SetBreakpointsArgs,
+ Source,
+ SourceBreakpoint,
+)
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
@skipIfWasm # inferior built without exception support
-class TestDAP_setBreakpoints(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_setBreakpoints(DAPTestCaseBase):
SHARED_BUILD_TESTCASE = False
def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
+ DAPTestCaseBase.setUp(self)
self.main_basename = "main-copy.cpp"
self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
- @skipIfTargetDoesNotSupportSharedLibraries()
@skipIfWindows
def test_source_map(self):
"""
@@ -30,8 +36,7 @@ def test_source_map(self):
with the corresponding source maps to have breakpoints and frames
working.
"""
- self.build_and_create_debug_adapter()
-
+ session = self.build_and_create_session()
other_basename = "other-copy.c"
other_path = self.getBuildArtifact(other_basename)
@@ -43,7 +48,7 @@ def test_source_map(self):
new_main_path = os.path.join(new_main_folder, self.main_basename)
new_other_path = os.path.join(new_other_folder, other_basename)
- # move the sources
+ # Move the sources.
os.mkdir(new_main_folder)
os.mkdir(new_other_folder)
shutil.move(self.main_path, new_main_path)
@@ -54,57 +59,59 @@ def test_source_map(self):
program = self.getBuildArtifact("a.out")
source_map = [
- [source_folder, new_main_folder],
- [source_folder, new_other_folder],
+ (source_folder, new_main_folder),
+ (source_folder, new_other_folder),
]
- self.launch(program, sourceMap=source_map)
-
- # breakpoint in main.cpp
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=new_main_path), [main_line]
+ with session.configure(LaunchArgs(program, sourceMap=source_map)) as ctx:
+ # Breakpoint in main.cpp.
+ response = session.set_source_breakpoints(new_main_path, [main_line])
+ self.assertEqual(len(response.body.breakpoints), 1)
+ [main_bp] = response.body.breakpoints
+ self.assertEqual(main_bp.line, main_line)
+ self.assertTrue(main_bp.verified)
+ breakpoint_source = self.expect_not_none(main_bp.source)
+ self.assertEqual(self.main_basename, breakpoint_source.name)
+ self.assertEqual(new_main_path, breakpoint_source.path)
+
+ # 2nd breakpoint, which is from a dynamically loaded library.
+ response = session.set_source_breakpoints(new_other_path, [other_line])
+ [other_bp] = response.body.breakpoints
+ self.assertEqual(other_bp.line, other_line)
+ self.assertFalse(other_bp.verified)
+ breakpoint_source = self.expect_not_none(other_bp.source)
+ self.assertEqual(other_basename, breakpoint_source.name)
+ self.assertEqual(new_other_path, breakpoint_source.path)
+ other_bp_id = self.expect_not_none(other_bp.id)
+
+ stop_event = session.verify_stopped_on_breakpoint(
+ other_bp_id, after=ctx.process_event
)
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 1)
- breakpoint = breakpoints[0]
- self.assertEqual(breakpoint["line"], main_line)
- self.assertTrue(breakpoint["verified"])
- self.assertEqual(self.main_basename, breakpoint["source"]["name"])
- self.assertEqual(new_main_path, breakpoint["source"]["path"])
-
- # 2nd breakpoint, which is from a dynamically loaded library
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=new_other_path), [other_line]
- )
- breakpoints = response["body"]["breakpoints"]
- breakpoint = breakpoints[0]
- self.assertEqual(breakpoint["line"], other_line)
- self.assertFalse(breakpoint["verified"])
- self.assertEqual(other_basename, breakpoint["source"]["name"])
- self.assertEqual(new_other_path, breakpoint["source"]["path"])
- other_breakpoint_id = breakpoint["id"]
-
- self.dap_server.request_continue()
- self.verify_breakpoint_hit([other_breakpoint_id])
-
- # 2nd breakpoint again, which should be valid at this point
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=new_other_path), [other_line]
- )
- breakpoints = response["body"]["breakpoints"]
- breakpoint = breakpoints[0]
- self.assertEqual(breakpoint["line"], other_line)
- self.assertTrue(breakpoint["verified"])
- self.assertEqual(other_basename, breakpoint["source"]["name"])
- self.assertEqual(new_other_path, breakpoint["source"]["path"])
- # now we check the stack trace making sure that we got mapped source paths
- frames = self.dap_server.request_stackTrace()["body"]["stackFrames"]
+ # 2nd breakpoint again, which should be valid at this point.
+ response = session.set_source_breakpoints(new_other_path, [other_line])
+ [other_bp] = response.body.breakpoints
+ self.assertEqual(other_bp.line, other_line)
+ self.assertTrue(other_bp.verified)
+ breakpoint_source = self.expect_not_none(other_bp.source)
+ self.assertEqual(other_basename, breakpoint_source.name)
+ self.assertEqual(new_other_path, breakpoint_source.path)
+
+ # Now we check the stack trace making sure that we got mapped source paths.
+ frame_ctxs = session.thread_context_from(stop_event).frames()
+ frames = [ctx.frame for ctx in frame_ctxs]
+
+ frame0_source = self.expect_not_none(frames[0].source)
+ self.assertEqual(frame0_source.name, other_basename)
+ self.assertEqual(frame0_source.path, new_other_path)
- self.assertEqual(frames[0]["source"]["name"], other_basename)
- self.assertEqual(frames[0]["source"]["path"], new_other_path)
+ frame1_source = self.expect_not_none(frames[1].source)
+ self.assertEqual(frame1_source.name, self.main_basename)
+ self.assertEqual(frame1_source.path, new_main_path)
- self.assertEqual(frames[1]["source"]["name"], self.main_basename)
- self.assertEqual(frames[1]["source"]["path"], new_main_path)
+ # Clear all breakpoints.
+ session.set_source_breakpoints(new_main_path, [])
+ session.set_source_breakpoints(new_other_path, [])
+ session.continue_to_exit()
@skipIfWindows
def test_set_and_clear(self):
@@ -129,25 +136,25 @@ def test_set_and_clear(self):
# without launching or attaching to a process, so we must start a
# process in order to be able to set breakpoints.
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ session = self.build_and_create_session()
+ session.initialize_and_launch(LaunchArgs(program))
- # Set 3 breakpoints and verify that they got set correctly
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
- )
- line_to_id = {}
- breakpoints = response["body"]["breakpoints"]
+ # Set 3 breakpoints and verify that they got set correctly.
+ response = session.set_source_breakpoints(self.main_path, lines)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(lines),
- "expect %u source breakpoints" % (len(lines)),
+ f"expect {len(lines)} source breakpoints",
)
+ line_to_id: Dict[int, int] = {}
for index, breakpoint in enumerate(breakpoints):
- line = breakpoint["line"]
+ line = self.expect_not_none(breakpoint.line)
self.assertEqual(line, lines[index])
- # Store the "id" of the breakpoint that was set for later
- line_to_id[line] = breakpoint["id"]
- self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
+ # Store the "id" of the breakpoint that was set for later.
+ breakpoint_id = self.expect_not_none(breakpoint.id)
+ line_to_id[line] = breakpoint_id
+ self.assertTrue(breakpoint.verified, "expect breakpoint verified")
# There is no breakpoint delete packet, clients just send another
# setBreakpoints packet with the same source file with fewer lines.
@@ -159,110 +166,96 @@ def test_set_and_clear(self):
lines.remove(second_line)
# Set 2 breakpoints and verify that the previous breakpoints that were
# set above are still set.
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
- )
- breakpoints = response["body"]["breakpoints"]
+ response = session.set_source_breakpoints(self.main_path, lines)
+ breakpoints = response.body.breakpoints
self.assertEqual(
- len(breakpoints),
- len(lines),
- "expect %u source breakpoints" % (len(lines)),
+ len(breakpoints), len(lines), f"expect {len(lines)} source breakpoints"
)
- for index, breakpoint in enumerate(breakpoints):
- line = breakpoint["line"]
- self.assertEqual(line, lines[index])
+ for expected_line, breakpoint in zip(lines, breakpoints):
+ line = self.expect_not_none(breakpoint.line)
+ self.assertEqual(line, expected_line)
# Verify the same breakpoints are still set within LLDB by
- # making sure the breakpoint ID didn't change
+ # making sure the breakpoint ID didn't change.
self.assertEqual(
line_to_id[line],
- breakpoint["id"],
+ breakpoint.id,
"verify previous breakpoints stayed the same",
)
- self.assertTrue(breakpoint["verified"], "expect breakpoint still verified")
+ self.assertTrue(breakpoint.verified, "expect breakpoint still verified")
# Now get the full list of breakpoints set in the target and verify
# we have only 2 breakpoints set. The response above could have told
# us about 2 breakpoints, but we want to make sure we don't have the
# third one still set in the target
- response = self.dap_server.request_testGetTargetBreakpoints()
- breakpoints = response["body"]["breakpoints"]
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(lines),
- "expect %u source breakpoints" % (len(lines)),
+ f"expect {len(lines)} source breakpoints",
)
for breakpoint in breakpoints:
- line = breakpoint["line"]
+ line = self.expect_not_none(breakpoint.line)
# Verify the same breakpoints are still set within LLDB by
# making sure the breakpoint ID didn't change
self.assertEqual(
line_to_id[line],
- breakpoint["id"],
+ breakpoint.id,
"verify previous breakpoints stayed the same",
)
self.assertIn(line, lines, "line expected in lines array")
- self.assertTrue(breakpoint["verified"], "expect breakpoint still verified")
+ self.assertTrue(breakpoint.verified, "expect breakpoint still verified")
# Now clear all breakpoints for the source file by passing down an
- # empty lines array
+ # empty lines array.
lines = []
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
- )
- breakpoints = response["body"]["breakpoints"]
+ response = session.set_source_breakpoints(self.main_path, lines)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(lines),
- "expect %u source breakpoints" % (len(lines)),
+ f"expect {len(lines)} source breakpoints",
)
# Verify with the target that all breakpoints have been cleared
- response = self.dap_server.request_testGetTargetBreakpoints()
- breakpoints = response["body"]["breakpoints"]
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(lines),
- "expect %u source breakpoints" % (len(lines)),
+ f"expect {len(lines)} source breakpoints",
)
# Now set a breakpoint again in the same source file and verify it
# was added.
lines = [second_line]
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
+ response = session.set_source_breakpoints(self.main_path, lines)
+ breakpoints = response.body.breakpoints
+ self.assertEqual(
+ len(breakpoints),
+ len(lines),
+ f"expect {len(lines)} source breakpoints",
)
- if response:
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(
- len(breakpoints),
- len(lines),
- "expect %u source breakpoints" % (len(lines)),
- )
- for breakpoint in breakpoints:
- line = breakpoint["line"]
- self.assertIn(line, lines, "line expected in lines array")
- self.assertTrue(
- breakpoint["verified"], "expect breakpoint still verified"
- )
+ for breakpoint in breakpoints:
+ line = self.expect_not_none(breakpoint.line)
+ self.assertIn(line, lines, "line expected in lines array")
+ self.assertTrue(breakpoint.verified, "expect breakpoint still verified")
# Now get the full list of breakpoints set in the target and verify
# we have only 2 breakpoints set. The response above could have told
# us about 2 breakpoints, but we want to make sure we don't have the
- # third one still set in the target
- response = self.dap_server.request_testGetTargetBreakpoints()
- if response:
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(
- len(breakpoints),
- len(lines),
- "expect %u source breakpoints" % (len(lines)),
- )
- for breakpoint in breakpoints:
- line = breakpoint["line"]
- self.assertIn(line, lines, "line expected in lines array")
- self.assertTrue(
- breakpoint["verified"], "expect breakpoint still verified"
- )
+ # third one still set in the target.
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
+ self.assertEqual(
+ len(breakpoints),
+ len(lines),
+ f"expect {len(lines)} source breakpoints",
+ )
+ for breakpoint in breakpoints:
+ line = self.expect_not_none(breakpoint.line)
+ self.assertIn(line, lines, "line expected in lines array")
+ self.assertTrue(breakpoint.verified, "expect breakpoint still verified")
@skipIfWindows
def test_clear_breakpoints_unset_breakpoints(self):
@@ -278,37 +271,33 @@ def test_clear_breakpoints_unset_breakpoints(self):
# without launching or attaching to a process, so we must start a
# process in order to be able to set breakpoints.
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set one breakpoint and verify that it got set correctly.
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
- )
- line_to_id = {}
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(
- len(breakpoints), len(lines), "expect %u source breakpoints" % (len(lines))
- )
- for index, breakpoint in enumerate(breakpoints):
- line = breakpoint["line"]
- self.assertEqual(line, lines[index])
- # Store the "id" of the breakpoint that was set for later
- line_to_id[line] = breakpoint["id"]
- self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
-
- # Now clear all breakpoints for the source file by not setting the
- # lines array.
- lines = None
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path), lines
- )
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 0, "expect no source breakpoints")
-
- # Verify with the target that all breakpoints have been cleared.
- response = self.dap_server.request_testGetTargetBreakpoints()
- breakpoints = response["body"]["breakpoints"]
- self.assertEqual(len(breakpoints), 0, "expect no source breakpoints")
+ session = self.build_and_create_session()
+ with session.configure(LaunchArgs(program)):
+ # Set one breakpoint and verify that it got set correctly.
+ response = session.set_source_breakpoints(self.main_path, lines)
+ breakpoints = response.body.breakpoints
+ self.assertEqual(
+ len(breakpoints), len(lines), f"expect {len(lines)} source breakpoints"
+ )
+ for expected_line, breakpoint in zip(lines, breakpoints):
+ line = self.expect_not_none(breakpoint.line)
+ self.assertEqual(line, expected_line)
+ self.expect_not_none(breakpoint.id)
+ self.assertTrue(breakpoint.verified, "expect breakpoint verified")
+
+ # Now clear all breakpoints for the source file by not setting the
+ # lines or breakpoints array.
+ set_bp_args = SetBreakpointsArgs(Source.create(path=self.main_path))
+ response = session.send_request(set_bp_args).result()
+ breakpoints = response.body.breakpoints
+ self.assertEqual(len(breakpoints), 0, "expect no source breakpoints")
+
+ # Verify with the target that all breakpoints have been cleared.
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
+ self.assertEqual(len(breakpoints), 0, "expect no source breakpoints")
+
+ session.verify_process_exited()
@skipIfWindows
def test_functionality(self):
@@ -317,122 +306,136 @@ def test_functionality(self):
loop_line = line_number("main.cpp", "// break loop")
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- # Set a breakpoint at the loop line with no condition and no
- # hitCondition
- breakpoint_ids = self.set_source_breakpoints(self.main_path, [loop_line])
- self.assertEqual(len(breakpoint_ids), 1, "expect one breakpoint")
- self.dap_server.request_continue()
-
- # Verify we hit the breakpoint we just set
- self.verify_breakpoint_hit(breakpoint_ids)
-
- # Make sure i is zero at first breakpoint
- i = int(self.dap_server.get_local_variable_value("i"))
- self.assertEqual(i, 0, "i != 0 after hitting breakpoint")
-
- # Update the condition on our breakpoint
- new_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [loop_line], [{"condition": "i==4"}]
+
+ session = self.build_and_create_session()
+ with session.configure(LaunchArgs(program)) as ctx:
+ # Set a breakpoint at the loop line with no condition and no
+ # hitCondition.
+ [loop_bp] = session.resolve_source_breakpoints(self.main_path, [loop_line])
+ process_event = ctx.process_event
+
+ # Verify we hit the breakpoint we just set.
+ stop_event = session.verify_stopped_on_breakpoint(loop_bp, after=process_event)
+
+ # Make sure i is zero at first breakpoint.
+ thread_ctx = session.thread_context_from(stop_event)
+ i_var = thread_ctx.top_frame().locals["i"]
+ self.assertEqual(i_var.value_as_int, 0, "i != 0 after hitting breakpoint")
+
+ # Update the condition on our breakpoint.
+ [condition_bp] = session.resolve_source_breakpoints(
+ self.main_path, [SourceBreakpoint(loop_line, condition="i==4")]
)
self.assertEqual(
- breakpoint_ids,
- new_breakpoint_ids,
- "existing breakpoint should have its condition " "updated",
+ loop_bp,
+ condition_bp,
+ "existing breakpoint should have its condition updated",
)
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
- self.assertEqual(i, 4, "i != 4 showing conditional works")
+ stop_event = session.continue_to_breakpoint(loop_bp)
+ thread_ctx = session.thread_context_from(stop_event)
+ i_var = thread_ctx.top_frame().locals["i"]
+ self.assertEqual(i_var.value_as_int, 4, "i != 4 showing conditional works")
- new_breakpoint_ids = self.set_source_breakpoints(
- self.main_path, [loop_line], [{"hitCondition": "2"}]
+ # Update the hitCondition on our breakpoint.
+ [hit_condition_bp] = session.resolve_source_breakpoints(
+ self.main_path, [SourceBreakpoint(loop_line, hitCondition="2")]
)
-
self.assertEqual(
- breakpoint_ids,
- new_breakpoint_ids,
- "existing breakpoint should have its condition " "updated",
+ loop_bp,
+ hit_condition_bp,
+ "existing breakpoint should have its condition updated",
)
- # Continue with a hitCondition of 2 and expect it to skip 1 value
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
- self.assertEqual(i, 6, "i != 6 showing hitCondition works")
+ # Continue with a hitCondition of 2 and expect it to skip 1 value.
+ stop_event = session.continue_to_breakpoint(loop_bp)
+ i_var = thread_ctx.top_frame().locals["i"]
+ self.assertEqual(i_var.value_as_int, 6, "i != 6 showing hitCondition works")
- # continue after hitting our hitCondition and make sure it only goes
- # up by 1
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
- self.assertEqual(i, 7, "i != 7 showing post hitCondition hits every time")
+ # Continue after hitting our hitCondition and make sure it only goes
+ # up by 1.
+ stop_event = session.continue_to_breakpoint(loop_bp)
+ i_var = thread_ctx.top_frame().locals["i"]
+ self.assertEqual(
+ i_var.value_as_int, 7, "i != 7 showing post hitCondition hits every time"
+ )
+
+ # Clear breakpoints and exit.
+ session.set_source_breakpoints(self.main_path, [])
+ session.continue_to_exit()
@skipIfWindows
def test_column_breakpoints(self):
"""Test setting multiple breakpoints in the same line at different columns."""
+ session = self.build_and_create_session()
loop_line = line_number("main.cpp", "// break loop")
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
-
- # Set two breakpoints on the loop line at different columns.
- columns = [13, 39]
- response = self.dap_server.request_setBreakpoints(
- Source.build(path=self.main_path),
- [loop_line, loop_line],
- list({"column": c} for c in columns),
- )
-
- # Verify the breakpoints were set correctly
- breakpoints = response["body"]["breakpoints"]
- breakpoint_ids = []
- self.assertEqual(
- len(breakpoints),
- len(columns),
- "expect %u source breakpoints" % (len(columns)),
- )
- for index, breakpoint in enumerate(breakpoints):
- self.assertEqual(breakpoint["line"], loop_line)
- self.assertEqual(breakpoint["column"], columns[index])
- self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
- breakpoint_ids.append(breakpoint["id"])
+ with session.configure(LaunchArgs(program)):
+ # Set two breakpoints on the loop line at different columns.
+ columns = [13, 39]
+ source_bps = [
+ SourceBreakpoint(line=loop_line, column=column) for column in columns
+ ]
+ response = session.set_source_breakpoints(self.main_path, source_bps)
+
+ # Verify the breakpoints were set correctly.
+ breakpoints = response.body.breakpoints
+ self.assertEqual(
+ len(breakpoints),
+ len(columns),
+ f"expect {len(columns)} source breakpoints",
+ )
+ breakpoint_ids: list[int] = []
+ for column, breakpoint in zip(columns, breakpoints):
+ self.assertEqual(breakpoint.line, loop_line)
+ self.assertEqual(breakpoint.column, column)
+ self.assertTrue(breakpoint.verified, "expect breakpoint verified")
+ breakpoint_id = self.expect_not_none(breakpoint.id)
+ breakpoint_ids.append(breakpoint_id)
# Continue to the first breakpoint,
- self.continue_to_breakpoints([breakpoint_ids[0]])
+ stop_event = session.verify_stopped_on_breakpoint(
+ breakpoint_ids[0], after=response
+ )
# We should have stopped right before the call to `twelve`.
# Step into and check we are inside `twelve`.
- self.stepIn()
- func_name = self.get_stackFrames()[0]["name"]
+ thread_ctx = session.thread_context_from(stop_event)
+ thread_ctx.step_in()
+ func_name = thread_ctx.top_frame().name
self.assertEqual(func_name, "twelve(int)")
# Continue to the second breakpoint.
- self.continue_to_breakpoints([breakpoint_ids[1]])
+ stop_event = session.continue_to_breakpoint(breakpoint_ids[1])
# We should have stopped right before the call to `fourteen`.
# Step into and check we are inside `fourteen`.
- self.stepIn()
- func_name = self.get_stackFrames()[0]["name"]
+ thread_ctx.step_in()
+ func_name = thread_ctx.top_frame().name
self.assertEqual(func_name, "a::fourteen(int)")
+ session.set_source_breakpoints(self.main_path, [])
+ session.continue_to_exit()
+
@skipIfWindows
def test_hit_multiple_breakpoints(self):
"""Test that if we hit multiple breakpoints at the same address, they
all appear in the stop reason."""
+ session = self.build_and_create_session()
breakpoint_lines = [
line_number("main.cpp", "// break non-breakpointable line"),
line_number("main.cpp", "// before loop"),
]
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ with session.configure(LaunchArgs(program)) as ctx:
+ # Set a pair of breakpoints that will both resolve to the same address.
+ breakpoint_ids = session.resolve_source_breakpoints(
+ self.main_path, breakpoint_lines
+ )
- # Set a pair of breakpoints that will both resolve to the same address.
- breakpoint_ids = [
- int(bp_id)
- for bp_id in self.set_source_breakpoints(self.main_path, breakpoint_lines)
- ]
- self.assertEqual(len(breakpoint_ids), 2, "expected two breakpoints")
- self.dap_server.request_continue()
- print(breakpoint_ids)
- # Verify we hit both of the breakpoints we just set
- self.verify_all_breakpoints_hit(breakpoint_ids)
+ # Verify we hit both of the breakpoints we just set.
+ session.verify_multiple_breakpoints_hit(breakpoint_ids, after=ctx.process_event)
+
+ session.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
index aec028b44e29a..aa28f7f8096de 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
@@ -2,13 +2,17 @@
Test lldb-dap setExceptionBreakpoints request
"""
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+
+from lldbsuite.test.decorators import (
+ skipIfTargetDoesNotSupportSharedLibraries,
+ skipIfWindows,
+)
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
@skipIfTargetDoesNotSupportSharedLibraries()
-class TestDAP_setExceptionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_setExceptionBreakpoints(DAPTestCaseBase):
@skipIfWindows
def test_functionality(self):
"""Tests setting and clearing exception breakpoints.
@@ -28,17 +32,22 @@ def test_functionality(self):
# without launching or attaching to a process, so we must start a
# process in order to be able to set breakpoints.
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
+ session = self.build_and_create_session()
- response = self.dap_server.request_setExceptionBreakpoints(
- filters=["cpp_throw", "cpp_catch"],
- )
- if response:
- self.assertTrue(response["success"])
+ with session.configure(LaunchArgs(program)) as ctx:
+ response = session.set_exception_breakpoints(
+ filters=["cpp_throw", "cpp_catch"]
+ )
+ breakpoints = self.expect_not_none(response.body.breakpoints)
+ for bp in breakpoints:
+ self.assertTrue(bp.verified, True)
- self.continue_to_exception_breakpoint(
- expected_description=r"breakpoint 1\.1", expected_text=r"C\+\+ Throw"
+ session.verify_stopped_on_exception(
+ expected_description=r"breakpoint 1\.1",
+ expected_text=r"C\+\+ Throw",
+ after=ctx.process_event,
)
- self.continue_to_exception_breakpoint(
+ session.continue_to_exception_breakpoint(
expected_description=r"breakpoint 2\.1", expected_text=r"C\+\+ Catch"
)
+ session.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
index d99f18ccb2000..f121b80648228 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
@@ -1,17 +1,21 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap setFunctionBreakpoints request
"""
-
-import dap_server
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-import lldbdap_testcase
+from lldbsuite.test.decorators import (
+ skipIfTargetDoesNotSupportSharedLibraries,
+ skipIfWindows,
+)
+from lldbsuite.test.tools.lldb_dap.dap_types import (
+ DAPTestGetTargetBreakpointsArgs,
+ FunctionBreakpoint,
+ LaunchArgs,
+)
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
@skipIfTargetDoesNotSupportSharedLibraries()
-class TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_setFunctionBreakpoints(DAPTestCaseBase):
@skipIfWindows
def test_set_and_clear(self):
"""Tests setting and clearing function breakpoints.
@@ -29,145 +33,134 @@ def test_set_and_clear(self):
# Visual Studio Code Debug Adapters have no way to specify the file
# without launching or attaching to a process, so we must start a
# process in order to be able to set breakpoints.
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- bp_id_12 = None
- functions = ["twelve"]
- # Set a function breakpoint at 'twelve'
- response = self.dap_server.request_setFunctionBreakpoints(functions)
- if response:
- breakpoints = response["body"]["breakpoints"]
+ session = self.build_and_create_session()
+ with session.configure(LaunchArgs(self.getBuildArtifact("a.out"))):
+ functions = ["twelve"]
+ # Set a function breakpoint at 'twelve'.
+ response = session.set_function_breakpoints(functions)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
- for breakpoint in breakpoints:
- bp_id_12 = breakpoint["id"]
- self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
-
- # Add an extra name and make sure we have two breakpoints after this
- functions.append("thirteen")
- response = self.dap_server.request_setFunctionBreakpoints(functions)
- if response:
- breakpoints = response["body"]["breakpoints"]
+ bp_id_12 = self.expect_not_none(breakpoints[0].id)
+ self.assertTrue(breakpoints[0].verified, "expect breakpoint verified")
+
+ # Add an extra name and make sure we have two breakpoints after this.
+ functions.append("thirteen")
+ response = session.set_function_breakpoints(functions)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
- for breakpoint in breakpoints:
- self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
-
- # There is no breakpoint delete packet, clients just send another
- # setFunctionBreakpoints packet with the different function names.
- functions.remove("thirteen")
- response = self.dap_server.request_setFunctionBreakpoints(functions)
- if response:
- breakpoints = response["body"]["breakpoints"]
+ for bp in breakpoints:
+ self.assertTrue(bp.verified, "expect breakpoint verified")
+
+ # There is no breakpoint delete packet, clients just send another
+ # setFunctionBreakpoints packet with the different function names.
+ functions.remove("thirteen")
+ response = session.set_function_breakpoints(functions)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
- for breakpoint in breakpoints:
- bp_id = breakpoint["id"]
+ for bp in breakpoints:
self.assertEqual(
- bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same'
- )
- self.assertTrue(
- breakpoint["verified"], "expect breakpoint still verified"
+ bp.id, bp_id_12, 'verify "twelve" breakpoint ID is same'
)
-
- # Now get the full list of breakpoints set in the target and verify
- # we have only 1 breakpoints set. The response above could have told
- # us about 1 breakpoints, but we want to make sure we don't have the
- # second one still set in the target
- response = self.dap_server.request_testGetTargetBreakpoints()
- if response:
- breakpoints = response["body"]["breakpoints"]
+ self.assertTrue(bp.verified, "expect breakpoint still verified")
+
+ # Now get the full list of breakpoints set in the target and verify
+ # we have only 1 breakpoints set. The response above could have told
+ # us about 1 breakpoints, but we want to make sure we don't have the
+ # second one still set in the target.
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
- for breakpoint in breakpoints:
- bp_id = breakpoint["id"]
+ for bp in breakpoints:
self.assertEqual(
- bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same'
- )
- self.assertTrue(
- breakpoint["verified"], "expect breakpoint still verified"
+ bp.id, bp_id_12, 'verify "twelve" breakpoint ID is same'
)
+ self.assertTrue(bp.verified, "expect breakpoint still verified")
- # Now clear all breakpoints for the source file by passing down an
- # empty lines array
- functions = []
- response = self.dap_server.request_setFunctionBreakpoints(functions)
- if response:
- breakpoints = response["body"]["breakpoints"]
+ # Now clear all breakpoints for the source file by passing down an
+ # empty lines array.
+ functions = []
+ response = session.set_function_breakpoints(functions)
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
- # Verify with the target that all breakpoints have been cleared
- response = self.dap_server.request_testGetTargetBreakpoints()
- if response:
- breakpoints = response["body"]["breakpoints"]
+ # Verify with the target that all breakpoints have been cleared.
+ response = session.send_request(DAPTestGetTargetBreakpointsArgs()).result()
+ breakpoints = response.body.breakpoints
self.assertEqual(
len(breakpoints),
len(functions),
- "expect %u source breakpoints" % (len(functions)),
+ f"expect {len(functions)} source breakpoints",
)
@skipIfWindows
def test_functionality(self):
"""Tests hitting breakpoints and the functionality of a single
breakpoint, like 'conditions' and 'hitCondition' settings."""
-
+ session = self.build_and_create_session()
program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- # Set a breakpoint on "twelve" with no condition and no hitCondition
- functions = ["twelve"]
- breakpoint_ids = self.set_function_breakpoints(functions)
- self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
+ # Set a breakpoint on "twelve" with no condition and no hitCondition.
+ with session.configure(LaunchArgs(program)) as ctx:
+ [bp_id] = session.resolve_function_breakpoints(["twelve"])
- # Verify we hit the breakpoint we just set
- self.continue_to_breakpoints(breakpoint_ids)
+ # Verify we hit the breakpoint we just set.
+ stop_event = session.verify_stopped_on_breakpoint(
+ bp_id, after=ctx.process_event
+ )
- # Make sure i is zero at first breakpoint
- i = int(self.dap_server.get_local_variable_value("i"))
+ # Make sure i is zero at first breakpoint.
+ thread_ctx = session.thread_context_from(stop_event)
+ i = thread_ctx.top_frame().locals["i"].value_as_int
self.assertEqual(i, 0, "i != 0 after hitting breakpoint")
- # Update the condition on our breakpoint
- new_breakpoint_ids = self.set_function_breakpoints(functions, condition="i==4")
+ # Update the condition on our breakpoint.
+ func_bp = FunctionBreakpoint(name="twelve", condition="i==4")
+ [condition_bp_id] = session.resolve_function_breakpoints([func_bp])
self.assertEqual(
- breakpoint_ids,
- new_breakpoint_ids,
- "existing breakpoint should have its condition " "updated",
+ bp_id,
+ condition_bp_id,
+ "existing breakpoint should have its condition updated",
)
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
+ session.continue_to_breakpoint(bp_id)
+ i = thread_ctx.top_frame().locals["i"].value_as_int
self.assertEqual(i, 4, "i != 4 showing conditional works")
- new_breakpoint_ids = self.set_function_breakpoints(functions, hitCondition="2")
+ func_bp = FunctionBreakpoint(name="twelve", hitCondition="2")
+ [hit_condition_bp_id] = session.resolve_function_breakpoints([func_bp])
self.assertEqual(
- breakpoint_ids,
- new_breakpoint_ids,
- "existing breakpoint should have its condition " "updated",
+ bp_id,
+ hit_condition_bp_id,
+ "existing breakpoint should have its condition updated",
)
- # Continue with a hitCondition of 2 and expect it to skip 1 value
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
+ # Continue with a hitCondition of 2 and expect it to skip 1 value.
+ session.continue_to_breakpoint(bp_id)
+ i = thread_ctx.top_frame().locals["i"].value_as_int
self.assertEqual(i, 6, "i != 6 showing hitCondition works")
- # continue after hitting our hitCondition and make sure it only goes
- # up by 1
- self.continue_to_breakpoints(breakpoint_ids)
- i = int(self.dap_server.get_local_variable_value("i"))
+ # Continue after hitting our hitCondition and make sure it only goes
+ # up by 1.
+ session.continue_to_breakpoint(bp_id)
+ i = thread_ctx.top_frame().locals["i"].value_as_int
self.assertEqual(i, 7, "i != 7 showing post hitCondition hits every time")
>From 9cb5526373d9ea481bd3901af369b938bec0cacd Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 8 Jul 2026 09:33:12 +0100
Subject: [PATCH 2/3] add missing decorator
---
.../tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index 66281576563f3..d54f16a86dbd6 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -6,7 +6,11 @@
import shutil
from typing import Dict
-from lldbsuite.test.decorators import skipIfWasm, skipIfWindows
+from lldbsuite.test.decorators import (
+ skipIfTargetDoesNotSupportSharedLibraries,
+ skipIfWasm,
+ skipIfWindows,
+)
from lldbsuite.test.lldbtest import line_number
from lldbsuite.test.tools.lldb_dap.dap_types import (
DAPTestGetTargetBreakpointsArgs,
@@ -28,6 +32,7 @@ def setUp(self):
self.main_basename = "main-copy.cpp"
self.main_path = os.path.realpath(self.getBuildArtifact(self.main_basename))
+ @skipIfTargetDoesNotSupportSharedLibraries()
@skipIfWindows
def test_source_map(self):
"""
>From 2d15ae05ccb7781d8f1bafccd304f1ed7a40e0bd Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 14 Jul 2026 22:48:50 +0100
Subject: [PATCH 3/3] update imports
---
.../tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py | 4 ++--
lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py | 5 ++---
.../API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py | 4 ++--
.../lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py | 5 ++---
.../lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py | 4 ++--
5 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
index f97b4b403b063..a9c5a801c1f92 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py
@@ -9,8 +9,8 @@
skipIfWindows,
)
from lldbsuite.test.lldbtest import line_number
-from lldbsuite.test.tools.lldb_dap.dap_types import BreakpointLocation, LaunchArgs
-from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.types import BreakpointLocation, LaunchArgs
@skipIfTargetDoesNotSupportSharedLibraries()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
index 71c7c0cf9097c..2135f179cc622 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_logpoints.py
@@ -9,13 +9,12 @@
skipIfWindows,
)
from lldbsuite.test.lldbtest import line_number
-from lldbsuite.test.tools.lldb_dap.dap_types import (
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase, DAPTestSession
+from lldbsuite.test.tools.lldb_dap.types import (
LaunchArgs,
SourceBreakpoint,
StoppedEvent,
)
-from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
-from lldbsuite.test.tools.lldb_dap.session_helpers import DAPTestSession
@skipIfTargetDoesNotSupportSharedLibraries()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
index d54f16a86dbd6..94c69436bd9b5 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py
@@ -12,14 +12,14 @@
skipIfWindows,
)
from lldbsuite.test.lldbtest import line_number
-from lldbsuite.test.tools.lldb_dap.dap_types import (
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.types import (
DAPTestGetTargetBreakpointsArgs,
LaunchArgs,
SetBreakpointsArgs,
Source,
SourceBreakpoint,
)
-from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
@skipIfWasm # inferior built without exception support
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
index aa28f7f8096de..0b1b8a6b5a541 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setExceptionBreakpoints.py
@@ -2,13 +2,12 @@
Test lldb-dap setExceptionBreakpoints request
"""
-
from lldbsuite.test.decorators import (
skipIfTargetDoesNotSupportSharedLibraries,
skipIfWindows,
)
-from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
-from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.types import LaunchArgs
@skipIfTargetDoesNotSupportSharedLibraries()
diff --git a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
index f121b80648228..1572cab8d852e 100644
--- a/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
+++ b/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py
@@ -6,12 +6,12 @@
skipIfTargetDoesNotSupportSharedLibraries,
skipIfWindows,
)
-from lldbsuite.test.tools.lldb_dap.dap_types import (
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+from lldbsuite.test.tools.lldb_dap.types import (
DAPTestGetTargetBreakpointsArgs,
FunctionBreakpoint,
LaunchArgs,
)
-from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
@skipIfTargetDoesNotSupportSharedLibraries()
More information about the lldb-commits
mailing list