From 205bb562e7f46061958efaa3c03ea35ab699d184 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 17 May 2022 13:12:04 +0100 Subject: [PATCH] Introduce "info breakpoints -hide-locations" This commit adds a new option to "info breakpoints", "-hide-locations". It's purpose is to tell GDB to skip printing breakpoint locations, printing only the breakpoint header rows. And then, since only code breakpoint locations print anything in the "Address" column, "-hide-breakpoints" also disables the "Address" column. For example, when debugging GDB, you can use the new options to get this: (top-gdb) i b -h Num Type Disp Enb What 1 breakpoint keep y internal_error 2 breakpoint keep y info_command silent return 3 breakpoint keep y main breakpoint already hit 1 time 4 breakpoint keep y error (top-gdb) instead of: (top-gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y internal_error 1.1 y 0x0000555555f81d12 in internal_error(char const*, int, char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:51 2 breakpoint keep y info_command silent return 2.1 y 0x00005555557b3097 in info_command(char const*, int) at /home/pedro/gdb/binutils-gdb/src/gdb/cli/cli-cmds.c:217 3 breakpoint keep y main breakpoint already hit 1 time 3.1 y 0x000055555564106c in main(int, char**) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:25 3.2 y 0x0000555555dba524 in selftests::string_view::capacity_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/capacity/1.cc:167 3.3 y 0x0000555555dba943 in selftests::string_view::cons_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/1.cc:62 3.4 y 0x0000555555dbaa34 in selftests::string_view::cons_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/2.cc:41 3.5 y 0x0000555555dbaa9a in selftests::string_view::cons_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/3.cc:34 3.6 y 0x0000555555dbac6b in selftests::string_view::element_access_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/1.cc:66 3.7 y 0x0000555555dbac83 in selftests::string_view::element_access_empty::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/empty.cc:25 3.8 y 0x0000555555dbae91 in selftests::string_view::element_access_front_back::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/front_back.cc:38 3.9 y 0x0000555555dbb2bd in selftests::string_view::inserters_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/inserters/char/2.cc:84 3.10 y 0x0000555555dbb429 in selftests::string_view::modifiers_remove_prefix::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/modifiers/remove_prefix/char/1.cc:58 3.11 y 0x0000555555dbb575 in selftests::string_view::modifiers_remove_suffix::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/modifiers/remove_suffix/char/1.cc:58 3.12 y 0x0000555555dbbd38 in selftests::string_view::operations_compare_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/compare/char/1.cc:127 3.13 y 0x0000555555dbbe7b in selftests::string_view::operations_compare_13650::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/compare/char/13650.cc:45 3.14 y 0x0000555555dbbf6a in selftests::string_view::operations_copy_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/copy/char/1.cc:41 3.15 y 0x0000555555dbc03b in selftests::string_view::operations_data_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/data/char/1.cc:39 3.16 y 0x0000555555dbc5fe in selftests::string_view::operations_find_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/1.cc:160 3.17 y 0x0000555555dbcb60 in selftests::string_view::operations_find_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/2.cc:158 3.18 y 0x0000555555dbd1c1 in selftests::string_view::operations_find_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/3.cc:158 3.19 y 0x0000555555dbd26c in selftests::string_view::operations_find_4::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/4.cc:40 3.20 y 0x0000555555dbd83f in selftests::string_view::operations_rfind_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/1.cc:90 3.21 y 0x0000555555dbda98 in selftests::string_view::operations_rfind_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/2.cc:48 3.22 y 0x0000555555dbde4c in selftests::string_view::operations_rfind_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/3.cc:63 3.23 y 0x0000555555dbe189 in selftests::string_view::operations_substr_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/substr/char/1.cc:74 3.24 y 0x0000555555dbffdb in selftests::string_view::operators_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operators/char/2.cc:366 4 breakpoint keep y error 4.1 y 0x00005555557f5142 in gcc_c_plugin::error(char const*) const at /home/pedro/gdb/binutils-gdb/src/gdb/../include/gcc-c-fe.def:198 4.2 y 0x00005555557fe1f4 in gcc_cp_plugin::error(char const*) const at /home/pedro/gdb/binutils-gdb/src/gdb/../include/gcc-cp-fe.def:983 4.3 y 0x0000555555f81c5e in error(char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:39 4.4 y 0x00007ffff65ee4e0 4.5 y 0x00007ffff685e070 4.6 y 0x00007ffff6cd4e86 in error at /usr/include/x86_64-linux-gnu/bits/error.h:40 4.7 y 0x00007ffff71c2190 in __error at error.c:274 Documentation change included. No testsuite changes yet until there's agreement on the previous patch. Change-Id: Ic42ad8565e79ca67bfebb22cbb4794ea816fd08b --- gdb/ada-lang.c | 9 +-- gdb/break-catch-exec.c | 10 ++- gdb/break-catch-fork.c | 10 ++- gdb/break-catch-load.c | 8 +-- gdb/break-catch-sig.c | 10 ++- gdb/break-catch-syscall.c | 9 ++- gdb/break-catch-throw.c | 10 ++- gdb/breakpoint.c | 139 ++++++++++++++++++++++++++++++-------- gdb/breakpoint.h | 5 +- gdb/cli/cli-option.c | 12 +++- gdb/cli/cli-option.h | 6 ++ gdb/doc/gdb.texinfo | 33 +++++++-- 12 files changed, 183 insertions(+), 78 deletions(-) diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 6ab01fd27d4..4229b116221 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -12153,7 +12153,7 @@ struct ada_catchpoint : public code_breakpoint void re_set () override; void check_status (struct bpstat *bs) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -12421,14 +12421,11 @@ ada_catchpoint::print_it (const bpstat *bs) const catchpoint kinds. */ bool -ada_catchpoint::print_one (bp_location **last_loc) const +ada_catchpoint::print_one (bp_location **last_loc, bool print_address_col) const { struct ui_out *uiout = current_uiout; - struct value_print_options opts; - get_user_print_options (&opts); - - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); diff --git a/gdb/break-catch-exec.c b/gdb/break-catch-exec.c index 07417ee499c..d0fb38cf768 100644 --- a/gdb/break-catch-exec.c +++ b/gdb/break-catch-exec.c @@ -49,7 +49,7 @@ struct exec_catchpoint : public catchpoint CORE_ADDR bp_addr, const target_waitstatus &ws) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -110,17 +110,15 @@ exec_catchpoint::print_it (const bpstat *bs) const } bool -exec_catchpoint::print_one (bp_location **last_loc) const +exec_catchpoint::print_one (bp_location **last_loc, + bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; - get_user_print_options (&opts); - /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); uiout->text ("exec"); diff --git a/gdb/break-catch-fork.c b/gdb/break-catch-fork.c index 1f8deec6a62..9848d7a22cf 100644 --- a/gdb/break-catch-fork.c +++ b/gdb/break-catch-fork.c @@ -49,7 +49,7 @@ struct fork_catchpoint : public catchpoint CORE_ADDR bp_addr, const target_waitstatus &ws) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool print_address_col) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -136,17 +136,15 @@ fork_catchpoint::print_it (const bpstat *bs) const /* Implement the "print_one" method for fork catchpoints. */ bool -fork_catchpoint::print_one (bp_location **last_loc) const +fork_catchpoint::print_one (bp_location **last_loc, + bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; - get_user_print_options (&opts); - /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); const char *name = is_vfork ? "vfork" : "fork"; diff --git a/gdb/break-catch-load.c b/gdb/break-catch-load.c index 617ee2b694d..9a91fd264d8 100644 --- a/gdb/break-catch-load.c +++ b/gdb/break-catch-load.c @@ -56,7 +56,7 @@ struct solib_catchpoint : public catchpoint const target_waitstatus &ws) override; void check_status (struct bpstat *bs) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -159,16 +159,14 @@ solib_catchpoint::print_it (const bpstat *bs) const } bool -solib_catchpoint::print_one (bp_location **locs) const +solib_catchpoint::print_one (bp_location **locs, bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; - get_user_print_options (&opts); /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) { annotate_field (4); uiout->field_skip ("addr"); diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c index 57a6255dc33..29276a4cf23 100644 --- a/gdb/break-catch-sig.c +++ b/gdb/break-catch-sig.c @@ -57,7 +57,7 @@ struct signal_catchpoint : public catchpoint CORE_ADDR bp_addr, const target_waitstatus &ws) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; bool explains_signal (enum gdb_signal) override; @@ -213,17 +213,15 @@ signal_catchpoint::print_it (const bpstat *bs) const /* Implement the "print_one" method for signal catchpoints. */ bool -signal_catchpoint::print_one (bp_location **last_loc) const +signal_catchpoint::print_one (bp_location **last_loc, + bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; - get_user_print_options (&opts); - /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c index 06d48466de7..6ee9277fee5 100644 --- a/gdb/break-catch-syscall.c +++ b/gdb/break-catch-syscall.c @@ -52,7 +52,7 @@ struct syscall_catchpoint : public catchpoint CORE_ADDR bp_addr, const target_waitstatus &ws) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -238,17 +238,16 @@ syscall_catchpoint::print_it (const bpstat *bs) const /* Implement the "print_one" method for syscall catchpoints. */ bool -syscall_catchpoint::print_one (bp_location **last_loc) const +syscall_catchpoint::print_one (bp_location **last_loc, + bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; struct gdbarch *gdbarch = loc->owner->gdbarch; - get_user_print_options (&opts); /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 66cf80be1c5..0e0e259cf6a 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -87,7 +87,7 @@ struct exception_catchpoint : public code_breakpoint void re_set () override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; void print_one_detail (struct ui_out *) const override; @@ -271,14 +271,12 @@ exception_catchpoint::print_it (const bpstat *bs) const } bool -exception_catchpoint::print_one (bp_location **last_loc) const +exception_catchpoint::print_one (bp_location **last_loc, + bool print_address_col) const { - struct value_print_options opts; struct ui_out *uiout = current_uiout; - get_user_print_options (&opts); - - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 964f87db0ba..59abf25555a 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -370,7 +370,7 @@ struct ranged_breakpoint : public ordinary_breakpoint const target_waitstatus &ws) override; int resources_needed (const struct bp_location *) override; enum print_stop_action print_it (const bpstat *bs) const override; - bool print_one (bp_location **) const override; + bool print_one (bp_location **, bool) const override; void print_one_detail (struct ui_out *) const override; void print_mention () const override; void print_recreate (struct ui_file *fp) const override; @@ -6174,6 +6174,34 @@ output_thread_groups (struct ui_out *uiout, } } +/* The options for the "info breakpoints" command. */ + +struct info_breakpoints_opts +{ + /* For "-hide-locations". */ + bool hide_locations = 0; +}; + +static const gdb::option::option_def info_breakpoints_option_defs[] = { + + gdb::option::flag_option_def { + "hide-locations", + [] (info_breakpoints_opts *opts) { return &opts->hide_locations; }, + N_("Hide breakpoint locations."), + }, + +}; + +/* Create an option_def_group for the "info breakpoints" options, with + OPTS as context. */ + +static inline gdb::option::option_def_group +make_info_breakpoints_options_def_group (info_breakpoints_opts *opts) +{ + return {{info_breakpoints_option_defs}, opts}; +} + + /* 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 @@ -6186,15 +6214,13 @@ print_one_breakpoint_location (struct breakpoint *b, struct bp_location *loc, int loc_number, struct bp_location **last_loc, - int allflag, bool raw_loc) + int allflag, bool raw_loc, + bool print_address_col) { struct command_line *l; static char bpenables[] = "nynny"; struct ui_out *uiout = current_uiout; - struct value_print_options opts; - - get_user_print_options (&opts); gdb_assert (!loc || loc_number != 0); @@ -6240,7 +6266,7 @@ print_one_breakpoint_location (struct breakpoint *b, /* 5 and 6 */ bool result = false; - if (!raw_loc && b->print_one (last_loc)) + if (!raw_loc && b->print_one (last_loc, print_address_col)) result = true; else { @@ -6251,7 +6277,7 @@ print_one_breakpoint_location (struct breakpoint *b, /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect is relatively readable). */ - if (opts.addressprint) + if (print_address_col) uiout->field_skip ("addr"); annotate_field (5); uiout->field_string ("what", w->exp_string.get ()); @@ -6259,7 +6285,7 @@ print_one_breakpoint_location (struct breakpoint *b, else if (!is_catchpoint (b) || is_exception_catchpoint (b) || is_ada_exception_catchpoint (b)) { - if (opts.addressprint) + if (print_address_col) { annotate_field (4); if (loc == nullptr) @@ -6498,6 +6524,18 @@ print_one_breakpoint_location (struct breakpoint *b, return result; } +/* Return whether to print the "Address" column. The "Address" column + is suppressed with either "set print address off", or "info + breakpoints -hide-locations". */ + +static bool +should_print_address_col (const info_breakpoints_opts &ib_opts) +{ + struct value_print_options opts; + get_user_print_options (&opts); + return opts.addressprint && !ib_opts.hide_locations; +} + /* See breakpoint.h. */ bool fix_multi_location_breakpoint_output_globally = false; @@ -6505,26 +6543,29 @@ bool fix_multi_location_breakpoint_output_globally = false; static void print_one_breakpoint (struct breakpoint *b, struct bp_location **last_loc, - int allflag) + int allflag, + const info_breakpoints_opts &ib_opts) { struct ui_out *uiout = current_uiout; bool use_fixed_output = (uiout->test_flags (fix_multi_location_breakpoint_output) || fix_multi_location_breakpoint_output_globally); + bool print_address_col = should_print_address_col (ib_opts); + gdb::optional bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt"); bool printed = print_one_breakpoint_location (b, NULL, 0, last_loc, - allflag, false); + allflag, false, print_address_col); /* The mi2 broken format: the main breakpoint tuple ends here, the locations are outside. */ if (!use_fixed_output) bkpt_tuple_emitter.reset (); - /* If this breakpoint has custom print function, - it's already printed. Otherwise, print individual - locations, if any. */ - if (!printed || allflag) + /* If this breakpoint has a custom print function, it's already + printed. Otherwise, print individual locations, if any, and if + not explicitly disabled by the user. */ + if (!ib_opts.hide_locations && (!printed || allflag)) { /* Note that while hardware watchpoints have several locations internally, that's not a property exposed to users. @@ -6552,7 +6593,8 @@ print_one_breakpoint (struct breakpoint *b, { ui_out_emit_tuple loc_tuple_emitter (uiout, NULL); print_one_breakpoint_location (b, loc, n, last_loc, - allflag, allflag); + allflag, allflag, + print_address_col); n++; } } @@ -6582,8 +6624,9 @@ breakpoint_address_bits (struct breakpoint *b) void print_breakpoint (breakpoint *b) { + info_breakpoints_opts ib_opts; struct bp_location *dummy_loc = NULL; - print_one_breakpoint (b, &dummy_loc, 0); + print_one_breakpoint (b, &dummy_loc, 0, ib_opts); } /* Return true if this breakpoint was set by the user, false if it is @@ -6605,9 +6648,9 @@ pending_breakpoint_p (struct breakpoint *b) /* Print information on breakpoints (including watchpoints and tracepoints). - If non-NULL, BP_NUM_LIST is a list of numbers and number ranges as - understood by number_or_range_parser. Only breakpoints included in this - list are then printed. + If non-NULL, ARGS possibly contains options, followed by a list of + numbers and number ranges as understood by number_or_range_parser. + Only breakpoints included in this list are then printed. If SHOW_INTERNAL is true, print internal breakpoints. @@ -6617,18 +6660,30 @@ pending_breakpoint_p (struct breakpoint *b) Return the total number of breakpoints listed. */ static int -breakpoint_1 (const char *bp_num_list, bool show_internal, +breakpoint_1 (const char *args, bool show_internal, bool (*filter) (const struct breakpoint *)) { struct bp_location *last_loc = NULL; int nr_printable_breakpoints; - struct value_print_options opts; int print_address_bits = 0; int print_type_col_width = 14; struct ui_out *uiout = current_uiout; bool has_disabled_by_cond_location = false; - get_user_print_options (&opts); + info_breakpoints_opts ib_opts; + + auto grp = make_info_breakpoints_options_def_group (&ib_opts); + + gdb::option::process_options + (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp); + + if (args != nullptr + && args[0] == '-' && (!show_internal || !isdigit (args[1]))) + gdb::option::error_unrecognized_option_at (args); + + const char *bp_num_list = args; + + bool print_address_col = should_print_address_col (ib_opts); /* Compute the number of rows in the table, as well as the size required for address fields. */ @@ -6667,7 +6722,7 @@ breakpoint_1 (const char *bp_num_list, bool show_internal, { ui_out_emit_table table_emitter (uiout, - opts.addressprint ? 6 : 5, + print_address_col ? 6 : 5, nr_printable_breakpoints, "BreakpointTable"); @@ -6685,7 +6740,7 @@ breakpoint_1 (const char *bp_num_list, bool show_internal, if (nr_printable_breakpoints > 0) annotate_field (3); uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */ - if (opts.addressprint) + if (print_address_col) { if (nr_printable_breakpoints > 0) annotate_field (4); @@ -6728,7 +6783,7 @@ breakpoint_1 (const char *bp_num_list, bool show_internal, show_internal is set. */ if (show_internal || user_breakpoint_p (b)) { - print_one_breakpoint (b, &last_loc, show_internal); + print_one_breakpoint (b, &last_loc, show_internal, ib_opts); for (bp_location *loc : b->locations ()) if (loc->disabled_by_cond) has_disabled_by_cond_location = true; @@ -6766,6 +6821,29 @@ breakpoint_1 (const char *bp_num_list, bool show_internal, return nr_printable_breakpoints; } +/* Completer for the "info breakpoints" command. */ + +static void +info_breakpoints_command_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word_ignored) +{ + const auto grp = make_info_breakpoints_options_def_group (nullptr); + + if (gdb::option::complete_options + (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp)) + return; + + /* Convenience to let the user know what the command can accept. */ + if (*text == '\0') + { + gdb::option::complete_on_all_options (tracker, grp); + /* Keep this "ID" in sync with what "help info breakpoints" + says. */ + tracker.add_completion (make_unique_xstrdup ("ID")); + } +} + /* Display the value of default-collect in a way that is generally compatible with the breakpoint list. */ @@ -9153,7 +9231,7 @@ ranged_breakpoint::print_it (const bpstat *bs) const /* Implement the "print_one" method for ranged breakpoints. */ bool -ranged_breakpoint::print_one (bp_location **last_loc) const +ranged_breakpoint::print_one (bp_location **last_loc, bool print_address_col) const { struct bp_location *bl = loc; struct value_print_options opts; @@ -9164,7 +9242,7 @@ ranged_breakpoint::print_one (bp_location **last_loc) const get_user_print_options (&opts); - if (opts.addressprint) + if (print_address_col) /* We don't print the address range here, it will be printed later by print_one_detail_ranged_breakpoint. */ uiout->field_skip ("addr"); @@ -14369,10 +14447,13 @@ are set to the address of the last breakpoint listed unless the command\n\ is prefixed with \"server \".\n\n\ Convenience variable \"$bpnum\" contains the number of the last\n\ breakpoint set.")); + set_cmd_completer_handle_brkchars (info_breakpoints_cmd, + info_breakpoints_command_completer); add_info_alias ("b", info_breakpoints_cmd, 1); - add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints, _("\ + cmd_list_element *breakpoints_cmd + = add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints, _("\ Status of all breakpoints, or breakpoint number NUMBER.\n\ The \"Type\" column indicates one of:\n\ \tbreakpoint - normal breakpoint\n\ @@ -14392,6 +14473,8 @@ is prefixed with \"server \".\n\n\ Convenience variable \"$bpnum\" contains the number of the last\n\ breakpoint set."), &maintenanceinfolist); + set_cmd_completer_handle_brkchars (breakpoints_cmd, + info_breakpoints_command_completer); add_basic_prefix_cmd ("catch", class_breakpoint, _("\ Set catchpoints to catch events."), diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 566f1285e46..f87c12b57a9 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -679,8 +679,9 @@ struct breakpoint /* Display information about this breakpoint, for "info breakpoints". Returns false if this method should use the - default behavior. */ - virtual bool print_one (bp_location **) const + default behavior. PRINT_ADDRESS_COL specifies whether the "addr" + column should be printed. */ + virtual bool print_one (bp_location **, bool print_address_col) const { return false; } diff --git a/gdb/cli/cli-option.c b/gdb/cli/cli-option.c index b1794ad4b17..69a2418f7ae 100644 --- a/gdb/cli/cli-option.c +++ b/gdb/cli/cli-option.c @@ -174,6 +174,14 @@ complete_on_all_options (completion_tracker &tracker, complete_on_options (options_group, tracker, opt + 1, opt); } +/* See cli-option.h. */ + +void +error_unrecognized_option_at (const char *at) +{ + error (_("Unrecognized option at: %s"), at); +} + /* Parse ARGS, guided by OPTIONS_GROUP. HAVE_DELIMITER is true if the whole ARGS line included the "--" options-terminator delimiter. */ @@ -189,7 +197,7 @@ parse_option (gdb::array_view options_group, else if (**args != '-') { if (have_delimiter) - error (_("Unrecognized option at: %s"), *args); + error_unrecognized_option_at (*args); return {}; } else if (check_for_argument (args, "--")) @@ -235,7 +243,7 @@ parse_option (gdb::array_view options_group, if (match == nullptr) { if (have_delimiter || mode != PROCESS_OPTIONS_UNKNOWN_IS_OPERAND) - error (_("Unrecognized option at: %s"), *args); + error_unrecognized_option_at (*args); return {}; } diff --git a/gdb/cli/cli-option.h b/gdb/cli/cli-option.h index 26a8da3a5a4..42385979774 100644 --- a/gdb/cli/cli-option.h +++ b/gdb/cli/cli-option.h @@ -335,6 +335,12 @@ extern void complete_on_all_options (completion_tracker &tracker, gdb::array_view options_group); +/* Throw an error indicating an unrecognized option was detected at + AT. Use this in conjunction with UNKNOWN_IS_OPERAND instead of + UNKNOWN_IS_ERROR when the operand may or may not begin with '-' + depending on some condition determined at run time. */ +extern void error_unrecognized_option_at (const char *at); + /* Return a string with the result of replacing %OPTIONS% in HELP_TMLP with an auto-generated "help" string fragment for all the options in OPTIONS_GROUP. */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 039d7fc7a40..b6d60af8308 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4551,15 +4551,16 @@ optionally be surrounded by spaces. @kindex info breakpoints @cindex @code{$_} and @code{info breakpoints} -@item info breakpoints @r{[}@var{list}@dots{}@r{]} -@itemx info break @r{[}@var{list}@dots{}@r{]} +@item info breakpoints [-hide-locations] @r{[}@var{list}@dots{}@r{]} +@itemx info break [-hide-locations] @r{[}@var{list}@dots{}@r{]} Print a table of all breakpoints, watchpoints, tracepoints, and catchpoints set and not deleted. The optional argument @var{n} means print information only about the specified breakpoint(s) (or watchpoint(s) or tracepoint(s) or catchpoint(s)). -For each code breakpoint and tracepoint (i.e., not for watchpoints, -nor catchpoints), after printing a row for the breakpoint itself, +Unless the @code{-hide-locations} option is specified, for each code +breakpoint and tracepoint (i.e., not for watchpoints, nor +catchpoints), after printing a row for the breakpoint itself, @value{GDBN} prints one row for each of the breakpoint's locations. More on this further below. @@ -4582,7 +4583,10 @@ independently of their parent breakpoint. @item Address Where the breakpoint location is in your program, as a memory address. For a breakpoint with no locations, this field will contain -@samp{}. +@samp{}. This column is not printed if you specify the +@code{-hide-locations} option, nor if you disable printing of +addresses with @code{set print address off} (@pxref{set print +address}). @item What For a breakpoint header row, this shows the breakpoint's location specification, derived from the string passed to the breakpoint @@ -4642,7 +4646,7 @@ C@t{++} template function, and a newly loaded shared library has an instantiation of that template, a new location is added to the list of locations for the breakpoint. More on this further below. -As mentioned above, regular code breakpoints and tracepoints are +As mentioned above, regular code breakpoints and tracepoints are normally displayed in the breakpoint table using several rows---one header row per breakpoint, followed by one row for each of the breakpoint's locations. The header row has an empty address column, and the @@ -4655,12 +4659,15 @@ of the form @var{breakpoint-number}.@var{location-number}. For example: @smallexample +(@value{GDBP}) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y foo stop only if i==1 breakpoint already hit 1 time 1.1 y 0x080486a2 in void foo() at t.cc:8 1.2 y 0x080486ca in void foo() at t.cc:8 +2 breakpoint keep y bar + 2.1 y 0x080646a8 in void bar() at t.cc:20 @end smallexample Above you can tell from the what column that the breakpoint had been @@ -4668,6 +4675,20 @@ created with @code{break foo}, and that @value{GDBN} found two actual locations that matched that location specification, each of them a different instanciation of the foo function template. +When the @code{-hide-locations} flag is used, @value{GDBN} doesn't +print breakpoint locations, and doesn't print the address column +either, since only breakpoint locations have addresses. With the same +breakpoints as the previous example, you'd get: + +@smallexample +(@value{GDBP}) info breakpoints -hide-locations +Num Type Disp Enb What +1 breakpoint keep y foo + stop only if i==1 + breakpoint already hit 1 time +2 breakpoint keep y bar +@end smallexample + Breakpoints created with the @code{-qualified} option show that fact in the breakpoint row's what column, as part of the breakpoint's location specification. For example: -- 2.47.2