https://github.com/da-viper updated 
https://github.com/llvm/llvm-project/pull/207029

>From a38f3b96f47a7e674f89e5bec2862248a0f6b063 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Wed, 1 Jul 2026 17:35:20 +0100
Subject: [PATCH 1/3] [lldb-dap] Migrate DAP exceptions test.

Migrate all the tests in the `lldb-dap/exception` folder.
---
 .../lldb-dap/exception/TestDAP_exception.py   | 27 +++---
 .../lldb-dap/exception/asan/TestDAP_asan.py   | 28 +++---
 .../exception/cpp/TestDAP_exception_cpp.py    | 33 ++++---
 .../exception/objc/TestDAP_exception_objc.py  | 89 +++++++++++--------
 .../lldb-dap/exception/ubsan/TestDAP_ubsan.py | 31 ++++---
 5 files changed, 123 insertions(+), 85 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/exception/TestDAP_exception.py 
b/lldb/test/API/tools/lldb-dap/exception/TestDAP_exception.py
index 15b8956995432..c1657853e8c94 100644
--- a/lldb/test/API/tools/lldb-dap/exception/TestDAP_exception.py
+++ b/lldb/test/API/tools/lldb-dap/exception/TestDAP_exception.py
@@ -2,24 +2,29 @@
 Test exception behavior in DAP with signal.
 """
 
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfNoSignals
+from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
 
 
 @skipIfNoSignals
-class TestDAP_exception(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_exception(lldb_dap_testcase.DAPTestCaseBase):
     def test_stopped_description(self):
         """
         Test that exception description is shown correctly in stopped
         event.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
-        self.do_continue()
+        session = self.build_and_create_session()
+        process_event = session.launch(LaunchArgs(program=program))
 
-        self.verify_stop_exception_info("signal SIGABRT")
-        exceptionInfo = self.get_exceptionInfo()
-        self.assertEqual(exceptionInfo["breakMode"], "always")
-        self.assertEqual(exceptionInfo["description"], "signal SIGABRT")
-        self.assertEqual(exceptionInfo["exceptionId"], "signal")
+        stopped_event = session.verify_stopped_on_exception(
+            expected_description="signal SIGABRT", after=process_event
+        )
+        thread_id = self.expect_not_none(stopped_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+
+        self.assertEqual(exception_info.breakMode, "always")
+        description = self.expect_not_none(exception_info.description)
+        self.assertEqual(description, "signal SIGABRT")
+        self.assertEqual(exception_info.exceptionId, "signal")
diff --git a/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py 
b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
index 0ce315d6e01b7..7a91c2d88f413 100644
--- a/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
+++ b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
@@ -2,25 +2,27 @@
 Test that we stop at runtime instrumentation locations (asan).
 """
 
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipUnlessAddressSanitizer
+from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
 
 
-class TestDAP_asan(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_asan(lldb_dap_testcase.DAPTestCaseBase):
     @skipUnlessAddressSanitizer
     def test_asan(self):
         """
         Test that we stop at asan.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
-        self.do_continue()
-
-        self.verify_stop_exception_info("Use of deallocated memory")
-        exceptionInfo = self.get_exceptionInfo()
-        self.assertEqual(exceptionInfo["breakMode"], "always")
-        self.assertRegex(
-            exceptionInfo["description"], r"fatal_error: heap-use-after-free"
+        session = self.build_and_create_session()
+        process_event = session.launch(LaunchArgs(program))
+        stop_event = session.verify_stopped_on_exception(
+            after=process_event, expected_description="Use of deallocated 
memory"
         )
-        self.assertEqual(exceptionInfo["exceptionId"], 
"runtime-instrumentation")
+
+        thread_id = self.expect_not_none(stop_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+        self.assertEqual(exception_info.breakMode, "always")
+        description = self.expect_not_none(exception_info.description)
+        self.assertRegex(description, r"fatal_error: heap-use-after-free")
+        self.assertEqual(exception_info.exceptionId, "runtime-instrumentation")
diff --git 
a/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py 
b/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
index 9fcc1d4a0a8e7..bc801ca9d9912 100644
--- a/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
+++ b/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
@@ -2,13 +2,13 @@
 Test exception behavior in DAP with c++ throw.
 """
 
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipIfWasm, skipIfWindows
+from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
 
 
-@skipIfWasm  # wasm inferiors are built with -fno-exceptions
-class TestDAP_exception_cpp(lldbdap_testcase.DAPTestCaseBase):
+@skipIfWasm  # wasm inferiors are built with -fno-exceptions.
+class TestDAP_exception_cpp(lldb_dap_testcase.DAPTestCaseBase):
     @skipIfWindows
     def test_stopped_description(self):
         """
@@ -16,11 +16,18 @@ def test_stopped_description(self):
         event.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
-        self.dap_server.request_continue()
-        self.verify_stop_exception_info("signal SIGABRT")
-        exceptionInfo = self.get_exceptionInfo()
-        self.assertEqual(exceptionInfo["breakMode"], "always")
-        self.assertIn("signal SIGABRT", exceptionInfo["description"])
-        self.assertEqual(exceptionInfo["exceptionId"], "signal")
-        self.assertIsNotNone(exceptionInfo["details"])
+        session = self.build_and_create_session()
+        process_event = session.launch(LaunchArgs(program=program))
+
+        stopped_event = session.verify_stopped_on_exception(
+            expected_description="signal SIGABRT", after=process_event
+        )
+
+        thread_id = self.expect_not_none(stopped_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+
+        self.assertEqual(exception_info.breakMode, "always")
+        description = self.expect_not_none(exception_info.description)
+        self.assertIn("signal SIGABRT", description)
+        self.assertEqual(exception_info.exceptionId, "signal")
+        self.assertIsNotNone(exception_info.details)
diff --git 
a/lldb/test/API/tools/lldb-dap/exception/objc/TestDAP_exception_objc.py 
b/lldb/test/API/tools/lldb-dap/exception/objc/TestDAP_exception_objc.py
index 89f96f428ec23..438039a19dbc9 100644
--- a/lldb/test/API/tools/lldb-dap/exception/objc/TestDAP_exception_objc.py
+++ b/lldb/test/API/tools/lldb-dap/exception/objc/TestDAP_exception_objc.py
@@ -2,28 +2,37 @@
 Test exception behavior in DAP with obj-c throw.
 """
 
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipUnlessDarwin
+from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
+from lldbsuite.test.tools.lldb_dap.dap_types import ExceptionFilterOptions, 
LaunchArgs
 
 
-class TestDAP_exception_objc(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_exception_objc(lldb_dap_testcase.DAPTestCaseBase):
     @skipUnlessDarwin
     def test_stopped_description(self):
         """
         Test that exception description is shown correctly in stopped event.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
-        self.dap_server.request_continue()
-        self.verify_stop_exception_info("signal SIGABRT")
-        exception_info = self.get_exceptionInfo()
-        self.assertEqual(exception_info["breakMode"], "always")
-        self.assertIn("signal SIGABRT", exception_info["description"])
-        self.assertEqual(exception_info["exceptionId"], "signal")
-        exception_details = exception_info["details"]
-        self.assertRegex(exception_details["message"], "SomeReason")
-        self.assertRegex(exception_details["stackTrace"], "main.m")
+        session = self.build_and_create_session()
+        process_event = session.launch(LaunchArgs(program))
+        stop_event = session.verify_stopped_on_exception(
+            after=process_event, expected_description="signal SIGABRT"
+        )
+
+        thread_id = self.expect_not_none(stop_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+
+        self.assertEqual(exception_info.breakMode, "always")
+        exception_description = 
self.expect_not_none(exception_info.description)
+        self.assertIn("signal SIGABRT", exception_description)
+        self.assertEqual(exception_info.exceptionId, "signal")
+
+        exception_details = self.expect_not_none(exception_info.details)
+        exception_message = self.expect_not_none(exception_details.message)
+        self.assertRegex(exception_message, "SomeReason")
+        stack_trace = self.expect_not_none(exception_details.stackTrace)
+        self.assertRegex(stack_trace, "main.m")
 
     @skipUnlessDarwin
     def test_break_on_throw_and_catch(self):
@@ -31,20 +40,21 @@ def test_break_on_throw_and_catch(self):
         Test that breakpoints on exceptions work as expected.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
+        session = self.build_and_create_session()
+        with session.configure(LaunchArgs(program)) as ctx:
+            response = session.set_exception_breakpoints(
+                filters=["objc_catch", "objc_throw"],
+                filterOptions=[
+                    ExceptionFilterOptions(
+                        filterId="objc_throw",
+                        condition='[[((NSException *)$arg1) name] 
isEqual:@"ThrownException"]',
+                    )
+                ],
+            )
+            self.assertTrue(response.success)
 
-        response = self.dap_server.request_setExceptionBreakpoints(
-            filter_options=[
-                {
-                    "filterId": "objc_throw",
-                    "condition": '[[((NSException *)$arg1) name] 
isEqual:@"ThrownException"]',
-                },
-            ]
-        )
-        if response:
-            self.assertTrue(response["success"])
-
-        self.continue_to_exception_breakpoint(
+        session.verify_stopped_on_exception(
+            after=ctx.process_event,
             expected_description="hit Objective-C exception",
             expected_text="Objective-C Throw",
         )
@@ -55,13 +65,20 @@ def test_break_on_throw_and_catch(self):
         # SBTarget::BreakpointCreateForException(eLanguageObjectiveC, 
/*catch_bp=*/true, /*throw_bp=*/false);
         # self.continue_to_exception_breakpoint("Objective-C Catch")
 
-        self.do_continue()
+        stop_event = session.continue_to_exception_breakpoint(
+            expected_description="signal SIGABRT"
+        )
+
+        thread_id = self.expect_not_none(stop_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+
+        self.assertEqual(exception_info.breakMode, "always")
+        description = self.expect_not_none(exception_info.description)
+        self.assertIn("signal SIGABRT", description)
+        self.assertEqual(exception_info.exceptionId, "signal")
 
-        self.verify_stop_exception_info("signal SIGABRT")
-        exception_info = self.get_exceptionInfo()
-        self.assertEqual(exception_info["breakMode"], "always")
-        self.assertIn("signal SIGABRT", exception_info["description"])
-        self.assertEqual(exception_info["exceptionId"], "signal")
-        exception_details = exception_info["details"]
-        self.assertRegex(exception_details["message"], "SomeReason")
-        self.assertRegex(exception_details["stackTrace"], "main.m")
+        exception_details = self.expect_not_none(exception_info.details)
+        message = self.expect_not_none(exception_details.message)
+        self.assertRegex(message, "SomeReason")
+        stack_trace = self.expect_not_none(exception_details.stackTrace)
+        self.assertRegex(stack_trace, "main.m")
diff --git a/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py 
b/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
index 270c7f0a22a89..fd2d46c730972 100644
--- a/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
+++ b/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
@@ -2,28 +2,35 @@
 Test that we stop at runtime instrumentation locations (ubsan).
 """
 
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
+from lldbsuite.test.decorators import skipUnlessUndefinedBehaviorSanitizer
+from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
 
 
-class TestDAP_ubsan(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_ubsan(DAPTestCaseBase):
     @skipUnlessUndefinedBehaviorSanitizer
     def test_ubsan(self):
         """
         Test that we stop at ubsan.
         """
         program = self.getBuildArtifact("a.out")
-        self.build_and_launch(program)
-        self.do_continue()
+        session = self.build_and_create_session()
+        process_event = session.launch(LaunchArgs(program))
+        stop_event = session.verify_stopped_on_exception(
+            after=process_event, expected_description=r"Out of bounds index"
+        )
 
-        self.verify_stop_exception_info("Out of bounds index")
-        exceptionInfo = self.get_exceptionInfo()
-        self.assertEqual(exceptionInfo["breakMode"], "always")
-        self.assertRegex(exceptionInfo["description"], r"Out of bounds index")
-        self.assertEqual(exceptionInfo["exceptionId"], 
"runtime-instrumentation")
+        thread_id = self.expect_not_none(stop_event.body.threadId)
+        exception_info = session.get_exception_info(thread_id)
+
+        self.assertEqual(exception_info.breakMode, "always")
+        description = self.expect_not_none(exception_info.description)
+        self.assertRegex(description, r"Out of bounds index")
+        self.assertEqual(exception_info.exceptionId, "runtime-instrumentation")
 
         # FIXME: Check on non macOS platform the stop information location 
heuristic
         # may be wrong. enable when we have updated Ubsan stopInfo heuristic.
         if self.platformIsDarwin():
-            self.assertIn("main.c", exceptionInfo["details"]["stackTrace"])
+            exception_details = self.expect_not_none(exception_info.details)
+            stack_trace = self.expect_not_none(exception_details.stackTrace)
+            self.assertIn("main.c", stack_trace)

>From 85ac2a47085eb9811be15c4418f7f5f221019ef3 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Thu, 2 Jul 2026 14:52:05 +0100
Subject: [PATCH 2/3] Add test for cpp throw and catch

---
 .../test/tools/lldb_dap/session_helpers.py    |  5 +-
 .../exception/cpp/TestDAP_exception_cpp.py    | 52 +++++++++++++++++++
 .../API/tools/lldb-dap/exception/cpp/main.cpp | 11 ++++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session_helpers.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session_helpers.py
index 1e992883d03eb..34eb33f03c450 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session_helpers.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session_helpers.py
@@ -1119,7 +1119,10 @@ def continue_to_any_breakpoint(self, breakpoint_ids: 
list[int]):
         return event
 
     def continue_to_exception_breakpoint(
-        self, *, expected_description: str, expected_text: Optional[str] = None
+        self,
+        *,
+        expected_description: Optional[str] = None,
+        expected_text: Optional[str] = None,
     ):
         continue_response = self.do_continue()
         return self.verify_stopped_on_exception(
diff --git 
a/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py 
b/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
index bc801ca9d9912..c42ba06a3fe6b 100644
--- a/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
+++ b/lldb/test/API/tools/lldb-dap/exception/cpp/TestDAP_exception_cpp.py
@@ -3,6 +3,7 @@
 """
 
 from lldbsuite.test.decorators import skipIfWasm, skipIfWindows
+from lldbsuite.test.lldbtest import line_number
 from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
 from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
 
@@ -31,3 +32,54 @@ def test_stopped_description(self):
         self.assertIn("signal SIGABRT", description)
         self.assertEqual(exception_info.exceptionId, "signal")
         self.assertIsNotNone(exception_info.details)
+
+    @skipIfWindows  # cpp exception breakpoint is not supported.
+    def test_break_on_throw_and_catch(self):
+        """Test thrown and caught cpp exception breakpoint works."""
+        program = self.getBuildArtifact("a.out")
+        session = self.build_and_create_session()
+        with session.configure(LaunchArgs(program, args=["1"])) as ctx:
+            # Check we advertise the c++ throw and catch exception filters.
+            resp = ctx.init_response
+            bp_filters = 
self.expect_not_none(resp.body.exceptionBreakpointFilters)
+
+            init_filters = [ft.filter for ft in bp_filters]
+            cpp_filters = ["cpp_throw", "cpp_catch"]
+            for filter in cpp_filters:
+                self.assertIn(filter, init_filters, "expect cpp_filters is 
advertised.")
+
+            session.set_exception_breakpoints(filters=cpp_filters)
+
+        stop_event = 
session.verify_stopped_on_exception(after=ctx.process_event)
+        thread_ctx = session.thread_context_from(stop_event)
+
+        def verify_stack_trace_contains(function: str, line: int):
+            frames = [ctx.frame for ctx in thread_ctx.frames()]
+            for frame in frames:
+                if frame.name.startswith(function):
+                    frame_line = self.expect_not_none(frame.line)
+                    self.assertEqual(frame_line, line)
+                    return
+
+            msg = f"expected {function=} {line=} in stacktrace:"
+            for i, frame in enumerate(frames):
+                msg += f"\n [{i}] {frame.name}:{frame.line}"
+            self.fail(msg)
+
+        source = self.getSourcePath("main.cpp")
+        [throw_filter, caught_filter] = cpp_filters
+
+        # Check the thrown exception.
+        thrown_line = line_number(source, "// thrown_exception")
+        verify_stack_trace_contains("throw_some_string", thrown_line)
+        exc_info = session.get_exception_info(thread_ctx.thread_id)
+        self.assertEqual(throw_filter, exc_info.exceptionId)
+
+        # Check the caught exception.
+        session.continue_to_exception_breakpoint()
+        caught_line = line_number(source, "// caught_exception")
+        verify_stack_trace_contains("main", caught_line)
+        exc_info = session.get_exception_info(thread_ctx.thread_id)
+        self.assertEqual(caught_filter, exc_info.exceptionId)
+
+        session.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/exception/cpp/main.cpp 
b/lldb/test/API/tools/lldb-dap/exception/cpp/main.cpp
index 39d89b95319a8..589906d1a08c0 100644
--- a/lldb/test/API/tools/lldb-dap/exception/cpp/main.cpp
+++ b/lldb/test/API/tools/lldb-dap/exception/cpp/main.cpp
@@ -1,6 +1,17 @@
 #include <stdexcept>
 
+void throw_some_string() {
+  throw "fake message"; // thrown_exception.
+}
+
 int main(int argc, char const *argv[]) {
+  try {
+    throw_some_string();
+  } catch (const char *) { // caught_exception.
+    if (argc > 1)
+      return 0;
+  }
+
   throw std::invalid_argument("throwing exception for testing");
   return 0;
 }

>From 889f411a5be2345b448d777c3817624bc852f185 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Mon, 6 Jul 2026 17:53:54 +0100
Subject: [PATCH 3/3] change the import style

---
 lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py 
b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
index 7a91c2d88f413..7f6afd078219a 100644
--- a/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
+++ b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
@@ -3,11 +3,11 @@
 """
 
 from lldbsuite.test.decorators import skipUnlessAddressSanitizer
-from lldbsuite.test.tools.lldb_dap import lldb_dap_testcase
 from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs
+from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase
 
 
-class TestDAP_asan(lldb_dap_testcase.DAPTestCaseBase):
+class TestDAP_asan(DAPTestCaseBase):
     @skipUnlessAddressSanitizer
     def test_asan(self):
         """

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to