diff options
-rw-r--r-- | gdb/breakpoint.c | 30 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/tasks.exp | 15 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/save-bp.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/thread-bp-multi-loc.c | 44 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/thread-bp-multi-loc.exp | 67 |
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 + } +} |