[gdb/syscalls] Sync with strace v6.13
[binutils-gdb.git] / gdb / testsuite / gdb.base / break-idempotent.exp
blob0903841e5be93a7c4c2ba312c00f6dd28d85f20c
1 # Copyright 2014-2024 Free Software Foundation, Inc.
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.
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.
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/>.  */
16 # Test that the Zx breakpoint/watchpoint packets are idempotent.
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.
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.
37 standard_testfile
39 # The allow_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 # allow_hw_watchpoint_tests first and cache the result.
43 set allow_hw_watchpoint_tests_p [allow_hw_watchpoint_tests]
45 # Force a breakpoint re-set in GDB.  Currently this is done by
46 # reloading symbols with the "file" command.
48 proc force_breakpoint_re_set {} {
49     global binfile gdb_prompt
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. $" {
54             send_gdb "y\n" optional
55             exp_continue
56         }
57         -re "Load new symbol table from \".*\".*y or n. $" {
58             send_gdb "y\n" optional
59             exp_continue
60         }
61         -re "Reading symbols from.*$gdb_prompt $" {
62             pass $test
63         }
64     }
67 # Set a break/hbreak/watch/rwatch/awatch.
69 proc set_breakpoint { break_command } {
70     global gdb_prompt srcfile
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     }
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.
112 proc test_break { always_inserted break_command } {
113     set cmd [lindex [split "$break_command"] 0]
115     with_test_prefix "$cmd" {
116         delete_breakpoints
118         if {![runto_main]} {
119             return
120         }
122         gdb_test_no_output "set breakpoint always-inserted $always_inserted"
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         }
136         # Force a breakpoint re-set.  In always-inserted mode, this
137         # makes GDB re-send Z packets too...
138         force_breakpoint_re_set
140         # Now really change the condition, which forces a reinsert by
141         # design.
142         gdb_test "condition \$bpnum cond_global == 0" ".*"
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     }
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.
157 foreach_with_prefix pie { "nopie" "pie" } {
159     set opts {debug}
160     lappend opts $pie
162     set binfile [standard_output_file $testfile-$pie]
164     if {[prepare_for_testing "failed to prepare" $binfile $srcfile $opts]} {
165         continue
166     }
168     if [is_remote host] {
169         set arg [remote_download host $binfile]
170         if { $arg == "" } {
171             untested "download failed"
172             continue
173         }
174     }
176     foreach_with_prefix always_inserted { "off" "on" } {
177         test_break $always_inserted "break"
179         if {[allow_hw_breakpoint_tests]} {
180             test_break $always_inserted "hbreak"
181         }
183         if {$allow_hw_watchpoint_tests_p} {
184             test_break $always_inserted "watch"
185         }
187         if {[allow_hw_watchpoint_access_tests]
188             && [allow_hw_watchpoint_multi_tests]} {
189             test_break $always_inserted "rwatch"
190             test_break $always_inserted "awatch"
191         }
192     }