public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 2/2] Introduce "info breakpoints -hide-locations"
Date: Thu, 19 May 2022 22:55:52 +0100	[thread overview]
Message-ID: <20220519215552.3254012-3-pedro@palves.net> (raw)
In-Reply-To: <20220519215552.3254012-1-pedro@palves.net>

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
---
 gdb/doc/gdb.texinfo       |  37 ++++++++---
 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          | 133 +++++++++++++++++++++++++++++++-------
 gdb/breakpoint.h          |   5 +-
 gdb/cli/cli-option.c      |  12 +++-
 gdb/cli/cli-option.h      |   6 ++
 12 files changed, 182 insertions(+), 77 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7bd791afa06..94cfcff8d29 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4550,8 +4550,8 @@ 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.  Optional argument @var{n} means
 print information only about the specified breakpoint(s) (or
@@ -4560,10 +4560,11 @@ watchpoint(s) or tracepoint(s) or catchpoint(s)).
 A breakpoint location specification (@pxref{Specify Location}) may be
 resolved to several locations in your program.  E.g., @code{break
 func} will find a location for each function named @code{func} in the
-program.  For each code breakpoint and tracepoint (not for
-watchpoints, nor catchpoints), @value{GDBN} prints a header entry, and
-then one entry for each resolved location of the breakpoint.  More on
-this further below.
+program.  Unless the @code{-hide-locations} option is specified, for
+each code breakpoint and tracepoint (i.e., not for watchpoints, nor
+catchpoints), @value{GDBN} prints a header entry, and then one entry
+for each resolved location of the breakpoint.  More on this further
+below.
 
 For each breakpoint and breakpoint location, the following columns are
 printed:
@@ -4585,7 +4586,10 @@ any location yet, this field will contain @samp{<PENDING>}.  Such
 breakpoint won't fire until its location spec is resolved to an actual
 location, such as e.g., when a shared library that has the symbol or
 line that matches the location specification is loaded.  See below for
-details.
+details.  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, the original location specification
 passed to the breakpoint command.  For a breakpoint location row,
@@ -4662,7 +4666,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.
 
-Regulars code breakpoints and tracepoints are displayed in the
+Regulars 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 original location
@@ -4675,12 +4679,29 @@ indented by one space to the right for grouping, and is of the form
 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
+
+When the @code{-hide-locations} flag is used, @value{GDBN} hides the
+breakpoint locations, and doesn't print the address column, since only
+breakpoint locations have addresses.  For example:
+
+@smallexample
+
+Num     Type           Disp Enb  What
+(@value{GDBP}) info breakpoints -hide-locations
+1       breakpoint     keep y    foo
+        stop only if i==1
+        breakpoint already hit 1 time
+2       breakpoint     keep y    bar
 @end smallexample
 
 You cannot delete the individual locations from a breakpoint.  However,
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 248b847cfbc..d70cc4651f1 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12133,7 +12133,7 @@ struct ada_catchpoint : public base_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;
 
@@ -12385,14 +12385,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 af55ecb1b5c..b57401b9aaa 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->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 f15fa531519..251fffdf21f 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -83,7 +83,7 @@ struct exception_catchpoint : public catchpoint
 
   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;
@@ -267,14 +267,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 724bc778a9b..653dd83ba92 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -316,7 +316,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;
@@ -6161,6 +6161,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
@@ -6173,15 +6201,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);
 
@@ -6227,7 +6253,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
     {
@@ -6238,7 +6264,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 ());
@@ -6246,7 +6272,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)
@@ -6485,6 +6511,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;
@@ -6492,16 +6530,19 @@ 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.  */
@@ -6511,7 +6552,7 @@ print_one_breakpoint (struct breakpoint *b,
   /* If this breakpoint has custom print function, it's already
      printed.  Otherwise, print individual locations, if any, and if
      not explicitly disabled by the user.  */
-  if (!printed || allflag)
+  if (!ib_opts.hide_locations && (!printed || allflag))
     {
       /* Note that while hardware watchpoints have several locations
 	 internally, that's not a property exposed to users.
@@ -6539,7 +6580,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++;
 	    }
 	}
@@ -6573,8 +6615,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
@@ -6596,9 +6639,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.
 
@@ -6608,18 +6651,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.  */
@@ -6658,7 +6713,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");
 
@@ -6676,7 +6731,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);
@@ -6719,7 +6774,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;
@@ -6757,6 +6812,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.  */
 
@@ -9228,7 +9306,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;
@@ -9239,7 +9317,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");
@@ -14494,10 +14572,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\
@@ -14517,6 +14598,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 ac738fd7c2d..93b521c1694 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -685,8 +685,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<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 {};
     }
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<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.  */
-- 
2.36.0


  parent reply	other threads:[~2022-05-19 21:56 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 21:55 [PATCH 0/2] info breakpoints improvements Pedro Alves
2022-05-19 21:55 ` [PATCH 1/2] Always show locations for breakpoints & show canonical location spec Pedro Alves
2022-05-20  6:45   ` Eli Zaretskii
2022-05-23 17:04     ` [PATCH v2 " Pedro Alves
2022-05-24 13:06       ` Eli Zaretskii
2022-05-25 19:32         ` Pedro Alves
2022-05-26 12:48           ` Eli Zaretskii
2022-05-26 14:04             ` Pedro Alves
2022-05-26 15:03               ` Eli Zaretskii
2022-05-26 15:10                 ` Pedro Alves
2022-05-26 15:33                   ` Eli Zaretskii
2022-05-26 19:29                 ` Pedro Alves
2022-05-26 19:55                   ` Eli Zaretskii
2022-05-26 20:40                     ` Pedro Alves
2023-04-10 15:07                   ` Andrew Burgess
2022-05-20  7:45   ` [PATCH " Metzger, Markus T
2022-05-23 17:05     ` Lancelot SIX
2022-05-19 21:55 ` Pedro Alves [this message]
2022-05-20  6:48   ` [PATCH 2/2] Introduce "info breakpoints -hide-locations" Eli Zaretskii
2022-05-20  5:57 ` [PATCH 0/2] info breakpoints improvements Eli Zaretskii
2022-05-23 17:06   ` Pedro Alves
2022-05-24 13:14     ` Eli Zaretskii
2022-05-24 13:45       ` Pedro Alves
2022-05-24  8:38 ` Luis Machado
2022-05-24 10:02   ` Pedro Alves
2022-05-24 13:20     ` Eli Zaretskii
2022-05-24 13:29       ` Pedro Alves
2022-05-24 13:43         ` Eli Zaretskii
2022-05-24 13:50           ` Pedro Alves
2022-05-24 14:03             ` Eli Zaretskii
2022-05-24 14:09               ` Pedro Alves
2022-05-24 14:25                 ` Eli Zaretskii
2022-05-24 14:33                   ` Pedro Alves
2022-05-24 14:11               ` Andreas Schwab
2022-05-24 14:17                 ` Pedro Alves
2022-05-24 19:49                   ` [PATCH] Show enabled locations with disabled breakpoint parent as "y-" (Re: [PATCH 0/2] info breakpoints improvements) Pedro Alves
2022-05-25 13:57                     ` Eli Zaretskii
2022-05-25 19:19                       ` Pedro Alves
2022-05-24 14:26                 ` [PATCH 0/2] info breakpoints improvements Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220519215552.3254012-3-pedro@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).