[2/2] "catch catch/throw/rethrow", breakpoint -> catchpoint
Commit Message
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?
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(-)
Comments
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
Pedro> (gdb) maint info breakpoints
Pedro> Num Type Disp Enb Address What
Pedro> 2 catchpoint keep y exception catch
Pedro> 2.1 y 0x000000000040545f <__cxa_begin_catch+95> inf 1
Pedro> 2.2 y 0x00007ffff71dbe0f <__cxxabiv1::__cxa_begin_catch(void*)+95> inf 1
Pedro> (gdb)
Pedro> WDYT?
This looks great to me.
Pedro> Note: I considered making the locations be printed from within
Pedro> breakpoint_ops::print_one(), but gave up given the handling
Pedro> for the broken MI v2 output:
Pedro> /* The mi2 broken format: the main breakpoint tuple ends here, the locations
Pedro> are outside. */
Pedro> if (!use_fixed_output)
Pedro> bkpt_tuple_emitter.reset ();
Pedro> in print_one_breakpoint.
Ouch. It would be nice if we could find a way to make the backward
compatibility hacks not impact the main code. Like, hacks in
mi/something.c somewhere instead would be preferable.
Tom
* 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
>
@@ -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
@@ -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);
}
}
}
@@ -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. */