902a5f818be9971422b5cfb154a2f28c7ab998da
[external/binutils.git] / gdb / testsuite / gdb.base / break-idempotent.exp
1 # Copyright 2014-2019 Free Software Foundation, Inc.
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
37 standard_testfile
38
39 if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
40     return -1
41 }
42
43 if ![runto_main] then {
44     fail "can't run to main"
45     return 0
46 }
47
48 if [is_remote host] {
49     set arg [remote_download host $binfile]
50     if { $arg == "" } {
51         perror "download failed"
52         return -1
53     }
54 }
55
56 # Force a breakpoint re-set in GDB.  Currently this is done by
57 # reloading symbols with the "file" command.
58
59 proc force_breakpoint_re_set {} {
60     global binfile gdb_prompt
61
62     set test "file \$binfile"
63     gdb_test_multiple "file $binfile" $test {
64         -re "Are you sure you want to change the file. .*y or n. $" {
65             send_gdb "y\n"
66             exp_continue
67         }
68         -re "Load new symbol table from \".*\".*y or n. $" {
69             send_gdb "y\n"
70             exp_continue
71         }
72         -re "Reading symbols from.*$gdb_prompt $" {
73             pass $test
74         }
75     }
76 }
77
78 # Set a break/hbreak/watch/rwatch/awatch.
79
80 proc set_breakpoint { break_command } {
81     global gdb_prompt srcfile
82
83     if { $break_command == "break" } {
84         gdb_test "$break_command foo" "Breakpoint.*at.* file .*$srcfile, line.*"
85     } elseif { $break_command == "hbreak" } {
86         set test "$break_command foo"
87         gdb_test_multiple $test $test {
88             -re "No hardware breakpoint support in the target.*$gdb_prompt $" {
89                 unsupported $test
90             }
91             -re "Hardware breakpoints used exceeds limit.*$gdb_prompt $" {
92                 unsupported $test
93             }
94             -re "Cannot insert hardware breakpoint.*$gdb_prompt $" {
95                 unsupported $test
96             }
97             -re "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*$gdb_prompt $" {
98                 pass $test
99             }
100         }
101     } elseif { [string first "watch" $break_command] != -1 } {
102         set test "$break_command global"
103         gdb_test_multiple $test $test {
104             -re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
105                 unsupported $test
106             }
107             -re "Could not insert hardware watchpoint.*$gdb_prompt $" {
108                 unsupported $test
109             }
110             -re "atchpoint \[0-9\]+: global\r\n$gdb_prompt $" {
111                 pass $test
112             }
113         }
114     } else {
115         error "unhandled command: $break_command"
116     }
117 }
118
119 # Run the test proper.  ALWAYS_INSERT determines whether
120 # always-inserted mode is on/off, and BREAK_COMMAND is the
121 # break/watch/etc. command being tested.
122 #
123 proc test_break { always_inserted break_command } {
124     set cmd [lindex [split "$break_command"] 0]
125
126     with_test_prefix "always-inserted $always_inserted: $cmd" {
127         delete_breakpoints
128
129         if ![runto_main] then {
130             fail "can't run to main"
131             return
132         }
133
134         gdb_test_no_output "set breakpoint always-inserted $always_inserted"
135
136         # Set breakpoints/watchpoints twice.  With always-inserted on,
137         # GDB reinserts the exact same Z breakpoint twice...  Do this
138         # to make sure the stub pays attention to idempotency even
139         # when the condition doesn't change.  If GDB end up optimizing
140         # out exact duplicate packets, we should come up with a way to
141         # keep testing this case.
142         foreach iter { "once" "twice" } {
143             with_test_prefix $iter {
144                 set_breakpoint $break_command
145             }
146         }
147
148         # Force a breakpoint re-set.  In always-inserted mode, this
149         # makes GDB re-send Z packets too...
150         force_breakpoint_re_set
151
152         # Now really change the condition, which forces a reinsert by
153         # design.
154         gdb_test "condition \$bpnum cond_global == 0" ".*"
155
156         # Now delete breakpoints, and let the program execute the
157         # address where the breakpoint used to be set.  If the target
158         # doesn't treat insertions an idempotent way, we'll get a
159         # spurious SIGTRAP.
160         delete_breakpoints
161         gdb_test "b bar" "Breakpoint .* at .*"
162         gdb_test "continue" "Breakpoint .*, bar .*"
163     }
164 }
165
166 foreach always_inserted { "off" "on" } {
167     test_break $always_inserted "break"
168
169     if {![skip_hw_breakpoint_tests]} {
170         test_break $always_inserted "hbreak"
171     }
172
173     if {![skip_hw_watchpoint_tests]} {
174         test_break $always_inserted "watch"
175     }
176
177     if {![skip_hw_watchpoint_access_tests]
178         && ![skip_hw_watchpoint_multi_tests]} {
179         test_break $always_inserted "rwatch"
180         test_break $always_inserted "awatch"
181     }
182 }