]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.base/break-idempotent.exp
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / break-idempotent.exp
CommitLineData
213516ef 1# Copyright 2014-2023 Free Software Foundation, Inc.
802e8e6d
PA
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16# Test that the Zx breakpoint/watchpoint packets are idempotent.
17
18# GDBserver used to not treat Zx breakpoints other than Z0 as
19# idempotent, although it must, to avoid problems with
20# retransmissions. Even without spurious transport problems, if the
21# target supports target conditions or commands, GDB re-inserts Zx
22# breakpoints even if they are already inserted, to update the
23# target-side condition/commands. E.g., simply when a duplicate
24# breakpoint is created, or when a shared library load causes a
25# re-set, which creates duplicate locations while breakpoints are
26# inserted, or when the condition is really changed while breakpoints
27# are inserted. To make the test not depend on shared library support
28# or on details of the breakpoint re-set implementation, or on GDB
29# optimizing out re-sends if the condition hasn't actually changed, we
30# force always-inserted on, and really change the breakpoint's
31# condition. For good measure, test with both always-inserted "on"
32# and "off" modes.
33
34# The test is written in black-box style, and doesn't actually use
35# anything target remote specific, so let it run on all targets.
36
37standard_testfile
38
13f72372
CL
39# The skip_hw_watchpoint_tests starts GDB on a small test program to
40# check if HW watchpoints are supported. We do not want to restart
41# GDB after this test script has itself started GDB, so call
42# skip_hw_watchpoint_tests first and cache the result.
43set skip_hw_watchpoint_tests_p [skip_hw_watchpoint_tests]
44
802e8e6d
PA
45# Force a breakpoint re-set in GDB. Currently this is done by
46# reloading symbols with the "file" command.
47
48proc force_breakpoint_re_set {} {
49 global binfile gdb_prompt
50
51 set test "file \$binfile"
52 gdb_test_multiple "file $binfile" $test {
53 -re "Are you sure you want to change the file. .*y or n. $" {
ea142fbf 54 send_gdb "y\n" optional
802e8e6d
PA
55 exp_continue
56 }
57 -re "Load new symbol table from \".*\".*y or n. $" {
ea142fbf 58 send_gdb "y\n" optional
802e8e6d
PA
59 exp_continue
60 }
3453e7e4 61 -re "Reading symbols from.*$gdb_prompt $" {
802e8e6d
PA
62 pass $test
63 }
64 }
65}
66
67# Set a break/hbreak/watch/rwatch/awatch.
68
69proc set_breakpoint { break_command } {
70 global gdb_prompt srcfile
71
72 if { $break_command == "break" } {
73 gdb_test "$break_command foo" "Breakpoint.*at.* file .*$srcfile, line.*"
74 } elseif { $break_command == "hbreak" } {
75 set test "$break_command foo"
76 gdb_test_multiple $test $test {
77 -re "No hardware breakpoint support in the target.*$gdb_prompt $" {
78 unsupported $test
79 }
80 -re "Hardware breakpoints used exceeds limit.*$gdb_prompt $" {
81 unsupported $test
82 }
83 -re "Cannot insert hardware breakpoint.*$gdb_prompt $" {
84 unsupported $test
85 }
86 -re "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*$gdb_prompt $" {
87 pass $test
88 }
89 }
90 } elseif { [string first "watch" $break_command] != -1 } {
91 set test "$break_command global"
92 gdb_test_multiple $test $test {
93 -re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
94 unsupported $test
95 }
96 -re "Could not insert hardware watchpoint.*$gdb_prompt $" {
97 unsupported $test
98 }
99 -re "atchpoint \[0-9\]+: global\r\n$gdb_prompt $" {
100 pass $test
101 }
102 }
103 } else {
104 error "unhandled command: $break_command"
105 }
106}
107
108# Run the test proper. ALWAYS_INSERT determines whether
109# always-inserted mode is on/off, and BREAK_COMMAND is the
110# break/watch/etc. command being tested.
111#
112proc test_break { always_inserted break_command } {
113 set cmd [lindex [split "$break_command"] 0]
114
ea142fbf 115 with_test_prefix "$cmd" {
802e8e6d
PA
116 delete_breakpoints
117
65a33d75 118 if {![runto_main]} {
802e8e6d
PA
119 return
120 }
121
122 gdb_test_no_output "set breakpoint always-inserted $always_inserted"
123
124 # Set breakpoints/watchpoints twice. With always-inserted on,
125 # GDB reinserts the exact same Z breakpoint twice... Do this
126 # to make sure the stub pays attention to idempotency even
127 # when the condition doesn't change. If GDB end up optimizing
128 # out exact duplicate packets, we should come up with a way to
129 # keep testing this case.
130 foreach iter { "once" "twice" } {
131 with_test_prefix $iter {
132 set_breakpoint $break_command
133 }
134 }
135
136 # Force a breakpoint re-set. In always-inserted mode, this
137 # makes GDB re-send Z packets too...
138 force_breakpoint_re_set
139
140 # Now really change the condition, which forces a reinsert by
141 # design.
142 gdb_test "condition \$bpnum cond_global == 0" ".*"
143
144 # Now delete breakpoints, and let the program execute the
145 # address where the breakpoint used to be set. If the target
146 # doesn't treat insertions an idempotent way, we'll get a
147 # spurious SIGTRAP.
148 delete_breakpoints
149 gdb_test "b bar" "Breakpoint .* at .*"
150 gdb_test "continue" "Breakpoint .*, bar .*"
151 }
152}
153
ea142fbf
AH
154# The testcase uses the "file" command to force breakpoint re-set in
155# GDB. Test both with and without PIE, as GDB used to mishandle
156# breakpoint re-set when reloading PIEs.
157foreach_with_prefix pie { "nopie" "pie" } {
158
159 set opts {debug}
160 lappend opts $pie
802e8e6d 161
ea142fbf
AH
162 set binfile [standard_output_file $testfile-$pie]
163
164 if {[prepare_for_testing "failed to prepare" $binfile $srcfile $opts]} {
165 continue
802e8e6d
PA
166 }
167
ea142fbf
AH
168 if [is_remote host] {
169 set arg [remote_download host $binfile]
170 if { $arg == "" } {
171 untested "download failed"
172 continue
173 }
802e8e6d
PA
174 }
175
ea142fbf
AH
176 foreach_with_prefix always_inserted { "off" "on" } {
177 test_break $always_inserted "break"
178
179 if {![skip_hw_breakpoint_tests]} {
180 test_break $always_inserted "hbreak"
181 }
182
13f72372 183 if {!$skip_hw_watchpoint_tests_p} {
ea142fbf
AH
184 test_break $always_inserted "watch"
185 }
186
187 if {![skip_hw_watchpoint_access_tests]
188 && ![skip_hw_watchpoint_multi_tests]} {
189 test_break $always_inserted "rwatch"
190 test_break $always_inserted "awatch"
191 }
802e8e6d
PA
192 }
193}