From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) by sourceware.org (Postfix) with ESMTPS id F22683839C65 for ; Thu, 19 May 2022 21:56:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F22683839C65 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f52.google.com with SMTP id s28so8885214wrb.7 for ; Thu, 19 May 2022 14:56:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Upd1skWErEDNjDt1nYRJ8+vy7KEk6jN2h5Cg8vBTwbY=; b=ewAwazo14n8LJyegu28zETO+knT6Hped78HdeiNtp4B2s3AmfHmUE+xbSSG+MuLWEK 5Ganfy9J27FkJ8aW2PViaOWv2wjr4wTQdW/HBSuqAxhPDsaV7TcTB9VcJBSoqvm1FZQ+ I/HxBOFoc+IM4If5DAZNFrtf9YGVkXB4hXmkMKZB6y4Qb7PN6XjrPiJ4+GsW7ENFbXax qcJ9LCVymVqaRcEJxwKdei1WlVhbazkfhpV3M6ahgLkDB/ru/km7coQzjEYD5igISp3z uiIY7yFit2BrbAutUfUtiOew8mbTh26XaOIPbhG+Z9Yy3dErUBJC0EYmno35F5aSVce/ zjFQ== X-Gm-Message-State: AOAM532pINFclMicbhs9fb/ELfcY2/Yp2ykbWLWJYQnz4AsJW74t1uSB MOyNYYz2Mp09NCBv814RQokoVra1tnE= X-Google-Smtp-Source: ABdhPJzmqREUsBqic5PPZ37TuWkuqyKxn9S9Kz/8VDGzwaY08vLcnMQMHNNPe6gTvUQmBg1rTSiByg== X-Received: by 2002:a05:6000:1f17:b0:20e:6626:5ac7 with SMTP id bv23-20020a0560001f1700b0020e66265ac7mr5654506wrb.489.1652997359711; Thu, 19 May 2022 14:55:59 -0700 (PDT) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id s11-20020adfbc0b000000b0020c5253d8f3sm742205wrg.63.2022.05.19.14.55.58 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 19 May 2022 14:55:58 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 2/2] Introduce "info breakpoints -hide-locations" Date: Thu, 19 May 2022 22:55:52 +0100 Message-Id: <20220519215552.3254012-3-pedro@palves.net> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220519215552.3254012-1-pedro@palves.net> References: <20220519215552.3254012-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 May 2022 21:56:06 -0000 This commit adds a new option to "info breakpoints", "-hide-locations". It's purpose is to tell GDB to skip printing breakpoint locations, printing only the breakpoint header rows. And then, since only code breakpoint locations print anything in the "Address" column, "-hide-breakpoints" also disables the "Address" column. For example, when debugging GDB, you can use the new options to get this: (top-gdb) i b -h Num Type Disp Enb What 1 breakpoint keep y internal_error 2 breakpoint keep y info_command silent return 3 breakpoint keep y main breakpoint already hit 1 time 4 breakpoint keep y error (top-gdb) instead of: (top-gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y internal_error 1.1 y 0x0000555555f81d12 in internal_error(char const*, int, char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:51 2 breakpoint keep y info_command silent return 2.1 y 0x00005555557b3097 in info_command(char const*, int) at /home/pedro/gdb/binutils-gdb/src/gdb/cli/cli-cmds.c:217 3 breakpoint keep y main breakpoint already hit 1 time 3.1 y 0x000055555564106c in main(int, char**) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:25 3.2 y 0x0000555555dba524 in selftests::string_view::capacity_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/capacity/1.cc:167 3.3 y 0x0000555555dba943 in selftests::string_view::cons_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/1.cc:62 3.4 y 0x0000555555dbaa34 in selftests::string_view::cons_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/2.cc:41 3.5 y 0x0000555555dbaa9a in selftests::string_view::cons_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/cons/char/3.cc:34 3.6 y 0x0000555555dbac6b in selftests::string_view::element_access_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/1.cc:66 3.7 y 0x0000555555dbac83 in selftests::string_view::element_access_empty::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/empty.cc:25 3.8 y 0x0000555555dbae91 in selftests::string_view::element_access_front_back::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/element_access/char/front_back.cc:38 3.9 y 0x0000555555dbb2bd in selftests::string_view::inserters_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/inserters/char/2.cc:84 3.10 y 0x0000555555dbb429 in selftests::string_view::modifiers_remove_prefix::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/modifiers/remove_prefix/char/1.cc:58 3.11 y 0x0000555555dbb575 in selftests::string_view::modifiers_remove_suffix::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/modifiers/remove_suffix/char/1.cc:58 3.12 y 0x0000555555dbbd38 in selftests::string_view::operations_compare_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/compare/char/1.cc:127 3.13 y 0x0000555555dbbe7b in selftests::string_view::operations_compare_13650::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/compare/char/13650.cc:45 3.14 y 0x0000555555dbbf6a in selftests::string_view::operations_copy_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/copy/char/1.cc:41 3.15 y 0x0000555555dbc03b in selftests::string_view::operations_data_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/data/char/1.cc:39 3.16 y 0x0000555555dbc5fe in selftests::string_view::operations_find_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/1.cc:160 3.17 y 0x0000555555dbcb60 in selftests::string_view::operations_find_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/2.cc:158 3.18 y 0x0000555555dbd1c1 in selftests::string_view::operations_find_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/3.cc:158 3.19 y 0x0000555555dbd26c in selftests::string_view::operations_find_4::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/find/char/4.cc:40 3.20 y 0x0000555555dbd83f in selftests::string_view::operations_rfind_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/1.cc:90 3.21 y 0x0000555555dbda98 in selftests::string_view::operations_rfind_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/2.cc:48 3.22 y 0x0000555555dbde4c in selftests::string_view::operations_rfind_3::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/rfind/char/3.cc:63 3.23 y 0x0000555555dbe189 in selftests::string_view::operations_substr_1::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operations/substr/char/1.cc:74 3.24 y 0x0000555555dbffdb in selftests::string_view::operators_2::main() at /home/pedro/gdb/binutils-gdb/src/gdb/unittests/basic_string_view/operators/char/2.cc:366 4 breakpoint keep y error 4.1 y 0x00005555557f5142 in gcc_c_plugin::error(char const*) const at /home/pedro/gdb/binutils-gdb/src/gdb/../include/gcc-c-fe.def:198 4.2 y 0x00005555557fe1f4 in gcc_cp_plugin::error(char const*) const at /home/pedro/gdb/binutils-gdb/src/gdb/../include/gcc-cp-fe.def:983 4.3 y 0x0000555555f81c5e in error(char const*, ...) at /home/pedro/gdb/binutils-gdb/src/gdbsupport/errors.cc:39 4.4 y 0x00007ffff65ee4e0 4.5 y 0x00007ffff685e070 4.6 y 0x00007ffff6cd4e86 in error at /usr/include/x86_64-linux-gnu/bits/error.h:40 4.7 y 0x00007ffff71c2190 in __error at error.c:274 Documentation change included. No testsuite changes yet until there's agreement on the previous patch. Change-Id: Ic42ad8565e79ca67bfebb22cbb4794ea816fd08b --- gdb/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{}. 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() at t.cc:8 1.2 y 0x080486ca in void foo() at t.cc:8 +2 breakpoint keep y bar + 2.1 y 0x080646a8 in void bar() at t.cc:20 +@end smallexample + +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 { + "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 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 options_group, else if (**args != '-') { if (have_delimiter) - error (_("Unrecognized option at: %s"), *args); + error_unrecognized_option_at (*args); return {}; } else if (check_for_argument (args, "--")) @@ -235,7 +243,7 @@ parse_option (gdb::array_view options_group, if (match == nullptr) { if (have_delimiter || mode != PROCESS_OPTIONS_UNKNOWN_IS_OPERAND) - error (_("Unrecognized option at: %s"), *args); + error_unrecognized_option_at (*args); return {}; } diff --git a/gdb/cli/cli-option.h b/gdb/cli/cli-option.h index 26a8da3a5a4..42385979774 100644 --- a/gdb/cli/cli-option.h +++ b/gdb/cli/cli-option.h @@ -335,6 +335,12 @@ extern void complete_on_all_options (completion_tracker &tracker, gdb::array_view options_group); +/* Throw an error indicating an unrecognized option was detected at + AT. Use this in conjunction with UNKNOWN_IS_OPERAND instead of + UNKNOWN_IS_ERROR when the operand may or may not begin with '-' + depending on some condition determined at run time. */ +extern void error_unrecognized_option_at (const char *at); + /* Return a string with the result of replacing %OPTIONS% in HELP_TMLP with an auto-generated "help" string fragment for all the options in OPTIONS_GROUP. */ -- 2.36.0