]>
Commit | Line | Data |
---|---|---|
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 | ||
37 | standard_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. | |
43 | set 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 | ||
48 | proc 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 | ||
69 | proc 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 | # | |
112 | proc 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. | |
157 | foreach_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 | } |