From a38118e5d165324b4f9509fd82cf1f1c6421bfc5 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 9 Jul 2019 19:26:16 +0100 Subject: [PATCH] Make "maint info breakpoints" show "catch catch/throw/rethrow" locations This commit makes "maint info breakpoints" show the internal locations of C++ exception catchpoints: (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 "" (gdb) maint info breakpoints Num Type Disp Enb Address What 3 catchpoint keep y signal "" inf 1 (gdb) 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. gdb/ChangeLog: 2019-07-09 Pedro Alves * 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/ChangeLog | 11 +++++ gdb/break-catch-throw.c | 8 ++++ gdb/breakpoint.c | 115 +++++++++++++++++++----------------------------- gdb/breakpoint.h | 5 +++ 4 files changed, 69 insertions(+), 70 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9ceb425..112b460 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2019-07-09 Pedro Alves + * 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. + +2019-07-09 Pedro Alves + * break-catch-throw.c (print_one_exception_catchpoint): Skip the "addr" field. (allocate_location_exception_catchpoint): New. diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index c0b3eec..17e3d26 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 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 1cdeade..5435de1 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", ""); - else if (b->loc == NULL || loc->shlib_disabled) - uiout->field_string ("addr", ""); - 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", ""); + else if (b->loc == NULL || loc->shlib_disabled) + uiout->field_string ("addr", ""); + 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 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 users. + + Likewise, while catchpoints may be implemented with + breakpoints (e.g., catch throw), that's not a property + exposed to users. 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 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 bcfa45b..e25acfa 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.7.4