From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@adacore.com>
Subject: [PATCH v2 8/8] Add $_ada_exception convenience variable
Date: Fri, 20 Sep 2019 19:20:00 -0000 [thread overview]
Message-ID: <20190920192017.15293-9-tromey@adacore.com> (raw)
In-Reply-To: <20190920192017.15293-1-tromey@adacore.com>
This adds the $_ada_exception convenience variable. It is set by the
Ada exception catchpoints, and holds the address of the exception
currently being thrown. This is useful because it allows more
fine-grained filtering of exceptions than is possible using the
existing "catch" syntax.
This also simplifies Ada catchpoints somewhat; because the catchpoint
must now carry the "kind", it's possible to remove many helper
functions.
gdb/ChangeLog
2019-08-21 Tom Tromey <tromey@adacore.com>
* NEWS: Add $_ada_exception entry.
* ada-lang.c (struct ada_catchpoint): Add constructor.
<m_kind>: New member.
(allocate_location_exception, re_set_exception): Remove
"ex" parameter.
(should_stop_exception): Compute $_ada_exception.
(check_status_exception, print_it_exception)
(print_one_exception, print_mention_exception): Remove
"ex" parameter.
(allocate_location_catch_exception, re_set_catch_exception)
(check_status_exception, print_it_catch_exception)
(print_one_catch_exception, print_mention_catch_exception)
(print_recreate_catch_exception)
(allocate_location_catch_exception_unhandled)
(re_set_catch_exception_unhandled)
(check_status_exception, print_it_catch_exception_unhandled)
(print_one_catch_exception_unhandled)
(print_mention_catch_exception_unhandled)
(print_recreate_catch_exception_unhandled)
(allocate_location_catch_assert, re_set_catch_assert)
(check_status_assert, print_it_catch_assert)
(print_one_catch_assert, print_mention_catch_assert)
(print_recreate_catch_assert)
(allocate_location_catch_handlers, re_set_catch_handlers)
(check_status_handlers, print_it_catch_handlers)
(print_one_catch_handlers, print_mention_catch_handlers)
(print_recreate_catch_handlers): Remove.
(create_ada_exception_catchpoint): Update.
(initialize_ada_catchpoint_ops): Update.
gdb/doc/ChangeLog
2019-08-21 Tom Tromey <tromey@adacore.com>
* gdb.texinfo (Set Catchpoints, Convenience Vars): Document
$_ada_exception.
gdb/testsuite/ChangeLog
2019-08-21 Tom Tromey <tromey@adacore.com>
* gdb.ada/catch_ex_std.exp: Add $_ada_exception test.
---
gdb/ChangeLog | 32 +++
gdb/NEWS | 3 +
gdb/ada-lang.c | 307 +++++++------------------
gdb/doc/ChangeLog | 5 +
gdb/doc/gdb.texinfo | 20 +-
gdb/testsuite/ChangeLog | 4 +
gdb/testsuite/gdb.ada/catch_ex_std.exp | 3 +
7 files changed, 142 insertions(+), 232 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 1fefd814095..959ea27e749 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -34,6 +34,9 @@
* GDB can now be compiled with Python 3 on Windows.
+* New convenience variable $_ada_exception holds the address of the
+ Ada exception being thrown. This is set by Ada-related catchpoints.
+
* Python API
** The gdb.Value type has a new method 'format_string' which returns a
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index e4702b96876..1f388eb4dba 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12326,8 +12326,16 @@ public:
struct ada_catchpoint : public breakpoint
{
+ explicit ada_catchpoint (enum ada_exception_catchpoint_kind kind)
+ : m_kind (kind)
+ {
+ }
+
/* The name of the specific exception the user specified. */
std::string excep_string;
+
+ /* What kind of catchpoint this is. */
+ enum ada_exception_catchpoint_kind m_kind;
};
/* Parse the exception condition string in the context of each of the
@@ -12387,8 +12395,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c,
structure for all exception catchpoint kinds. */
static struct bp_location *
-allocate_location_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *self)
+allocate_location_exception (struct breakpoint *self)
{
return new ada_catchpoint_location (self);
}
@@ -12397,7 +12404,7 @@ allocate_location_exception (enum ada_exception_catchpoint_kind ex,
exception catchpoint kinds. */
static void
-re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
+re_set_exception (struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
@@ -12407,7 +12414,7 @@ re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
/* Reparse the exception conditional expressions. One for each
location. */
- create_excep_cond_exprs (c, ex);
+ create_excep_cond_exprs (c, c->m_kind);
}
/* Returns true if we should stop for this breakpoint hit. If the
@@ -12422,6 +12429,30 @@ should_stop_exception (const struct bp_location *bl)
= (const struct ada_catchpoint_location *) bl;
int stop;
+ struct internalvar *var = lookup_internalvar ("_ada_exception");
+ if (c->m_kind == ada_catch_assert)
+ clear_internalvar (var);
+ else
+ {
+ try
+ {
+ const char *expr;
+
+ if (c->m_kind == ada_catch_handlers)
+ expr = ("GNAT_GCC_exception_Access(gcc_exception)"
+ ".all.occurrence.id");
+ else
+ expr = "e";
+
+ struct value *exc = parse_and_eval (expr);
+ set_internalvar (var, exc);
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ clear_internalvar (var);
+ }
+ }
+
/* With no specific exception, should always stop. */
if (c->excep_string.empty ())
return 1;
@@ -12455,7 +12486,7 @@ should_stop_exception (const struct bp_location *bl)
for all exception catchpoint kinds. */
static void
-check_status_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
+check_status_exception (bpstat bs)
{
bs->stop = should_stop_exception (bs->bp_location_at);
}
@@ -12464,7 +12495,7 @@ check_status_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
for all exception catchpoint kinds. */
static enum print_stop_action
-print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
+print_it_exception (bpstat bs)
{
struct ui_out *uiout = current_uiout;
struct breakpoint *b = bs->breakpoint_at;
@@ -12490,13 +12521,14 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
ada_find_printable_frame). */
select_frame (get_current_frame ());
- switch (ex)
+ struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+ switch (c->m_kind)
{
case ada_catch_exception:
case ada_catch_exception_unhandled:
case ada_catch_handlers:
{
- const CORE_ADDR addr = ada_exception_name_addr (ex, b);
+ const CORE_ADDR addr = ada_exception_name_addr (c->m_kind, b);
char exception_name[256];
if (addr != 0)
@@ -12520,7 +12552,7 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
it clearer to the user which kind of catchpoint just got
hit. We used ui_out_text to make sure that this extra
info does not pollute the exception name in the MI case. */
- if (ex == ada_catch_exception_unhandled)
+ if (c->m_kind == ada_catch_exception_unhandled)
uiout->text ("unhandled ");
uiout->field_string ("exception-name", exception_name);
}
@@ -12553,8 +12585,7 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
for all exception catchpoint kinds. */
static void
-print_one_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b, struct bp_location **last_loc)
+print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
{
struct ui_out *uiout = current_uiout;
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
@@ -12566,7 +12597,7 @@ print_one_exception (enum ada_exception_catchpoint_kind ex,
uiout->field_skip ("addr");
annotate_field (5);
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
if (!c->excep_string.empty ())
@@ -12610,8 +12641,7 @@ print_one_exception (enum ada_exception_catchpoint_kind ex,
for all exception catchpoint kinds. */
static void
-print_mention_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b)
+print_mention_exception (struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
struct ui_out *uiout = current_uiout;
@@ -12621,7 +12651,7 @@ print_mention_exception (enum ada_exception_catchpoint_kind ex,
uiout->field_signed ("bkptno", b->number);
uiout->text (": ");
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
if (!c->excep_string.empty ())
@@ -12664,12 +12694,11 @@ print_mention_exception (enum ada_exception_catchpoint_kind ex,
for all exception catchpoint kinds. */
static void
-print_recreate_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b, struct ui_file *fp)
+print_recreate_exception (struct breakpoint *b, struct ui_file *fp)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
fprintf_filtered (fp, "catch exception");
@@ -12695,192 +12724,10 @@ print_recreate_exception (enum ada_exception_catchpoint_kind ex,
print_recreate_thread (b, fp);
}
-/* Virtual table for "catch exception" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_exception (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_exception, self);
-}
-
-static void
-re_set_catch_exception (struct breakpoint *b)
-{
- re_set_exception (ada_catch_exception, b);
-}
-
-static void
-check_status_catch_exception (bpstat bs)
-{
- check_status_exception (ada_catch_exception, bs);
-}
-
-static enum print_stop_action
-print_it_catch_exception (bpstat bs)
-{
- return print_it_exception (ada_catch_exception, bs);
-}
-
-static void
-print_one_catch_exception (struct breakpoint *b, struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_exception, b, last_loc);
-}
-
-static void
-print_mention_catch_exception (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_exception, b);
-}
-
-static void
-print_recreate_catch_exception (struct breakpoint *b, struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_exception, b, fp);
-}
-
+/* Virtual tables for various breakpoint types. */
static struct breakpoint_ops catch_exception_breakpoint_ops;
-
-/* Virtual table for "catch exception unhandled" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_exception_unhandled (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_exception_unhandled, self);
-}
-
-static void
-re_set_catch_exception_unhandled (struct breakpoint *b)
-{
- re_set_exception (ada_catch_exception_unhandled, b);
-}
-
-static void
-check_status_catch_exception_unhandled (bpstat bs)
-{
- check_status_exception (ada_catch_exception_unhandled, bs);
-}
-
-static enum print_stop_action
-print_it_catch_exception_unhandled (bpstat bs)
-{
- return print_it_exception (ada_catch_exception_unhandled, bs);
-}
-
-static void
-print_one_catch_exception_unhandled (struct breakpoint *b,
- struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_exception_unhandled, b, last_loc);
-}
-
-static void
-print_mention_catch_exception_unhandled (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_exception_unhandled, b);
-}
-
-static void
-print_recreate_catch_exception_unhandled (struct breakpoint *b,
- struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_exception_unhandled, b, fp);
-}
-
static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops;
-
-/* Virtual table for "catch assert" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_assert (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_assert, self);
-}
-
-static void
-re_set_catch_assert (struct breakpoint *b)
-{
- re_set_exception (ada_catch_assert, b);
-}
-
-static void
-check_status_catch_assert (bpstat bs)
-{
- check_status_exception (ada_catch_assert, bs);
-}
-
-static enum print_stop_action
-print_it_catch_assert (bpstat bs)
-{
- return print_it_exception (ada_catch_assert, bs);
-}
-
-static void
-print_one_catch_assert (struct breakpoint *b, struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_assert, b, last_loc);
-}
-
-static void
-print_mention_catch_assert (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_assert, b);
-}
-
-static void
-print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_assert, b, fp);
-}
-
static struct breakpoint_ops catch_assert_breakpoint_ops;
-
-/* Virtual table for "catch handlers" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_handlers (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_handlers, self);
-}
-
-static void
-re_set_catch_handlers (struct breakpoint *b)
-{
- re_set_exception (ada_catch_handlers, b);
-}
-
-static void
-check_status_catch_handlers (bpstat bs)
-{
- check_status_exception (ada_catch_handlers, bs);
-}
-
-static enum print_stop_action
-print_it_catch_handlers (bpstat bs)
-{
- return print_it_exception (ada_catch_handlers, bs);
-}
-
-static void
-print_one_catch_handlers (struct breakpoint *b,
- struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_handlers, b, last_loc);
-}
-
-static void
-print_mention_catch_handlers (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_handlers, b);
-}
-
-static void
-print_recreate_catch_handlers (struct breakpoint *b,
- struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_handlers, b, fp);
-}
-
static struct breakpoint_ops catch_handlers_breakpoint_ops;
/* See ada-lang.h. */
@@ -13154,7 +13001,7 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
const struct breakpoint_ops *ops = NULL;
struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string, &ops);
- std::unique_ptr<ada_catchpoint> c (new ada_catchpoint ());
+ std::unique_ptr<ada_catchpoint> c (new ada_catchpoint (ex_kind));
init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
ops, tempflag, disabled, from_tty);
c->excep_string = excep_string;
@@ -14345,43 +14192,43 @@ initialize_ada_catchpoint_ops (void)
ops = &catch_exception_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_exception;
- ops->re_set = re_set_catch_exception;
- ops->check_status = check_status_catch_exception;
- ops->print_it = print_it_catch_exception;
- ops->print_one = print_one_catch_exception;
- ops->print_mention = print_mention_catch_exception;
- ops->print_recreate = print_recreate_catch_exception;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_exception_unhandled_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_exception_unhandled;
- ops->re_set = re_set_catch_exception_unhandled;
- ops->check_status = check_status_catch_exception_unhandled;
- ops->print_it = print_it_catch_exception_unhandled;
- ops->print_one = print_one_catch_exception_unhandled;
- ops->print_mention = print_mention_catch_exception_unhandled;
- ops->print_recreate = print_recreate_catch_exception_unhandled;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_assert_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_assert;
- ops->re_set = re_set_catch_assert;
- ops->check_status = check_status_catch_assert;
- ops->print_it = print_it_catch_assert;
- ops->print_one = print_one_catch_assert;
- ops->print_mention = print_mention_catch_assert;
- ops->print_recreate = print_recreate_catch_assert;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_handlers_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_handlers;
- ops->re_set = re_set_catch_handlers;
- ops->check_status = check_status_catch_handlers;
- ops->print_it = print_it_catch_handlers;
- ops->print_one = print_one_catch_handlers;
- ops->print_mention = print_mention_catch_handlers;
- ops->print_recreate = print_recreate_catch_handlers;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
}
/* This module's 'new_objfile' observer. */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a129ea0aa1b..c3ed62002f8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4788,9 +4788,16 @@ called @code{Constraint_Error} is defined in package @code{Pck}, then
the command to use to catch such exceptions is @kbd{catch exception
Pck.Constraint_Error}.
+@vindex $_ada_exception@r{, convenience variable}
+The convenience variable @code{$_ada_exception} holds the address of
+the exception being thrown. This can be useful when setting a
+condition for such a catchpoint.
+
@item exception unhandled
@kindex catch exception unhandled
-An exception that was raised but is not handled by the program.
+An exception that was raised but is not handled by the program. The
+convenience variable @code{$_ada_exception} is set as for @code{catch
+exception}.
@item handlers @r{[}@var{name}@r{]}
@kindex catch handlers
@@ -4812,9 +4819,13 @@ user-defined one. For instance, assuming an exception called
command to use to catch such exceptions handling is
@kbd{catch handlers Pck.Constraint_Error}.
+The convenience variable @code{$_ada_exception} is set as for
+@code{catch exception}.
+
@item assert
@kindex catch assert
-A failed Ada assertion.
+A failed Ada assertion. Note that the convenience variable
+@code{$_ada_exception} is @emph{not} set by this catchpoint.
@item exec
@kindex catch exec
@@ -11823,6 +11834,11 @@ The program has exited
The variable @code{$_exception} is set to the exception object being
thrown at an exception-related catchpoint. @xref{Set Catchpoints}.
+@item $_ada_exception
+The variable @code{$_ada_exception} is set to the address of the
+exception being caught or thrown at an Ada exception-related
+catchpoint. @xref{Set Catchpoints}.
+
@item $_probe_argc
@itemx $_probe_arg0@dots{}$_probe_arg11
Arguments to a static probe. @xref{Static Probe Points}.
diff --git a/gdb/testsuite/gdb.ada/catch_ex_std.exp b/gdb/testsuite/gdb.ada/catch_ex_std.exp
index 63714a8aa81..839d0bb092f 100644
--- a/gdb/testsuite/gdb.ada/catch_ex_std.exp
+++ b/gdb/testsuite/gdb.ada/catch_ex_std.exp
@@ -101,3 +101,6 @@ gdb_test "catch exception some_kind_of_error" \
gdb_test "cont" \
"Catchpoint \[0-9\]+, .* at .*foo\.adb:\[0-9\]+.*" \
"caught the exception"
+
+gdb_test "print \$_ada_exception = some_package.some_kind_of_error'Address" \
+ " = true"
--
2.20.1
next prev parent reply other threads:[~2019-09-20 19:20 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-20 19:20 [PATCH v2 0/8] Handle copy relocations and add $_ada_exception Tom Tromey
2019-09-20 19:20 ` [PATCH v2 1/8] Change SYMBOL_VALUE_ADDRESS to be an rvalue Tom Tromey
2019-09-20 19:20 ` [PATCH v2 7/8] Back out earlier Ada exception change Tom Tromey
2019-09-20 19:20 ` Tom Tromey [this message]
2019-09-20 19:20 ` [PATCH v2 6/8] Make print-file-var.exp test attribute visibility hidden, dlopen, and main symbol Tom Tromey
2019-09-23 14:52 ` Andrew Burgess
2019-10-01 14:11 ` Tom Tromey
2019-09-20 19:20 ` [PATCH v2 3/8] Don't call decode_line_with_current_source from select_source_symtab Tom Tromey
2019-09-20 19:20 ` [PATCH v2 2/8] Search global block from basic_lookup_symbol_nonlocal Tom Tromey
2019-09-21 4:32 ` Christian Biesinger via gdb-patches
2019-09-23 14:17 ` Andrew Burgess
2019-10-02 15:51 ` Tom Tromey
2019-11-09 6:54 ` Christian Biesinger via gdb-patches
2019-09-20 19:27 ` [PATCH v2 5/8] Handle copy relocations Tom Tromey
2019-09-20 19:27 ` [PATCH v2 4/8] Make current_source_* per-program-space Tom Tromey
2019-09-23 14:56 ` [PATCH v2 0/8] Handle copy relocations and add $_ada_exception Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190920192017.15293-9-tromey@adacore.com \
--to=tromey@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox