From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 117695 invoked by alias); 24 Nov 2017 21:32:28 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 116253 invoked by uid 89); 24 Nov 2017 21:32:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KB_WAM_FROM_NAME_SINGLEWORD,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=whenever, Continue, adb, parse_and_eval X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 24 Nov 2017 21:32:25 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id D2F22116653; Fri, 24 Nov 2017 16:32:23 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Bb1+XFptUuov; Fri, 24 Nov 2017 16:32:23 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 9CE87116651; Fri, 24 Nov 2017 16:32:23 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 012A587442; Fri, 24 Nov 2017 13:32:21 -0800 (PST) Date: Fri, 24 Nov 2017 21:32:00 -0000 From: Joel Brobecker To: Eli Zaretskii Cc: Xavier Roirand , gdb-patches@sourceware.org Subject: Re: [RFA/doco] (Ada) provide the exception message when hitting an exception catchpoint Message-ID: <20171124213221.5ltvhfqzapgb2xdz@adacore.com> References: <1510953646-116765-1-git-send-email-brobecker@adacore.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1510953646-116765-1-git-send-email-brobecker@adacore.com> User-Agent: NeoMutt/20170113 (1.7.2) X-SW-Source: 2017-11/txt/msg00628.txt.bz2 Hi Eli, Would you have some time to review the doc changes in the patches below? Thanks! On Fri, Nov 17, 2017 at 04:20:46PM -0500, Joel Brobecker wrote: > Hello, > > This patch enhances the debugger to print the exception message, when > available, as part of an exception catchpoint hit notification (both > GDB/CLI and GDB/MI). For instance, with the following code... > > procedure A is > begin > raise Constraint_Error with "hello world"; > end A; > > ... instead of printing... > > Catchpoint 1, CONSTRAINT_ERROR at 0x000000000040245c in a () at a.adb:3 > > ... it now prints: > > Catchpoint 1, CONSTRAINT_ERROR (hello world) at 0x000000000040245c in a () > ^^^^^^^^^^^^^ > > This enhancement requires runtime support. If not present, the debugger > just behaves as before. > > In GDB/MI mode, if the exception message is available, it is provided > as an extra field named "exception-message" in the catchpoint notification: > > *stopped,bkptno="1",[...],exception-name="CONSTRAINT_ERROR", > exception-message="hello world",[...] > > gdb/ChangeLog: > > * ada-lang.c (ada_exception_message_1, ada_exception_message): > New functions. > (print_it_exception): If available, display the exception > message as well. > NEWS: Document new feature. > > gdb/doc/ChangeLog: > > * gdb.texinfo (GDB/MI Ada Exception Information): Document > new "exception-message" field. > > gdb/testsuite/ChangeLog: > > * gdb.ada/catch_ex.exp, gdb.ada/mi_catch_ex.exp, > gdb.ada/mi_ex_cond.exp: Accept optional exception message in > when hitting an exception catchpoint. > > Tested on x86_64-linux, no regression. > > Are the NEWS and doc/gdb.texinfo changes OK to commit? > > Thank you, > -- > Joel > > --- > gdb/NEWS | 5 +++ > gdb/ada-lang.c | 81 +++++++++++++++++++++++++++++++++++ > gdb/doc/gdb.texinfo | 4 +- > gdb/testsuite/gdb.ada/catch_ex.exp | 8 ++-- > gdb/testsuite/gdb.ada/mi_catch_ex.exp | 10 ++--- > gdb/testsuite/gdb.ada/mi_ex_cond.exp | 2 +- > 6 files changed, 99 insertions(+), 11 deletions(-) > > diff --git a/gdb/NEWS b/gdb/NEWS > index dc070fa..5928bd6 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -52,6 +52,11 @@ > variables that are to be set or unset from GDB. These variables > will affect the environment to be passed to the inferior. > > +* When catching an Ada exception raised with a message, GDB now prints > + the message in the catchpoint hit notification. In GDB/MI mode, that > + information is provided as an extra field named "exception-message" > + in the *stopped notification. > + > * New remote packets > > QEnvironmentHexEncoded > diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c > index 33c4e8e..3265c21 100644 > --- a/gdb/ada-lang.c > +++ b/gdb/ada-lang.c > @@ -12105,6 +12105,73 @@ ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex, > return 0; /* Should never be reached. */ > } > > +/* Assuming the inferior is stopped at an exception catchpoint, > + return the message which was associated to the exception, if > + available. Return NULL if the message could not be retrieved. > + > + The caller must xfree the string after use. > + > + Note: The exception message can be associated to an exception > + either through the use of the Raise_Exception function, or > + more simply (Ada 2005 and later), via: > + > + raise Exception_Name with "exception message"; > + > + */ > + > +static char * > +ada_exception_message_1 (void) > +{ > + struct value *e_msg_val; > + char *e_msg = NULL; > + int e_msg_len; > + struct cleanup *cleanups; > + > + /* For runtimes that support this feature, the exception message > + is passed as an unbounded string argument called "message". */ > + e_msg_val = parse_and_eval ("message"); > + if (e_msg_val == NULL) > + return NULL; /* Exception message not supported. */ > + > + e_msg_val = ada_coerce_to_simple_array (e_msg_val); > + gdb_assert (e_msg_val != NULL); > + e_msg_len = TYPE_LENGTH (value_type (e_msg_val)); > + > + /* If the message string is empty, then treat it as if there was > + no exception message. */ > + if (e_msg_len <= 0) > + return NULL; > + > + e_msg = (char *) xmalloc (e_msg_len + 1); > + cleanups = make_cleanup (xfree, e_msg); > + read_memory_string (value_address (e_msg_val), e_msg, e_msg_len + 1); > + e_msg[e_msg_len] = '\0'; > + > + discard_cleanups (cleanups); > + return e_msg; > +} > + > +/* Same as ada_exception_message_1, except that all exceptions are > + contained here (returning NULL instead). */ > + > +static char * > +ada_exception_message (void) > +{ > + char *e_msg = NULL; /* Avoid a spurious uninitialized warning. */ > + > + TRY > + { > + e_msg = ada_exception_message_1 (); > + } > + CATCH (e, RETURN_MASK_ERROR) > + { > + e_msg = NULL; > + } > + END_CATCH > + > + return e_msg; > +} > + > /* Same as ada_exception_name_addr_1, except that it intercepts and contains > any error that ada_exception_name_addr_1 might cause to be thrown. > When an error is intercepted, a warning with the error message is printed, > @@ -12340,6 +12407,7 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs) > { > struct ui_out *uiout = current_uiout; > struct breakpoint *b = bs->breakpoint_at; > + char *exception_message; > > annotate_catchpoint (b->number); > > @@ -12405,6 +12473,19 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs) > uiout->text ("failed assertion"); > break; > } > + > + exception_message = ada_exception_message (); > + if (exception_message != NULL) > + { > + struct cleanup *cleanups = make_cleanup (xfree, exception_message); > + > + uiout->text (" ("); > + uiout->field_string ("exception-message", exception_message); > + uiout->text (")"); > + > + do_cleanups (cleanups); > + } > + > uiout->text (" at "); > ada_find_printable_frame (get_current_frame ()); > > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 29d4789..430db0f 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -27183,7 +27183,9 @@ thread was last seen on. This field is optional. > Whenever a @code{*stopped} record is emitted because the program > stopped after hitting an exception catchpoint (@pxref{Set Catchpoints}), > @value{GDBN} provides the name of the exception that was raised via > -the @code{exception-name} field. > +the @code{exception-name} field. Also, for exceptions that were raised > +with an exception message, @value{GDBN} provides that message via > +the @code{exception-message} field. > > @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > @node GDB/MI Simple Examples > diff --git a/gdb/testsuite/gdb.ada/catch_ex.exp b/gdb/testsuite/gdb.ada/catch_ex.exp > index 5313e77..3797601 100644 > --- a/gdb/testsuite/gdb.ada/catch_ex.exp > +++ b/gdb/testsuite/gdb.ada/catch_ex.exp > @@ -62,13 +62,13 @@ gdb_test "info break" \ > "info break, catch all Ada exceptions" > > set catchpoint_msg \ > - "Catchpoint $any_nb, CONSTRAINT_ERROR at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > + "Catchpoint $any_nb, CONSTRAINT_ERROR (\\\(foo\\.adb:$decimal explicit raise\\\) )?at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > gdb_test "continue" \ > "Continuing\.$eol$catchpoint_msg$eol.*SPOT1" \ > "continuing to first exception" > > set catchpoint_msg \ > - "Catchpoint $any_nb, PROGRAM_ERROR at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > + "Catchpoint $any_nb, PROGRAM_ERROR (\\\(foo\\.adb:$decimal explicit raise\\\) )?at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > gdb_test "continue" \ > "Continuing\.$eol$catchpoint_msg$eol.*SPOT2" \ > "continuing to second exception" > @@ -116,7 +116,7 @@ gdb_test "info break" \ > "info break, second run" > > set catchpoint_msg \ > - "Catchpoint $any_nb, PROGRAM_ERROR at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > + "Catchpoint $any_nb, PROGRAM_ERROR (\\\(foo.adb:$decimal explicit raise\\\) )?at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > gdb_test "continue" \ > "Continuing\.$eol$catchpoint_msg$eol.*SPOT2" \ > "continuing to Program_Error exception" > @@ -157,7 +157,7 @@ gdb_test "tcatch exception" \ > "Temporary catchpoint $any_nb: all Ada exceptions" > > set temp_catchpoint_msg \ > - "Temporary catchpoint $any_nb, CONSTRAINT_ERROR at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > + "Temporary catchpoint $any_nb, CONSTRAINT_ERROR (\\\(.*\\\) )?at $any_addr in foo \\\(\\\).*at .*foo.adb:$any_nb" > gdb_test "continue" \ > "Continuing\.$eol$temp_catchpoint_msg$eol.*SPOT1" \ > "continuing to temporary catchpoint" > diff --git a/gdb/testsuite/gdb.ada/mi_catch_ex.exp b/gdb/testsuite/gdb.ada/mi_catch_ex.exp > index c9dd616..2ca3b6c 100644 > --- a/gdb/testsuite/gdb.ada/mi_catch_ex.exp > +++ b/gdb/testsuite/gdb.ada/mi_catch_ex.exp > @@ -80,7 +80,7 @@ mi_gdb_test "-catch-exception" \ > > # Continue to caught exception. > > -proc continue_to_exception { exception_name test } { > +proc continue_to_exception { exception_name exception_message test } { > global hex any_nb > > mi_send_resuming_command "exec-continue" "$test" > @@ -97,18 +97,18 @@ proc continue_to_exception { exception_name test } { > > # Now MI stream output. > mi_expect_stop \ > - "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"$exception_name" \ > + "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"$exception_name(\",exception-message=\"$exception_message)?" \ > "foo" "" ".*" ".*" \ > ".*" \ > $test > } > > continue_to_exception \ > - "CONSTRAINT_ERROR" \ > + "CONSTRAINT_ERROR" "foo\\.adb:$decimal explicit raise" \ > "continue until CE caught by all-exceptions catchpoint" > > continue_to_exception \ > - "PROGRAM_ERROR" \ > + "PROGRAM_ERROR" "foo\\.adb:$decimal explicit raise" \ > "continue until PE caught by all-exceptions catchpoint" > > ################################################ > @@ -143,7 +143,7 @@ mi_gdb_test "-catch-exception -u" \ > "catch unhandled exceptions" > > mi_execute_to "exec-continue" \ > - "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"PROGRAM_ERROR" \ > + "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"PROGRAM_ERROR(\",exception-message=\"foo\\.adb:$decimal explicit raise)?" \ > "foo" "" ".*" ".*" \ > ".*" \ > "continue to exception catchpoint hit" > diff --git a/gdb/testsuite/gdb.ada/mi_ex_cond.exp b/gdb/testsuite/gdb.ada/mi_ex_cond.exp > index 78765be..369f155 100644 > --- a/gdb/testsuite/gdb.ada/mi_ex_cond.exp > +++ b/gdb/testsuite/gdb.ada/mi_ex_cond.exp > @@ -81,7 +81,7 @@ mi_gdb_test "-catch-exception -c \"i = 2\" -e constraint_error" \ > mi_run_cmd > > mi_expect_stop \ > - "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"CONSTRAINT_ERROR" \ > + "breakpoint-hit\",disp=\"keep\",bkptno=\"$any_nb\",exception-name=\"CONSTRAINT_ERROR(\",exception-message=\"foo\\.adb:$decimal explicit raise)?" \ > "foo" "" ".*" ".*" \ > ".*" \ > "run to exception catchpoint hit" > -- > 2.1.4 -- Joel