This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 2/2] "catch catch/throw/rethrow", breakpoint -> catchpoint
* Pedro Alves <palves@redhat.com> [2019-07-09 16:47:27 +0100]:
> On 7/9/19 10:55 AM, Andrew Burgess wrote:
>
> >> This commit hides the addresses from view, and makes GDB show
> >> "catchpoint" for type as well:
> >>
> >> (gdb) info breakpoints
> >> Num Type Disp Enb Address What
> >> 1 catchpoint keep y exception catch
> >> 2 catchpoint keep y exception throw
> >> 3 catchpoint keep y exception rethrow
> >>
> >
> > I agree for users knowing the address is probably not helpful, but we
> > also have 'maintenance info breakpoints'. I think it might (one day)
> > be helpful if we _did_ print the address in the maintenance version of
> > the command.
>
> Indeed, that crossed my mind too, though at first I thought it would
> be easier to do with my "always show locations" change.
>
> So, the additional patch below gets us this:
>
> (gdb) info breakpoints
> Num Type Disp Enb Address What
> 2 catchpoint keep y exception catch
>
> With multiple locations:
>
> (gdb) maint info breakpoints
> Num Type Disp Enb Address What
> 2 catchpoint keep y exception catch
> 2.1 y 0x000000000040545f <__cxa_begin_catch+95> inf 1
> 2.2 y 0x00007ffff71dbe0f <__cxxabiv1::__cxa_begin_catch(void*)+95> inf 1
> (gdb)
>
> With a single location:
>
> (gdb) maint info breakpoints 2
> Num Type Disp Enb Address What
> 2 catchpoint keep y exception catch inf 1
> 2.1 y 0x00007ffff7bc0b7f <__cxa_begin_catch+95> inf 1
>
> With no locations:
>
> (gdb) maint info breakpoints 2
> Num Type Disp Enb Address What
> 2 catchpoint keep y exception catch inf 1
>
>
> Other catchpoints still show the same way, here a catch signal:
>
> (gdb) info breakpoints
> Num Type Disp Enb Address What
> 3 catchpoint keep y signal "<standard signals>"
>
> (gdb) maint info breakpoints
> Num Type Disp Enb Address What
> 3 catchpoint keep y signal "<standard signals>" inf 1
> (gdb)
>
> WDYT?
This looks good to me.
Thanks,
Andrew
>
> Note: I considered making the locations be printed from within
> breakpoint_ops::print_one(), but gave up given the handling
> for the broken MI v2 output:
>
> /* The mi2 broken format: the main breakpoint tuple ends here, the locations
> are outside. */
> if (!use_fixed_output)
> bkpt_tuple_emitter.reset ();
>
> in print_one_breakpoint.
>
> From 3f315479a9b802d8da92116d49637f73dbb1b483 Mon Sep 17 00:00:00 2001
> From: Pedro Alves <palves@redhat.com>
> Date: Tue, 9 Jul 2019 12:40:25 +0100
> Subject: [PATCH] Make "maint info breakpoints" show "catch
> catch/throw/rethrow" locations
>
> gdb/ChangeLog:
> yyyy-mm-dd Pedro Alves <palves@redhat.com>
>
> * break-catch-throw.c (is_exception_catchpoint): New.
> * breakpoint.c (print_one_breakpoint_location): New parameter
> 'raw_loc'. Handle it. Use
> is_watchpoint/is_catchpoint/is_exception_catchpoint instead of
> looking at the breakpoint's type.
> (print_one_breakpoint): If handling "maint info breakpoints", also
> print locations of exception catchpoints.
> * breakpoint.h (is_exception_catchpoint): Declare.
> ---
> gdb/break-catch-throw.c | 8 ++++
> gdb/breakpoint.c | 115 +++++++++++++++++++-----------------------------
> gdb/breakpoint.h | 5 +++
> 3 files changed, 58 insertions(+), 70 deletions(-)
>
> diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
> index c0b3eec63d1..17e3d26d376 100644
> --- a/gdb/break-catch-throw.c
> +++ b/gdb/break-catch-throw.c
> @@ -83,6 +83,14 @@ struct exception_catchpoint : public breakpoint
> std::unique_ptr<compiled_regex> pattern;
> };
>
> +/* See breakpoint.h. */
> +
> +bool
> +is_exception_catchpoint (breakpoint *bp)
> +{
> + return bp->ops == &gnu_v3_exception_catchpoint_ops;
> +}
> +
>
>
> /* A helper function that fetches exception probe arguments. This
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index 36500758257..25b3dc17476 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -5974,14 +5974,18 @@ output_thread_groups (struct ui_out *uiout,
> }
> }
>
> -/* Print B to gdb_stdout. */
> +/* Print B to gdb_stdout. If RAW_LOC, print raw breakpoint locations
> + instead of going via breakpoint_ops::print_one. This makes "maint
> + info breakpoints" show the software breakpoint locations of
> + catchpoints, which are considered internal implementation
> + detail. */
>
> static void
> print_one_breakpoint_location (struct breakpoint *b,
> struct bp_location *loc,
> int loc_number,
> struct bp_location **last_loc,
> - int allflag)
> + int allflag, bool raw_loc)
> {
> struct command_line *l;
> static char bpenables[] = "nynny";
> @@ -6034,20 +6038,11 @@ print_one_breakpoint_location (struct breakpoint *b,
> uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
>
> /* 5 and 6 */
> - if (b->ops != NULL && b->ops->print_one != NULL)
> + if (!raw_loc && b->ops != NULL && b->ops->print_one != NULL)
> b->ops->print_one (b, last_loc);
> else
> - switch (b->type)
> - {
> - case bp_none:
> - internal_error (__FILE__, __LINE__,
> - _("print_one_breakpoint: bp_none encountered\n"));
> - break;
> -
> - case bp_watchpoint:
> - case bp_hardware_watchpoint:
> - case bp_read_watchpoint:
> - case bp_access_watchpoint:
> + {
> + if (is_watchpoint (b))
> {
> struct watchpoint *w = (struct watchpoint *) b;
>
> @@ -6059,55 +6054,26 @@ print_one_breakpoint_location (struct breakpoint *b,
> annotate_field (5);
> uiout->field_string ("what", w->exp_string);
> }
> - break;
> -
> - case bp_breakpoint:
> - case bp_hardware_breakpoint:
> - case bp_single_step:
> - case bp_until:
> - case bp_finish:
> - case bp_longjmp:
> - case bp_longjmp_resume:
> - case bp_longjmp_call_dummy:
> - case bp_exception:
> - case bp_exception_resume:
> - case bp_step_resume:
> - case bp_hp_step_resume:
> - case bp_watchpoint_scope:
> - case bp_call_dummy:
> - case bp_std_terminate:
> - case bp_shlib_event:
> - case bp_thread_event:
> - case bp_overlay_event:
> - case bp_longjmp_master:
> - case bp_std_terminate_master:
> - case bp_exception_master:
> - case bp_tracepoint:
> - case bp_fast_tracepoint:
> - case bp_static_tracepoint:
> - case bp_dprintf:
> - case bp_jit_event:
> - case bp_gnu_ifunc_resolver:
> - case bp_gnu_ifunc_resolver_return:
> - if (opts.addressprint)
> - {
> - annotate_field (4);
> - if (header_of_multiple)
> - uiout->field_string ("addr", "<MULTIPLE>");
> - else if (b->loc == NULL || loc->shlib_disabled)
> - uiout->field_string ("addr", "<PENDING>");
> - else
> - uiout->field_core_addr ("addr",
> - loc->gdbarch, loc->address);
> - }
> - annotate_field (5);
> - if (!header_of_multiple)
> - print_breakpoint_location (b, loc);
> - if (b->loc)
> - *last_loc = b->loc;
> - break;
> - }
> -
> + else if (!is_catchpoint (b) || is_exception_catchpoint (b))
> + {
> + if (opts.addressprint)
> + {
> + annotate_field (4);
> + if (header_of_multiple)
> + uiout->field_string ("addr", "<MULTIPLE>");
> + else if (b->loc == NULL || loc->shlib_disabled)
> + uiout->field_string ("addr", "<PENDING>");
> + else
> + uiout->field_core_addr ("addr",
> + loc->gdbarch, loc->address);
> + }
> + annotate_field (5);
> + if (!header_of_multiple)
> + print_breakpoint_location (b, loc);
> + if (b->loc)
> + *last_loc = b->loc;
> + }
> + }
>
> if (loc != NULL && !header_of_multiple)
> {
> @@ -6336,7 +6302,7 @@ print_one_breakpoint (struct breakpoint *b,
> || fix_multi_location_breakpoint_output_globally);
>
> gdb::optional<ui_out_emit_tuple> bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt");
> - print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
> + print_one_breakpoint_location (b, NULL, 0, last_loc, allflag, false);
>
> /* The mi2 broken format: the main breakpoint tuple ends here, the locations
> are outside. */
> @@ -6346,7 +6312,9 @@ print_one_breakpoint (struct breakpoint *b,
> /* If this breakpoint has custom print function,
> it's already printed. Otherwise, print individual
> locations, if any. */
> - if (b->ops == NULL || b->ops->print_one == NULL)
> + if (b->ops == NULL
> + || b->ops->print_one == NULL
> + || allflag)
> {
> /* If breakpoint has a single location that is disabled, we
> print it as if it had several locations, since otherwise it's
> @@ -6354,10 +6322,16 @@ print_one_breakpoint (struct breakpoint *b,
> situation.
>
> Note that while hardware watchpoints have several locations
> - internally, that's not a property exposed to user. */
> - if (b->loc
> - && !is_hardware_watchpoint (b)
> - && (b->loc->next || !b->loc->enabled))
> + internally, that's not a property exposed to user.
> +
> + Likewise, while catchpoints may be implemented with
> + breakpoints (e.g., catch throw), that's not a property
> + exposed to user. We do however display the internal
> + breakpoint locations with "maint info breakpoints". */
> + if (!is_hardware_watchpoint (b)
> + && (!is_catchpoint (b) || is_exception_catchpoint (b))
> + && (allflag
> + || (b->loc && (b->loc->next || !b->loc->enabled))))
> {
> gdb::optional<ui_out_emit_list> locations_list;
>
> @@ -6371,7 +6345,8 @@ print_one_breakpoint (struct breakpoint *b,
> for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n)
> {
> ui_out_emit_tuple loc_tuple_emitter (uiout, NULL);
> - print_one_breakpoint_location (b, loc, n, last_loc, allflag);
> + print_one_breakpoint_location (b, loc, n, last_loc,
> + allflag, allflag);
> }
> }
> }
> diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
> index 6e9a35e82de..43dfa05bbb8 100644
> --- a/gdb/breakpoint.h
> +++ b/gdb/breakpoint.h
> @@ -872,6 +872,11 @@ extern int is_breakpoint (const struct breakpoint *bpt);
>
> extern int is_watchpoint (const struct breakpoint *bpt);
>
> +/* Return true if BPT is a C++ exception catchpoint (catch
> + catch/throw/rethrow). */
> +
> +extern bool is_exception_catchpoint (breakpoint *bp);
> +
> /* An instance of this type is used to represent all kinds of
> tracepoints. */
>
> --
> 2.14.5
>