+/* 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.
+
+ 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 gdb::unique_xmalloc_ptr<char>
+ada_exception_message_1 (void)
+{
+ struct value *e_msg_val;
+ int e_msg_len;
+
+ /* 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;
+
+ gdb::unique_xmalloc_ptr<char> e_msg ((char *) xmalloc (e_msg_len + 1));
+ read_memory_string (value_address (e_msg_val), e_msg.get (), e_msg_len + 1);
+ e_msg.get ()[e_msg_len] = '\0';
+
+ return e_msg;
+}
+
+/* Same as ada_exception_message_1, except that all exceptions are
+ contained here (returning NULL instead). */
+
+static gdb::unique_xmalloc_ptr<char>
+ada_exception_message (void)
+{
+ gdb::unique_xmalloc_ptr<char> e_msg;
+
+ TRY
+ {
+ e_msg = ada_exception_message_1 ();
+ }
+ CATCH (e, RETURN_MASK_ERROR)
+ {
+ e_msg.reset (nullptr);
+ }
+ END_CATCH
+
+ return e_msg;
+}
+