summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/breakpoint.c30
-rw-r--r--gdb/testsuite/gdb.ada/tasks.exp15
-rw-r--r--gdb/testsuite/gdb.base/save-bp.exp2
-rw-r--r--gdb/testsuite/gdb.base/thread-bp-multi-loc.c44
-rw-r--r--gdb/testsuite/gdb.base/thread-bp-multi-loc.exp67
5 files changed, 136 insertions, 22 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 8bc62743bb5..adf38e7d722 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6468,20 +6468,19 @@ print_one_breakpoint_location (struct breakpoint *b,
output_thread_groups (uiout, "thread-groups", inf_nums, mi_only);
}
- if (!part_of_multiple)
+ /* In the MI output, each location of a thread or task specific
+ breakpoint includes the relevant thread or task ID. This is done for
+ backwards compatibility reasons.
+
+ For the CLI output, the thread/task information is printed on a
+ separate line, see the 'stop only in thread' and 'stop only in task'
+ output below. */
+ if (!header_of_multiple && uiout->is_mi_like_p ())
{
if (b->thread != -1)
- {
- /* FIXME: This seems to be redundant and lost here; see the
- "stop only in" line a little further down. */
- uiout->text (" thread ");
- uiout->field_signed ("thread", b->thread);
- }
+ uiout->field_signed ("thread", b->thread);
else if (b->task != 0)
- {
- uiout->text (" task ");
- uiout->field_signed ("task", b->task);
- }
+ uiout->field_signed ("task", b->task);
}
uiout->text ("\n");
@@ -6536,7 +6535,14 @@ print_one_breakpoint_location (struct breakpoint *b,
}
uiout->text ("\n");
}
-
+
+ if (!part_of_multiple && b->task != 0)
+ {
+ uiout->text ("\tstop only in task ");
+ uiout->field_signed ("task", b->task);
+ uiout->text ("\n");
+ }
+
if (!part_of_multiple)
{
if (b->hit_count)
diff --git a/gdb/testsuite/gdb.ada/tasks.exp b/gdb/testsuite/gdb.ada/tasks.exp
index 3eea04b3911..88ef123865b 100644
--- a/gdb/testsuite/gdb.ada/tasks.exp
+++ b/gdb/testsuite/gdb.ada/tasks.exp
@@ -50,21 +50,18 @@ gdb_test "watch j task 1 task 3" "You can specify only one task\\."
# breakpoint in the list that matched the triggered-breakpoint's
# address, no matter which task it was specific to.
gdb_test "break break_me task 1" "Breakpoint .* at .*"
+gdb_test "info breakpoints" "foo.adb:${decimal}\r\n\\s+stop only in task 1" \
+ "check info breakpoints for task 1 breakpoint"
# Now, insert a breakpoint that should stop only if task 3 stops, and
# extract its number.
-set bp_number -1
-set test "break break_me task 3"
-gdb_test_multiple $test $test {
- -re "Breakpoint (.*) at .*$gdb_prompt $" {
- set bp_number $expect_out(1,string)
- pass $test
- }
-}
-
+gdb_breakpoint "break_me task 3" message
+set bp_number [get_integer_valueof "\$bpnum" -1]
if {$bp_number < 0} {
return
}
+gdb_test "info breakpoints" "foo.adb:${decimal}\r\n\\s+stop only in task 3" \
+ "check info breakpoints for task 3 breakpoint"
# Continue to that breakpoint. Task 2 should hit it first, and GDB
# is expected to ignore that hit and resume the execution. Only then
diff --git a/gdb/testsuite/gdb.base/save-bp.exp b/gdb/testsuite/gdb.base/save-bp.exp
index a39712c7f5c..41d71837fb6 100644
--- a/gdb/testsuite/gdb.base/save-bp.exp
+++ b/gdb/testsuite/gdb.base/save-bp.exp
@@ -79,7 +79,7 @@ gdb_test_sequence "info break" "info break" [list \
"\[\r\n\]+Num +Type +Disp +Enb +Address +What" \
"\[\r\n\]+$bp_row_start break_me at \[^\r\n\]*$srcfile:\[0-9\]+" \
"\[\r\n\]+$bp_row_start main at \[^\r\n\]*$srcfile:$loc_bp2" \
- "\[\r\n\]+$bp_row_start main at \[^\r\n\]*$srcfile:$loc_bp3 +thread 1" \
+ "\[\r\n\]+$bp_row_start main at \[^\r\n\]*$srcfile:$loc_bp3" \
"\[\r\n\]+\[ \t]+stop only in thread 1" \
"\[\r\n\]+$bp_row_start main at \[^\r\n\]*$srcfile:$loc_bp4" \
"\[\r\n\]+\[ \t\]+stop only if i == 1( \\((host|target) evals\\))?" \
diff --git a/gdb/testsuite/gdb.base/thread-bp-multi-loc.c b/gdb/testsuite/gdb.base/thread-bp-multi-loc.c
new file mode 100644
index 00000000000..2adb179d93c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/thread-bp-multi-loc.c
@@ -0,0 +1,44 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2022-2023 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 <http://www.gnu.org/licenses/>. */
+
+volatile int global_var = 0;
+
+__attribute__((__always_inline__)) static inline void
+foo (void)
+{
+ int i;
+
+ for (i = 0; i < 10; ++i)
+ global_var = i;
+}
+
+static void
+bar (void)
+{
+ global_var = 0;
+ foo ();
+}
+
+int
+main (void)
+{
+ global_var = 0;
+ foo ();
+ bar ();
+ foo ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/thread-bp-multi-loc.exp b/gdb/testsuite/gdb.base/thread-bp-multi-loc.exp
new file mode 100644
index 00000000000..6e1121e867a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/thread-bp-multi-loc.exp
@@ -0,0 +1,67 @@
+# Copyright 2022-2023 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 <http://www.gnu.org/licenses/>.
+
+# Create a multi-location breakpoint with a thread condition, then check the
+# output of 'info breakpoints' to ensure that the thread condition is
+# displayed correctly.
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+ return -1
+}
+
+if {![runto_main]} {
+ return -1
+}
+
+delete_breakpoints
+
+gdb_breakpoint "foo thread 1"
+set bp_number [get_integer_valueof "\$bpnum" 0]
+if { $bp_number == 0 } {
+ unresolved "breakpoint not placed correctly"
+ return -1
+}
+
+set saw_header false
+set saw_cond false
+set loc_count 0
+gdb_test_multiple "info breakpoints" \
+ "check thread condition is displayed correctly" {
+ -re "\r\nNum\\s+\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+
+ -re "^$bp_number\\s+breakpoint\\s+keep\\s+y\\s+<MULTIPLE>\\s*\r\n" {
+ set saw_header true
+ exp_continue
+ }
+
+ -re "^\\s+stop only in thread 1\r\n" {
+ set saw_cond true
+ exp_continue
+ }
+
+ -re "^$bp_number\\.\[123\]\\s+\[^\r\n\]+:${decimal}\r\n" {
+ incr loc_count
+ exp_continue
+ }
+
+ -re "^$gdb_prompt $" {
+ gdb_assert { $saw_header && $saw_cond && $loc_count == 3} \
+ $gdb_test_name
+ }
+}