From: Tom Tromey Date: Fri, 22 Aug 2025 17:52:26 +0000 (-0600) Subject: Change DAP condition for Ada exception catchpoint X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e957baea206253a54e16e45bbe5cec0401c2a7ed;p=thirdparty%2Fbinutils-gdb.git Change DAP condition for Ada exception catchpoint Currently, the gdb DAP implementation doesn't provide a way to filter based on the thrown Ada exception. There isn't really an ideal way to handle this in DAP: * Requiring an IDE to use an expression checking $_ada_exception exposes the IDE to any workarounds needed to get this correct (see ada-lang.c). * The setExceptionBreakpoint "filterOptions" field doesn't allow a special kind of condition to be set. (We could add one but we've generally avoided gdb-specific extensions.) * The "exceptionOptions" approach is under-documented. It could be used but it would have to be in a somewhat gdb-specific way anyway -- and this approach does not allow a separate condition that is an expression. So, after some internal discussion, we agreed that it isn't all that useful to have conditions on Ada exception catchpoints. This patch changes the implementation to treat the condition as an exception name here. --- diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py index 4d4ca181e04..31629117071 100644 --- a/gdb/python/lib/gdb/dap/breakpoint.py +++ b/gdb/python/lib/gdb/dap/breakpoint.py @@ -373,10 +373,12 @@ def set_insn_breakpoints( @in_gdb_thread def _catch_exception(filterId, **args): if filterId in ("assert", "exception", "throw", "rethrow", "catch"): - cmd = "-catch-" + filterId + cmd = ["-catch-" + filterId] else: raise DAPException("Invalid exception filterID: " + str(filterId)) - result = exec_mi_and_log(cmd) + if "exception" in args and args["exception"] is not None: + cmd += ["-e", args["exception"]] + result = exec_mi_and_log(*cmd) # While the Ada catchpoints emit a "bkptno" field here, the C++ # ones do not. So, instead we look at the "number" field. num = result["bkpt"]["number"] @@ -404,6 +406,13 @@ def _rewrite_exception_breakpoint( # Note that exception breakpoints do not support a hit count. **args, ): + if filterId == "exception": + # Treat Ada exceptions specially -- in particular the + # condition is just an exception name, not an expression. + return { + "filterId": filterId, + "exception": condition, + } return { "filterId": filterId, "condition": condition, diff --git a/gdb/testsuite/gdb.dap/catch-exception.exp b/gdb/testsuite/gdb.dap/catch-exception.exp index ced2cc5f7fc..0e8c27ac955 100644 --- a/gdb/testsuite/gdb.dap/catch-exception.exp +++ b/gdb/testsuite/gdb.dap/catch-exception.exp @@ -35,7 +35,7 @@ set obj [dap_check_request_and_response "set exception catchpoints" \ setExceptionBreakpoints \ {o filters [a [s nosuchfilter] [s assert]] \ filterOptions [a [o filterId [s exception] \ - condition [s "Global_Var = 23"]]]}] + condition [s program_error]]]}] set bps [dict get [lindex $obj 0] body breakpoints] # We should get three responses, because we requested three @@ -77,6 +77,20 @@ dap_wait_for_event_and_check "stopped at first raise" stopped \ "body reason" breakpoint \ "body hitBreakpointIds" 2 +set found_line -1 +set line [gdb_get_line_number "EXPECTED" $testdir/prog.adb] +set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \ + {o threadId [i 1]}] \ + 0] +foreach frame [dict get $bt body stackFrames] { + if {[dict exists $frame source path] + && [file tail [dict get $frame source path]] == "prog.adb"} { + set found_line [dict get $frame line] + } +} + +gdb_assert {$found_line == $line} "stopped at correct raise" + dap_check_request_and_response "continue to assert" continue \ {o threadId [i 1]} dap_wait_for_event_and_check "stopped at assert" stopped \ diff --git a/gdb/testsuite/gdb.dap/catch-exception/prog.adb b/gdb/testsuite/gdb.dap/catch-exception/prog.adb index ed60272b906..7a5a31d6ebb 100644 --- a/gdb/testsuite/gdb.dap/catch-exception/prog.adb +++ b/gdb/testsuite/gdb.dap/catch-exception/prog.adb @@ -19,15 +19,14 @@ procedure Prog is begin begin - raise Program_Error; + raise Constraint_Error; exception when others => null; end; begin - Global_Var := 23; - raise Program_Error; + raise Program_Error; -- EXPECTED exception when others => null;