mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
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:
@@ -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,
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user