From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by sourceware.org (Postfix) with ESMTPS id 077A7385843F for ; Tue, 29 Oct 2024 11:34:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 077A7385843F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 077A7385843F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730201666; cv=none; b=JAOuZrOXdBs/TQm6hj8IR5KLNzn1qg2kOnERK2n8KTzzMAfDftibl6rPSsU3DZlIISXIR7P+4OP5uSUG14IzaoZNc0FdJwhgdou//rKFcrKWJUAmcy+N2u0bnoEDD3/E9rzm79yH5Hl+JoEfMvHBP1TVwGaKx1Enlz4Zt9iV4nQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730201666; c=relaxed/simple; bh=ABgfuvAHlFOZ2qvE+pyzKovAPspPtFOjZsDpo9MUmmg=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=j4Y3IPv9gHKqVtF7OqU6YfOkcE5pTIrltfNhcXR8yDcxDy5q5QbRUmGmRUY6q2PcrutyhxJDd033+61FlxOroFdBo9V5gLTS9JRAJwBjLJHv0dnGxsv57Rr74uR6+2IKB24zf+QmF2+h98hQSQiO1VVvPuAQqd6//nSkLefSSLs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1730201661; x=1761737661; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=ABgfuvAHlFOZ2qvE+pyzKovAPspPtFOjZsDpo9MUmmg=; b=FmCqZYtt07O81OhTjRZRQF99C0grxb0Hwq/l69jbJ2PUaLk13XlroKYu WDGaYOF9QeyBhbKJym6qd9VajffYogHx8xsMl/XueN37wDjn5Zi01Odt9 VhshXu0cOCDp2irG4BwF5xHoRrE511P9YvEYAwjgvxokaVpOSINeoM1hK eTe9p4Zsxg9/6PcnSO4FRfmnpFtpweY57MJ9HQ/HY7Cueap8kup7mKKeU EReIpjn0+efaIzqd0DiU5mcbAnK+k45uC0A+3RelKen/FCvwNAVR5Wkgz iFPov5cD8VP2zZ9PbqW5Xw5qO/SoP7qNxS2j0lUDQiAf6X6xYfYQlM+6K Q==; X-CSE-ConnectionGUID: uyWUHwJ3SPyX04raZzGIjw== X-CSE-MsgGUID: sI3rALGJT3OLAw3SyHzlWw== X-IronPort-AV: E=McAfee;i="6700,10204,11222"; a="47297095" X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="47297095" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Oct 2024 04:34:19 -0700 X-CSE-ConnectionGUID: uzw05s0RSSWzrNIOF0dH4w== X-CSE-MsgGUID: 6Njfx9BiRS6RR3uUME10Xg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,241,1725346800"; d="scan'208";a="81842549" Received: from dut1513dg2mrb.igk.intel.com (HELO localhost) ([10.102.46.197]) by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Oct 2024 04:34:18 -0700 From: Klaus Gerlicher To: gdb-patches@sourceware.org, aburgess@redhat.com, blarsen@redhat.com, eliz@gnu.org Subject: [PATCH v7 2/2] gdb, breakpoint: output multiple bp locations Date: Tue, 29 Oct 2024 11:33:43 +0000 Message-Id: <20241029113343.3945855-3-klaus.gerlicher@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241029113343.3945855-1-klaus.gerlicher@intel.com> References: <20241029113343.3945855-1-klaus.gerlicher@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: "Gerlicher, Klaus" When setting a breakpoint that resolves to multiple locations only the address of the first location is printed but multiple locations are indicated. See this example: 01 template 02 T 03 f (T t) 04 { 05 return t; 06 } 07 08 int 09 main (void) 10 { 11 return f (1) + f (1.0f) + f (1) 12 + f (1) + f (1); 13 } Setting a breakpoint on line 5 will yield 5 locations: (gdb) b 5 Breakpoint 1 at 0x11cf: main.cpp:5. (5 locations) Even though this indicates multiple locations, it only shows the first one. A better way would be: Set how many locations to be printed, then... (gdb) set breakpoint max-breakpoint-locations-printed 4 ... set breakpoint. (gdb) b 5 Breakpoint 1 for main.cpp:5 at 5 locations: Location 1 at 0x11cf in function f(int) in file main.cpp, line 5. Location 2 at 0x11e1 in function f(float) in file main.cpp, line 5. Location 3 at 0x11f5 in function f(char) in file main.cpp, line 5. Location 4 at 0x1209 in function f(short) in file main.cpp, line 5. 1 additional location not printed. Make the number of breakpoint locations printed configurable. Introduce the "set breakpoint max-breakpoint-locations-printed" command. Convert tests that use gdb_test "break" to using gdb_breakpoint because previously the "break" output was parseable with a single regex. Now that it has become multi-line, tests that were previously creating multiple locations unknowingly need to be fixed to use the right regex which is simpler (and more properly) done by using the gdb_breakpoint. gdb_breakpoint knows which regex to use for any case. This also adds two more options to gdb_breakpoint, -add_locs and -inferior: -add_locs is used for testing the additional print when there are more locations then allowed to be printed with the "set max-breakpoint-locations-printed" command. -inferior is used to match "on inferior X" output when multiple locations are on different inferiors. --- gdb/NEWS | 4 + gdb/breakpoint.c | 135 ++++++++++++++---- gdb/doc/gdb.texinfo | 45 +++++- gdb/testsuite/gdb.base/ctxobj.exp | 4 +- .../run-control-while-bg-execution.exp | 2 +- gdb/testsuite/gdb.cp/ovldbreak.exp | 6 +- gdb/testsuite/gdb.linespec/cpcompletion.exp | 2 + gdb/testsuite/gdb.linespec/linespec.exp | 2 +- gdb/testsuite/gdb.linespec/multiple-locs.cc | 41 ++++++ gdb/testsuite/gdb.linespec/multiple-locs.exp | 57 ++++++++ .../mi-breakpoint-multiple-locations.exp | 4 +- .../gdb.mi/user-selected-context-sync.exp | 16 +-- .../gdb.multi/inferior-specific-bp.exp | 2 +- .../gdb.multi/multi-target-continue.exp | 3 +- .../gdb.multi/multi-target-ping-pong-next.exp | 6 +- gdb/testsuite/gdb.python/py-breakpoint.exp | 3 +- gdb/testsuite/lib/completion-support.exp | 3 + gdb/testsuite/lib/gdb.exp | 34 ++++- 18 files changed, 308 insertions(+), 61 deletions(-) create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.cc create mode 100644 gdb/testsuite/gdb.linespec/multiple-locs.exp diff --git a/gdb/NEWS b/gdb/NEWS index 42b8a88fd8a..bae2fa9b93f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,10 @@ *** Changes since GDB 15 +* Printing multiple breakpoint locations when setting a breakpoint that is + instantiated for multiple locations now prints all locations limited by + "set breakpoint max-breakpoint-location-printed ". + * Debugging support for Intel MPX has been removed. This includes the removal of ** MPX register support diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b7e4f5d0a45..7845d696de9 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -170,6 +170,19 @@ static bool bl_address_is_meaningful (bp_location *loc); static int find_loc_num_by_location (const bp_location *loc); +/* Maximum number of locations printed when setting a breakpoint. Controlled + by "set breakpoint max-breakpoint-locations-printed ". */ + +static unsigned int breakpoint_show_max_locations = 10; +static void +show_max_breakpoint_location_printed (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + gdb_printf (file, + _("Number of breakpoint location printed is %s.\n"), + value); +} + /* update_global_location_list's modes of operation wrt to whether to insert locations now. */ enum ugll_insert_mode @@ -11813,39 +11826,93 @@ code_breakpoint::say_where () const } else { - const bp_location &bl = this->first_loc (); - if (opts.addressprint || bl.symtab == nullptr) - gdb_printf (" at %ps", - styled_string (address_style.style (), - paddress (bl.gdbarch, - bl.address))); - if (bl.symtab != NULL) - { - /* If there is a single location, we can print the location - more nicely. */ - if (!this->has_multiple_locations ()) + if (this->has_multiple_locations ()) + { + int n = std::distance (m_locations.begin (), m_locations.end ()); + + gdb_printf (" for %s at %d locations:\n", locspec->to_string (), n); + int loc_idx = 0; + for (const bp_location &bl : m_locations) + { + gdb_printf (" Location %d", loc_idx + 1); + if (opts.addressprint || bl.symtab == nullptr) + gdb_printf (" at %ps", styled_string (address_style.style (), + paddress (bl.gdbarch, + bl.address))); + + if (bl.symtab != nullptr) + { + const struct symbol *sym = bl.symbol; + if (sym != nullptr) + { + gdb_stdout->wrap_here (6); + gdb_printf (" in function %ps", + styled_string (function_name_style.style (), + sym->print_name ())); + } + + const char *filename + = symtab_to_filename_for_display (bl.symtab); + gdb_stdout->wrap_here (6); + gdb_printf (": file %ps, line %ps", + styled_string (file_name_style.style (), + filename), + styled_string (line_number_style.style (), + pulongest (bl.line_number))); + } + + if (all_inferiors ().size () > 1) + { + for (const auto &inf : all_inferiors ()) + if (inf->pspace == bl.pspace) + gdb_printf (" in inferior %d", inf->num); + } + else if (bl.owner->inferior != -1) + gdb_printf (" in inferior %d", bl.owner->inferior); + + loc_idx++; + + gdb_printf ("."); + if (loc_idx < n) + gdb_printf ("\n"); + + /* The user (or default) has selected a maximum number of + locations to be printed. */ + if (loc_idx >= breakpoint_show_max_locations) + break; + } + + /* We printed less locations than there are present, let the user + know how many more there are. */ + if (loc_idx < n) { - const char *filename - = symtab_to_filename_for_display (bl.symtab); - gdb_printf (": file %ps, line %ps.", - styled_string (file_name_style.style (), - filename), - styled_string (line_number_style.style (), - pulongest (bl.line_number))); + int omitted_locs = n - loc_idx; + if (omitted_locs == 1) + gdb_printf (_("%u additional location not printed."), + omitted_locs); + else + gdb_printf (_("%u additional locations not printed."), + omitted_locs); } - else - /* This is not ideal, but each location may have a - different file name, and this at least reflects the - real situation somewhat. */ - gdb_printf (": %s.", locspec->to_string ()); } - - if (this->has_multiple_locations ()) + else { - int n = std::distance (m_locations.begin (), m_locations.end ()); - gdb_printf (" (%d locations)", n); + const bp_location &bl = this->first_loc (); + if (opts.addressprint || bl.symtab == nullptr) + gdb_printf (" at %ps", + styled_string (address_style.style (), + paddress (bl.gdbarch, bl.address))); + if (bl.symtab != nullptr) + { + const char *filename + = symtab_to_filename_for_display (bl.symtab); + gdb_printf (": file %ps, line %ps.", + styled_string (file_name_style.style (), filename), + styled_string (line_number_style.style (), + pulongest (bl.line_number))); + } } - } + } } /* See breakpoint.h. */ @@ -15254,6 +15321,18 @@ Usage: agent-printf \"format string\", ARG1, ARG2, ARG3, ..., ARGN\n\ This supports most C printf format specifications, like %s, %d, etc.\n\ This is useful for formatted output in user-defined commands.")); + add_setshow_uinteger_cmd ("max-breakpoint-locations-printed", + class_breakpoint, + &breakpoint_show_max_locations, _("\ +Set number of locations printed when setting a breakpoint."), _("\ +Show number of locations printed when setting a breakpoint."), _("\ +Use this to choose how many number of locations are printed\n\ +when setting a breakpoint.\n\ +A value of \"unlimited\", or zero, means there's no limit."), + nullptr, /* set_cmd. */ + show_max_breakpoint_location_printed, + &breakpoint_set_cmdlist, &breakpoint_show_cmdlist); + automatic_hardware_breakpoints = true; gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed, diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index eb2aff974bb..a03ceccd5fa 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4518,16 +4518,47 @@ $1 = 1 A breakpoint may be mapped to multiple code locations for example with inlined functions, Ada generics, C@t{++} templates or overloaded function names. -@value{GDBN} then indicates the number of code locations in the breakpoint +@value{GDBN} then lists the number of code locations in the breakpoint command output: @smallexample (gdb) b some_func -Breakpoint 2 at 0x1179: some_func. (3 locations) +Breakpoint 2 for some_func at 3 locations: + Location 1 at 0x118e in function some_func in file somefunc.cc, line 23. + Location 2 at 0x11ee in function some_func in file somefunc.cc, line 38. + Location 3 at 0x12fe in function some_func in file someother.cc, line 58. (gdb) p $bpnum $2 = 2 (gdb) @end smallexample +@cindex @code{break}, how many locations are displayed +By default, @value{GDBN} prints up to ten breakpoint locations, you can change +this using @code{set breakpoint max-breakpoint-locations-printed}: + +@smallexample +(gdb) set breakpoint max-breakpoint-locations-printed 2 +(gdb) b some_func +Breakpoint 2 for some_func at 3 locations: + Location 1 at 0x118e in function some_func in file somefunc.cc, line 23. + Location 2 at 0x11ee in function some_func in file somefunc.cc, line 38. +1 additional location not printed. +(gdb) +@end smallexample + +@table @code +@kindex set breakpoint max-breakpoint-locations-printed +@item set breakpoint max-breakpoint-locations-printed @var{count} +@itemx set breakpoint max-breakpoint-locations-printed unlimited +Make the @code{break} command display up to @var{count} locations. +Setting @var{count} to @code{unlimited} or 0 means there's no limit. + +@kindex show breakpoint max-breakpoint-locations-printed +@item show breakpoint max-breakpoint-locations-printed +Display the number of locations that @code{break} will print. If the number +of locations is greater than the limit, the additional number of locations +will be listed. +@end table + @vindex $_hit_bpnum@r{, convenience variable} @vindex $_hit_locno@r{, convenience variable} When your program stops on a breakpoint, the convenience variables @@ -4637,7 +4668,10 @@ warning: failed to validate condition at location 0x11ce, disabling: No symbol "a" in current context. warning: failed to validate condition at location 0x11b6, disabling: No symbol "a" in current context. -Breakpoint 1 at 0x11b6: func. (3 locations) +Breakpoint 1 for func at 3 locations: + Location 1 at 0x11ce in function func in file somefunc.cc, line 23. + Location 2 at 0x11b6 in function func in file somefunc.cc, line 38. + Location 3 at 0x12fe in function func in file someother.cc, line 58. @end smallexample Locations that are disabled because of the condition are denoted by an @@ -4681,7 +4715,10 @@ warning: failed to validate condition at location 2, disabling: No symbol "foo" in current context. warning: failed to validate condition at location 3, disabling: No symbol "foo" in current context. -Breakpoint 1 at 0x1158: test.c:18. (3 locations) +Breakpoint 1 for func at 3 locations: + Location 1 at 0x1158 in function func in file test.c, line 18. + Location 2 at 0x11b6 in function func in file test.c, line 28. + Location 3 at 0x12fe in function func in file test.c, line 58. @end smallexample This causes all the present locations where the breakpoint would diff --git a/gdb/testsuite/gdb.base/ctxobj.exp b/gdb/testsuite/gdb.base/ctxobj.exp index d1137189108..e73b29fcf3a 100644 --- a/gdb/testsuite/gdb.base/ctxobj.exp +++ b/gdb/testsuite/gdb.base/ctxobj.exp @@ -61,9 +61,7 @@ if ![runto_main] { } set bp_location [gdb_get_line_number "STOP" "ctxobj-f.c"] -gdb_test "break ctxobj-f.c:$bp_location" \ - "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \ - "break in get_version functions" +gdb_breakpoint "ctxobj-f.c:$bp_location" global expect_out set test "continue to get_version_1" diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp index 380047ae854..fd395f10387 100644 --- a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp +++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp @@ -90,7 +90,7 @@ proc do_test { action1 action2 } { if { $action2 == "start" } { gdb_test "start" "Temporary breakpoint $::decimal\(?:\.$::decimal\)?, main .*" } elseif { $action2 == "run" } { - gdb_test "break main" "Breakpoint $::decimal at $::hex.*" + gdb_breakpoint "main" gdb_test "run" "Breakpoint $::decimal\(?:\.$::decimal\)?, main .*" } elseif { $action2 == "attach" } { set test_spawn_id [spawn_wait_for_attach $::binfile] diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp index 84efb37b8db..1f5383e92e9 100644 --- a/gdb/testsuite/gdb.cp/ovldbreak.exp +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp @@ -332,6 +332,10 @@ gdb_test "info breakpoints" "No breakpoints, watchpoints, tracepoints, or catchp # Test choice "all". # This is copy-and-paste from set_bp_overloaded. +gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 0" + +set breakmsg [gdb_multi_loc_regex "Breakpoint $decimal" 12] + incr bpnum send_gdb "break foo::overload1arg\n" gdb_expect { @@ -340,7 +344,7 @@ gdb_expect { # Choose all. send_gdb "1\n" gdb_expect { - -re "Breakpoint $bpnum at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" { + -re "$breakmsg$gdb_prompt $" { pass "set bp on overload1arg all" } -re ".*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp index 09bd9a25d77..49d59e79918 100644 --- a/gdb/testsuite/gdb.linespec/cpcompletion.exp +++ b/gdb/testsuite/gdb.linespec/cpcompletion.exp @@ -1397,4 +1397,6 @@ proc test_driver {} { if-expression } +gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 0" + test_driver diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp index 6398309f7e4..e5a0e205e9e 100644 --- a/gdb/testsuite/gdb.linespec/linespec.exp +++ b/gdb/testsuite/gdb.linespec/linespec.exp @@ -69,7 +69,7 @@ if { [is_remote host] } { send_gdb "\n" gdb_test "" \ - "Breakpoint $decimal at $hex: thefile.cc:twodup\\(\\). \[(\]2 locations\[)\]" \ + "[gdb_multi_loc_regex "Breakpoint $decimal" 2]\[^\r\n\]*" \ "set break at unique function name in two source files" } } diff --git a/gdb/testsuite/gdb.linespec/multiple-locs.cc b/gdb/testsuite/gdb.linespec/multiple-locs.cc new file mode 100644 index 00000000000..e7ca889e0fa --- /dev/null +++ b/gdb/testsuite/gdb.linespec/multiple-locs.cc @@ -0,0 +1,41 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +template +int +templ1 (T param) +{ + return (int) param; /* Break here. */ +} + +template <> +int +templ1 (char* param) +{ + return 2; +} + +int +main () +{ + templ1 (1L); + templ1 (1.0f); + templ1 (1U); + templ1 (1UL); + templ1 (1ULL); + return 0; +} diff --git a/gdb/testsuite/gdb.linespec/multiple-locs.exp b/gdb/testsuite/gdb.linespec/multiple-locs.exp new file mode 100644 index 00000000000..d829e93b1ed --- /dev/null +++ b/gdb/testsuite/gdb.linespec/multiple-locs.exp @@ -0,0 +1,57 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Tests of printing of multiple breakpoint locations when setting a breakpoint. + +standard_testfile .cc + +require allow_cplus_tests + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { + return -1 +} + +gdb_test_no_output "set confirm off" + +gdb_test_no_output "set multiple-symbols all" + +set bp_location [gdb_get_line_number "Break here." $srcfile] +gdb_breakpoint "$bp_location" -locs 5 + +delete_breakpoints + +gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 2" + +set bp_location [gdb_get_line_number "Break here." $srcfile] + +gdb_breakpoint $bp_location -locs 5 -add_locs 3 + +delete_breakpoints + +set bp_location [gdb_get_line_number "Break here." $srcfile] + +gdb_breakpoint "$bp_location inferior 1" -locs 5 -locspec "$bp_location" \ + -add_locs 3 -inferior 1 + +delete_breakpoints + +# Now add the 2nd inferior. +gdb_test "add-inferior" "Added inferior 2.*" "add inferior 2" +gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2" +gdb_file_cmd $binfile + +gdb_test_no_output "set breakpoint max-breakpoint-locations-printed 20" + +gdb_breakpoint "$bp_location" -locs 10 -inferior "\[12\]" diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp index 93ddad84444..a02fe1f7cce 100644 --- a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp +++ b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp @@ -69,7 +69,9 @@ proc do_test { mi_version use_fix_flag expect_fixed_output } { set pattern [make_breakpoints_pattern $expect_fixed_output 2 y y] mi_gdb_test "break a_very_unique_name" \ [multi_line "&\"break a_very_unique_name\\\\n\"" \ - "~\"Breakpoint ${decimal} at.*\\(2 locations\\)\\\\n\"" \ + "~\"Breakpoint ${decimal} for.*at.*2 locations:\\\\n\"" \ + "~\" Location ${decimal}.*\\\\n\"" \ + "~\" Location ${decimal}.*\\\\n\"" \ "=breakpoint-created,${pattern}" \ "\\^done" ] \ "break a_very_unique_name" diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp index e168a5eee45..b8d640d010a 100644 --- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp +++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp @@ -293,9 +293,7 @@ proc test_continue_to_start { mode inf } { with_spawn_id $gdb_main_spawn_id { # Continue to the point where we know for sure the threads are # started. - gdb_test "tbreak $srcfile:$main_break_line" \ - "Temporary breakpoint ${any}" \ - "set breakpoint in main" + gdb_breakpoint "$srcfile:$main_break_line" {temporary} gdb_continue_to_breakpoint "main breakpoint" @@ -321,9 +319,7 @@ proc test_continue_to_start { mode inf } { foreach thread { 2 3 } { gdb_test "thread $inf.$thread" ".*" "select child thread $inf.$thread" - gdb_test "tbreak $srcfile:$thread_loop_line" \ - "Temporary breakpoint ${any}" \ - "set breakpoint for thread $inf.$thread" + gdb_breakpoint "$srcfile:$thread_loop_line" {temporary} gdb_continue_to_breakpoint "continue thread $inf.$thread to infinite loop breakpoint" @@ -347,12 +343,8 @@ proc test_continue_to_start { mode inf } { # Put a thread-specific breakpoint for thread 2 of the current # inferior. We don't put a breakpoint for thread 3, since we # want to let it run. - set test "set thread-specific breakpoint, thread $inf.2" - gdb_test_multiple "tbreak $srcfile:$thread_loop_line thread $inf.2" $test { - -re "Temporary breakpoint ${any}\r\n$gdb_prompt " { - pass $test - } - } + gdb_breakpoint "$srcfile:$thread_loop_line thread $inf.2" \ + {temporary} # Confirm the stop of thread $inf.2. set test "thread $inf.2 stops CLI" diff --git a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp index 67069e1da4d..3c37c068b71 100644 --- a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp +++ b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp @@ -172,7 +172,7 @@ proc check_info_breakpoints { testname bp_number expected_loc_count } { # Create an inferior-specific breakpoint. Use gdb_test instead of # gdb_breakpoint here as we want to check the breakpoint was placed in # multiple locations. -gdb_breakpoint "foo inferior 1" -locs 2 -locspec "foo" +gdb_breakpoint "foo inferior 1" -locs 2 -locspec "foo" -inferior 1 set bp_number [get_integer_valueof "\$bpnum" "INVALID" \ "get b/p number for inferior specific breakpoint"] diff --git a/gdb/testsuite/gdb.multi/multi-target-continue.exp b/gdb/testsuite/gdb.multi/multi-target-continue.exp index d4b2fc28133..2e8dcae13bf 100644 --- a/gdb/testsuite/gdb.multi/multi-target-continue.exp +++ b/gdb/testsuite/gdb.multi/multi-target-continue.exp @@ -29,8 +29,7 @@ proc test_continue {non-stop} { } proc set_break {inf} { - gdb_test "break function${inf} thread ${inf}.1" \ - "Breakpoint ${::decimal} at ${::hex}: file .*, line ${::decimal}\\." + gdb_breakpoint "function${inf} thread ${inf}.1" } # Select inferior INF, and then run to a breakpoint on inferior diff --git a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp index 36f9d24a917..fe2683e9edb 100644 --- a/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp +++ b/gdb/testsuite/gdb.multi/multi-target-ping-pong-next.exp @@ -51,13 +51,11 @@ proc test_ping_pong_next {} { gdb_test "thread 1.1" "Switching to thread 1.1 .*" - gdb_test "break $srcfile:$line1 thread 1.1" \ - "Breakpoint .*$srcfile, line $line1\\." + gdb_breakpoint "$srcfile:$line1 thread 1.1" gdb_test "continue" "hit Breakpoint .*" - gdb_test "break $srcfile:$line2 thread 2.1" \ - "Breakpoint .*$srcfile, line $line2\\." + gdb_breakpoint "$srcfile:$line2 thread 2.1" # Now block inferior 1 and issue "next". We should stop at the # breakpoint for inferior 2, given schedlock off. diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 934690db2a1..e2f55f4e98e 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -765,7 +765,8 @@ proc_with_prefix test_bkpt_qualified {} { clean_restart ${testfile} set one_location_re "Breakpoint $decimal at $hex:.*line $decimal." - set two_location_re "Breakpoint $decimal at $hex:.*2 locations." + set two_location_re \ + "[gdb_multi_loc_regex "Breakpoint $decimal" 2]\[^\r\n\]*" if {![runto_main]} { return 0 diff --git a/gdb/testsuite/lib/completion-support.exp b/gdb/testsuite/lib/completion-support.exp index 5f0f6199894..e6f1c7b1f9f 100644 --- a/gdb/testsuite/lib/completion-support.exp +++ b/gdb/testsuite/lib/completion-support.exp @@ -417,6 +417,9 @@ proc completion::_create_bp {break_command} { -re "\\\(\($decimal\) locations\\\)\r\n$gdb_prompt $" { set found_locations "$expect_out(1,string)" } + -re "[gdb_multi_loc_regex "Breakpoint $decimal" $decimal]$gdb_prompt $" { + set found_locations 1 + } -re "Breakpoint $decimal at $hex: file .*, line .*$gdb_prompt $" { set found_locations 1 } diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index bcaf061a8ce..f72b42beeb8 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -668,12 +668,25 @@ proc gdb_starti_cmd { {inferior_args {}} } { return -1 } +# Construct a breakpoint regex for multiple bp locations given a breakpoint +# command BREAK_MESSAGE and a regex of expected locations LOCS. +# This is useful for constructing multiple location regex where the +# gdb_breakpoint proc cannot be used (for instance in completion tests). +# It is also used in proc gdb_breakpoint. + +proc gdb_multi_loc_regex { break_message locs {locspec ""} { inferior ""}} { + set fill "\[^\r\n]" + return [multi_line \ + "$break_message for $fill*$locspec at $locs locations:" \ + "(?: Location $::decimal at $::hex\[^\r\n\]*$inferior\.\\r\n)+" ] +} + # Set a breakpoint using LINESPEC. # # If there is an additional argument it is a list of options; the supported # options are allow-pending, temporary, message, no-message and qualified. # For multiple breakpoint locations additional options are used. These -# are -locspec, -locs and -extra: +# are -locspec, -locs, -extra, -add_locs and -inferior: # -locspec specifies a regex for the location spec output of the break command. # This is only used when multiple locations matching is enabled by # the -locs option. It is useful when a very specific breakpoint @@ -685,6 +698,8 @@ proc gdb_starti_cmd { {inferior_args {}} } { # treated as an error. # -extra allows specifying a regex for extra matches that need to appear in # the output. +# -add_locs specifies a regex for additional locations printed. +# -inferior specifies a regex for "in inferior" in the break command output. # # The result is 1 for success, 0 for failure. # @@ -701,6 +716,7 @@ proc gdb_breakpoint { linespec args } { parse_some_args { {locspec "\[^\r\n\]*"} {locs "\[0-9\]+"} + {add_locs ""} {extra ""} {inferior ""} } @@ -746,6 +762,20 @@ proc gdb_breakpoint { linespec args } { # Commonly used pattern. set fill "\[^\r\n]" + # If requested, expect "in inferior" in the locations output. + if { $inferior != ""} { + set inferior "in inferior $inferior" + } + + set multiloc_msg \ + [gdb_multi_loc_regex $break_message $locs $locspec $inferior] + + set additional_locs "" + if { $add_locs != "" } { + set additional_locs \ + "$add_locs additional location\[s\]* not printed\.\r\n" + } + # The extra regex is setup to not match unless the caller specifies # an extra match. gdb_test_multiple "$break_command $linespec" $test_name { @@ -762,7 +792,7 @@ proc gdb_breakpoint { linespec args } { -re -wrap "$break_message: file .*, line $decimal\\." { incr single_loc } - -re -wrap "$break_message at $::hex$fill*$locspec$fill*\\($locs locations\\)$fill+" { + -re "$multiloc_msg$additional_locs$gdb_prompt $" { incr multiple_locs } -re -wrap "$break_message at $fill+\." { -- 2.34.1 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928