]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Introduce "info breakpoints -hide-locations"
authorPedro Alves <pedro@palves.net>
Tue, 17 May 2022 12:12:04 +0000 (13:12 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 23 May 2022 19:31:44 +0000 (20:31 +0100)
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 <icu_66::RBBIRuleScanner::error(UErrorCode)>
  4.5                        y   0x00007ffff685e070 <icu_66::RegexCompile::error(UErrorCode)>
  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

12 files changed:
gdb/ada-lang.c
gdb/break-catch-exec.c
gdb/break-catch-fork.c
gdb/break-catch-load.c
gdb/break-catch-sig.c
gdb/break-catch-syscall.c
gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/cli/cli-option.c
gdb/cli/cli-option.h
gdb/doc/gdb.texinfo

index 6ab01fd27d4f9021e1d0220dafb599ac1b76680f..4229b116221d7bbde577ec2cd8c100b0a4a2fe0e 100644 (file)
@@ -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);
index 07417ee499ca2d8cae81457f3340ac28651e2423..d0fb38cf7682c7073ebff1be0c44259cf44b8668 100644 (file)
@@ -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");
index 1f8deec6a62fd1f112a96fcd848ec30c067d93a9..9848d7a22cf6c7a82ae173c3941eb74e18d628a3 100644 (file)
@@ -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";
index 617ee2b694d19e56a0240b6921fcb75c68f33c53..9a91fd264d8b36d018d64a3538e0ddcf85316aee 100644 (file)
@@ -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");
index 57a6255dc33a94f47e70f31c4d18a11d6bd19abf..29276a4cf23e9ea079cb8c8e6344517c4a243878 100644 (file)
@@ -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);
 
index 06d48466de7466b38b0d7076167f4a38256ab91d..6ee9277fee5dca0ab5f4a2ebd6ca937042c86ac9 100644 (file)
@@ -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);
 
index 66cf80be1c53e9c34ca6e178fc1e0964391f0f28..0e0e259cf6a2765e4365c22d75451de5c78984c7 100644 (file)
@@ -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);
 
index 964f87db0ba791eb1adf80263d9e88e33d2fa97d..59abf25555a835e105aabaca1193acd72deaf39d 100644 (file)
@@ -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<info_breakpoints_opts> {
+    "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<ui_out_emit_tuple> 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."),
index 566f1285e461b4c4e5b6fdcd8e1ba34d3dd97ae1..f87c12b57a9369e90afa93d249e848a33f23752a 100644 (file)
@@ -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;
   }
index b1794ad4b17c5513f9ee110de15d973dcbdf3e86..69a2418f7aea5403ca411d01dac407a7d806516a 100644 (file)
@@ -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<const option_def_group> 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<const option_def_group> 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 {};
     }
index 26a8da3a5a42f77010cf2e67b686325c25b9c26d..42385979774febd5a1b349a8866008c98fa481e2 100644 (file)
@@ -335,6 +335,12 @@ extern void
   complete_on_all_options (completion_tracker &tracker,
                           gdb::array_view<const option_def_group> 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.  */
index 039d7fc7a40b47bff18c0393f2457036786efdab..b6d60af83080d997281c1c65e9cddf8246ba9ee3 100644 (file)
@@ -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{<PENDING>}.
+@samp{<PENDING>}.  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<int>() at t.cc:8
  1.2                        y    0x080486ca in void foo<double>() 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: