[Ada catchpoints] Fix "warning: failed to get exception name: No definition of \...
authorPedro Alves <palves@redhat.com>
Tue, 21 Jun 2016 00:11:43 +0000 (01:11 +0100)
committerPedro Alves <palves@redhat.com>
Tue, 21 Jun 2016 00:11:43 +0000 (01:11 +0100)
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:
2016-06-21  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:
2016-06-21  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/ChangeLog
gdb/ada-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/mi_catch_ex.exp

index faa9e9fb81f19ac72b287ca3692945d56bed5575..98f56ed31767cd7d270277f0c25cb767d304598d 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-21  Pedro Alves  <palves@redhat.com>
+
+       * ada-lang.c (ada_exception_name_addr_1): Add comment.
+       (print_it_exception): Select the current frame.
+
 2016-06-17  Yan-Ting Lin  <currygt52@gmail.com>
 
        * Makefile.in (ALL_TARGET_OBS): Add nds32-tdep.o.
index 412aa972caa1579b84c92c2543c40bc83b1575c0..3c5ab26b405870d190404c0710d64ca9b4a2e23b 100644 (file)
@@ -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:
index b33e1be731547c6430b6802d5fadb037753ff0df..86560821aa70d3c88d921c9b4657eb091786a90a 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-21  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.
+
 2016-06-21  Pedro Alves  <palves@redhat.com>
 
        * gdb.python/py-mi-events-gdb.py (stop_handler_str)
index 320f3bfba9b9a8f18d8db3d9a7e573a4af014c23..288a0659ba84eb1d6037f7f3e1b5556bed748ef4 100644 (file)
@@ -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. #