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.
This commit is contained in:
Tom Tromey
2025-08-22 11:52:26 -06:00
parent 31cb4bb676
commit e957baea20
3 changed files with 28 additions and 6 deletions

View File

@@ -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,

View File

@@ -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 \

View File

@@ -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;