Message ID | 28eb4028-87a7-9929-5cb1-d8c3f96544e9@redhat.com |
---|---|
State | New |
Headers | show |
>>>>> "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 >
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. */