From patchwork Thu Aug 1 17:04:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 33901 Received: (qmail 117215 invoked by alias); 1 Aug 2019 17:04:25 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 117037 invoked by uid 89); 1 Aug 2019 17:04:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=observer 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; Thu, 01 Aug 2019 17:04:20 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 7CE1C56053; Thu, 1 Aug 2019 13:04:17 -0400 (EDT) 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 ZzGo712acoGk; Thu, 1 Aug 2019 13:04:17 -0400 (EDT) Received: from murgatroyd.Home (97-122-178-82.hlrn.qwest.net [97.122.178.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPSA id 271FE56018; Thu, 1 Aug 2019 13:04:17 -0400 (EDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH v2 7/8] Add $_ada_exception convenience variable Date: Thu, 1 Aug 2019 11:04:11 -0600 Message-Id: <20190801170412.5553-8-tromey@adacore.com> In-Reply-To: <20190801170412.5553-1-tromey@adacore.com> References: <20190801170412.5553-1-tromey@adacore.com> MIME-Version: 1.0 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. 2019-08-01 Tom Tromey * NEWS: Add $_ada_exception entry. * ada-lang.c (struct ada_catchpoint): Add constructor. : 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-01 Tom Tromey * gdb.texinfo (Set Catchpoints, Convenience Vars): Document $_ada_exception. gdb/testsuite/ChangeLog 2019-08-01 Tom Tromey * 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 | 19 +- gdb/testsuite/ChangeLog | 4 + gdb/testsuite/gdb.ada/catch_ex_std.exp | 3 + 7 files changed, 141 insertions(+), 232 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index ac44399304c..6bee9b13a38 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -25,6 +25,9 @@ provide the exitcode or exit status of the shell commands launched by GDB commands such as "shell", "pipe" and "make". +* 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 6851386b48b..286eca3bfa1 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -12275,8 +12275,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 @@ -12336,8 +12344,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); } @@ -12346,7 +12353,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; @@ -12356,7 +12363,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 @@ -12371,6 +12378,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; @@ -12404,7 +12435,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); } @@ -12413,7 +12444,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; @@ -12439,13 +12470,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) @@ -12469,7 +12501,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); } @@ -12502,8 +12534,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; @@ -12515,7 +12546,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 ()) @@ -12559,8 +12590,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; @@ -12570,7 +12600,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 ()) @@ -12613,12 +12643,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"); @@ -12644,192 +12673,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. */ @@ -13103,7 +12950,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 c (new ada_catchpoint ()); + std::unique_ptr 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; @@ -14294,43 +14141,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 0fcd131f71e..ae266d4bfac 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4788,9 +4788,15 @@ 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}. +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 +4818,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 @@ -11742,6 +11752,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"