Add Ada unhandled exception filter to DAP

Message ID 20251217165455.3312359-1-tromey@adacore.com
State New
Headers
Series Add Ada unhandled exception filter to DAP |

Commit Message

Tom Tromey Dec. 17, 2025, 4:54 p.m. UTC
  This adds a way for DAP clients to catch unhandled Ada exceptions,
similar to the "catch exception unhandled" CLI command.
---
 gdb/NEWS                                      |  5 ++
 gdb/python/lib/gdb/dap/breakpoint.py          |  9 +++-
 gdb/testsuite/gdb.dap/catch-unhandled.exp     | 48 +++++++++++++++++++
 gdb/testsuite/gdb.dap/catch-unhandled/pck.adb | 21 ++++++++
 gdb/testsuite/gdb.dap/catch-unhandled/pck.ads | 18 +++++++
 .../gdb.dap/catch-unhandled/prog.adb          | 21 ++++++++
 6 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled.exp
 create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/pck.adb
 create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/pck.ads
 create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/prog.adb


base-commit: e607549f2495ed68da314642d5c4c51bdd470933
  

Comments

Eli Zaretskii Dec. 17, 2025, 6:09 p.m. UTC | #1
> From: Tom Tromey <tromey@adacore.com>
> Cc: Tom Tromey <tromey@adacore.com>
> Date: Wed, 17 Dec 2025 09:54:55 -0700
> 
> This adds a way for DAP clients to catch unhandled Ada exceptions,
> similar to the "catch exception unhandled" CLI command.
> ---
>  gdb/NEWS                                      |  5 ++
>  gdb/python/lib/gdb/dap/breakpoint.py          |  9 +++-
>  gdb/testsuite/gdb.dap/catch-unhandled.exp     | 48 +++++++++++++++++++
>  gdb/testsuite/gdb.dap/catch-unhandled/pck.adb | 21 ++++++++
>  gdb/testsuite/gdb.dap/catch-unhandled/pck.ads | 18 +++++++
>  .../gdb.dap/catch-unhandled/prog.adb          | 21 ++++++++
>  6 files changed, 121 insertions(+), 1 deletion(-)
>  create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled.exp
>  create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/pck.adb
>  create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/pck.ads
>  create mode 100644 gdb/testsuite/gdb.dap/catch-unhandled/prog.adb
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index ba37dc89f76..b068697bc5c 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -90,6 +90,11 @@ New command class for help
>    commands that we, as developers, believe would be close to a minimal
>    set of commands for a new user of GDB.
>  
> +* Debugger Adapter Protocol changes
> +
> +  ** Unhandled Ada exceptions can now be caught using the "unhandled"
> +     exception filter.
> +
>  * Changed remote packets

This part is okay, thanks.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
  
Tom Tromey Jan. 5, 2026, 2:24 p.m. UTC | #2
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:

Tom> This adds a way for DAP clients to catch unhandled Ada exceptions,
Tom> similar to the "catch exception unhandled" CLI command.

I'm checking this in.

Tom
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index ba37dc89f76..b068697bc5c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -90,6 +90,11 @@  New command class for help
   commands that we, as developers, believe would be close to a minimal
   set of commands for a new user of GDB.
 
+* Debugger Adapter Protocol changes
+
+  ** Unhandled Ada exceptions can now be caught using the "unhandled"
+     exception filter.
+
 * Changed remote packets
 
 single-inf-arg in qSupported
diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py
index 060e4d8878c..b1d42ed3d8b 100644
--- a/gdb/python/lib/gdb/dap/breakpoint.py
+++ b/gdb/python/lib/gdb/dap/breakpoint.py
@@ -367,7 +367,9 @@  def set_insn_breakpoints(
 
 @in_gdb_thread
 def _catch_exception(filterId, **args):
-    if filterId in ("assert", "exception", "throw", "rethrow", "catch"):
+    if filterId == "unhandled":
+        cmd = ["-catch-exception", "-u"]
+    elif filterId in ("assert", "exception", "throw", "rethrow", "catch"):
         cmd = ["-catch-" + filterId]
     else:
         raise DAPException("Invalid exception filterID: " + str(filterId))
@@ -424,6 +426,11 @@  def _rewrite_exception_breakpoint(
             "label": "Ada exceptions",
             "supportsCondition": True,
         },
+        {
+            "filter": "unhandled",
+            "label": "Ada exceptions without a handler",
+            "supportsCondition": True,
+        },
         {
             "filter": "throw",
             "label": "C++ exceptions, when thrown",
diff --git a/gdb/testsuite/gdb.dap/catch-unhandled.exp b/gdb/testsuite/gdb.dap/catch-unhandled.exp
new file mode 100644
index 00000000000..e2eb77195c5
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/catch-unhandled.exp
@@ -0,0 +1,48 @@ 
+# Copyright 2025 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib ada.exp
+load_lib dap-support.exp
+
+require allow_ada_tests allow_dap_tests gnat_runtime_has_debug_info
+
+standard_ada_testfile prog
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != ""} {
+    return -1
+}
+
+if {[dap_initialize] == ""} {
+    return
+}
+
+set launch_id [dap_launch $testfile]
+
+set obj [dap_check_request_and_response "set exception catchpoints" \
+	     setExceptionBreakpoints \
+	     {o filters [a [s unhandled]]}]
+
+set bps [dict get [lindex $obj 0] body breakpoints]
+gdb_assert {[llength $bps] == 1} "one breakpoint"
+
+dap_check_request_and_response "configurationDone" configurationDone
+
+dap_check_response "launch response" launch $launch_id
+
+dap_wait_for_event_and_check "stopped at unhandled exception" stopped \
+    "body reason" breakpoint \
+    "body hitBreakpointIds" 1
+
+dap_shutdown
diff --git a/gdb/testsuite/gdb.dap/catch-unhandled/pck.adb b/gdb/testsuite/gdb.dap/catch-unhandled/pck.adb
new file mode 100644
index 00000000000..367af8eafd7
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/catch-unhandled/pck.adb
@@ -0,0 +1,21 @@ 
+--  Copyright 2025 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package body Pck is
+   procedure Throw_Something (Val : Integer) is
+   begin
+      raise Program_Error;
+   end Throw_Something;
+end Pck;
diff --git a/gdb/testsuite/gdb.dap/catch-unhandled/pck.ads b/gdb/testsuite/gdb.dap/catch-unhandled/pck.ads
new file mode 100644
index 00000000000..513554fa0d8
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/catch-unhandled/pck.ads
@@ -0,0 +1,18 @@ 
+--  Copyright 2025 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package Pck is
+   procedure Throw_Something (Val : Integer);
+end Pck;
diff --git a/gdb/testsuite/gdb.dap/catch-unhandled/prog.adb b/gdb/testsuite/gdb.dap/catch-unhandled/prog.adb
new file mode 100644
index 00000000000..9db1a3e1587
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/catch-unhandled/prog.adb
@@ -0,0 +1,21 @@ 
+--  Copyright 2025 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+with Pck; use Pck;
+
+procedure Prog is
+begin
+   Throw_Something (23);
+end Prog;