[PATCH v3 02/34] [Ada catchpoints] Fix "warning: failed to get exception name: No definition of \"e.full_name\" in current context"

Pedro Alves
2016-05-06T12:35:20Z

Looking at testsuite results, I noticed this warning in an MI test:

~"\nCatchpoint "
~"2, "
&"warning: failed to get exception name: No definition of \"e.full_name\" in current context.\n"
~"exception at 0x000000000040192d in foo () at /home/pedro/brno/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/mi_catch_ex/foo.adb:20\n"
~"20\t raise Constraint_Error; -- SPOT1\n"
*stopped,reason="breakpoint-hit",disp="keep",bkptno="2",exception-name="CONSTRAINT_ERROR",frame={addr="0x000000000040192d",func="foo",args=[],file="/home/pedro/brno/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/mi_catch_ex/foo.adb",fullname="/home/pedro/brno/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/mi_catch_ex/foo.adb",line="20"},thread-id="1",stopped-threads="all",core="5"
(gdb)
PASS: gdb.ada/mi_catch_ex.exp: continue until CE caught by all-exceptions catchpoint

The problem is that:

- MI prints the breakpoint hit twice: once on the MI stream;
another time on the console stream.

- After printing the Ada catchpoint hit, gdb selects a non-current
frame, from within the catchpoint's print_it routine.

So the second time the breakpoint is printed, the selected frame is no
longer the current frame, and then evaluating e.full_name in
ada_exception_name_addr fails.

This commit fixes the problem and enhances the gdb.ada/mi_catch_ex.exp
test to make sure the catchpoint hit is printed correctly on the
console stream too.

gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>

* ada-lang.c (ada_exception_name_addr_1): Add comment.
(print_it_exception): Select the current frame.

gdb/testsuite/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>

* gdb.ada/mi_catch_ex.exp (continue_to_exception): New procedure.
(top level): Use it instead of mi_execute_to.
---
gdb/ada-lang.c | 9 ++++++++
gdb/testsuite/gdb.ada/mi_catch_ex.exp | 41 ++++++++++++++++++++++++++---------
2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 412aa97..3c5ab26 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12183,6 +12183,8 @@ ada_unhandled_exception_name_addr_from_raise (void)
(of any type), return the address in inferior memory where the name
of the exception is stored, if applicable.

+ Assumes the selected frame is the current frame.
+
Return zero if the address could not be computed, or if not relevant. */

static CORE_ADDR
@@ -12484,6 +12486,13 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
ui_out_field_int (uiout, "bkptno", b->number);
ui_out_text (uiout, ", ");

+ /* ada_exception_name_addr relies on the selected frame being the
+ current frame. Need to do this here because this function may be
+ called more than once when printing a stop, and below, we'll
+ select the first frame past the Ada run-time (see
+ ada_find_printable_frame). */
+ select_frame (get_current_frame ());
+
switch (ex)
{
case ada_catch_exception:
diff --git a/gdb/testsuite/gdb.ada/mi_catch_ex.exp b/gdb/testsuite/gdb.ada/mi_catch_ex.exp
index 320f3bf..288a065 100644
--- a/gdb/testsuite/gdb.ada/mi_catch_ex.exp
+++ b/gdb/testsuite/gdb.ada/mi_catch_ex.exp
@@ -78,17 +78,38 @@ mi_gdb_test "-catch-exception" \
"\\^done,bkptno=\"$decimal\",bkpt={.*disp=\"keep\",enabled=\"y\",addr=\"$hex\",what=\"all Ada exceptions\",.*}" \
"catch all exceptions"

-mi_execute_to "exec-continue" \
- "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"CONSTRAINT_ERROR" \
- "foo" "" ".*" ".*" \
- ".*" \
- "continue until CE caught by all-exceptions catchpoint"
+# Continue to caught exception.

-mi_execute_to "exec-continue" \
- "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"PROGRAM_ERROR" \
- "foo" "" ".*" ".*" \
- ".*" \
- "continue until PE caught by all-exceptions catchpoint"
+proc continue_to_exception { exception_name test } {
+ global hex any_nb
+
+ mi_send_resuming_command "exec-continue" "$test"
+
+ # Match console stream output.
+ gdb_expect {
+ -re " $exception_name at $hex in foo " {
+ }
+ timeout {
+ fail "$test (timeout)"
+ return -1
+ }
+ }
+
+ # Now MI stream output.
+ mi_expect_stop \
+ "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"$exception_name" \
+ "foo" "" ".*" ".*" \
+ ".*" \
+ $test
+}
+
+continue_to_exception \
+ "CONSTRAINT_ERROR" \
+ "continue until CE caught by all-exceptions catchpoint"
+
+continue_to_exception \
+ "PROGRAM_ERROR" \
+ "continue until PE caught by all-exceptions catchpoint"

################################################
# 2. Try catching only some of the exceptions. #
--
2.5.5