[PATCH 2/2] Introduce "info breakpoints -hide-locations"
Pedro Alves
pedro@palves.net
Thu May 19 21:55:52 GMT 2022
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
More information about the Gdb-patches
mailing list