aboutsummaryrefslogtreecommitdiff
path: root/gdb/ada-lang.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2017-11-24 17:09:42 -0500
committerJoel Brobecker <brobecker@adacore.com>2017-11-24 17:15:30 -0500
commite547c119d043f2ecffb70452020ab9150d083a91 (patch)
treea10b51c4f842670ed00ce3970ee54adbafa9d55a /gdb/ada-lang.c
parent5f1ca24acd8fd4e21c4f6f3ed2bbc4e2365215fe (diff)
downloadgdb-e547c119d043f2ecffb70452020ab9150d083a91.zip
gdb-e547c119d043f2ecffb70452020ab9150d083a91.tar.gz
gdb-e547c119d043f2ecffb70452020ab9150d083a91.tar.bz2
(Ada) provide the exception message when hitting an exception catchpoint
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.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r--gdb/ada-lang.c81
1 files changed, 81 insertions, 0 deletions
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 ());