1 # Copyright
2014-2022 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"
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.
39 # Force a breakpoint re-set in GDB. Currently this is done by
40 # reloading symbols with the "file" command.
42 proc force_breakpoint_re_set {} {
43 global binfile gdb_prompt
45 set test "file \$binfile"
46 gdb_test_multiple "file $binfile" $test {
47 -re "Are you sure you want to change the file. .*y or n. $" {
48 send_gdb "y\n" optional
51 -re "Load new symbol table from \".*\".*y or n. $" {
52 send_gdb "y\n" optional
55 -re "Reading symbols from.*$gdb_prompt $" {
61 # Set a break/hbreak/watch/rwatch/awatch.
63 proc set_breakpoint { break_command } {
64 global gdb_prompt srcfile
66 if { $break_command == "break" } {
67 gdb_test "$break_command foo" "Breakpoint.*at.* file .*$srcfile, line.*"
68 } elseif { $break_command == "hbreak" } {
69 set test "$break_command foo"
70 gdb_test_multiple $test $test {
71 -re "No hardware breakpoint support in the target.*$gdb_prompt $" {
74 -re "Hardware breakpoints used exceeds limit.*$gdb_prompt $" {
77 -re "Cannot insert hardware breakpoint.*$gdb_prompt $" {
80 -re "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*$gdb_prompt $" {
84 } elseif { [string first "watch" $break_command] != -1 } {
85 set test "$break_command global"
86 gdb_test_multiple $test $test {
87 -re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
90 -re "Could not insert hardware watchpoint.*$gdb_prompt $" {
93 -re "atchpoint \[0-9\]+: global\r\n$gdb_prompt $" {
98 error "unhandled command: $break_command"
102 # Run the test proper. ALWAYS_INSERT determines whether
103 # always-inserted mode is on/off, and BREAK_COMMAND is the
104 # break/watch/etc. command being tested.
106 proc test_break { always_inserted break_command } {
107 set cmd [lindex [split "$break_command"] 0]
109 with_test_prefix "$cmd" {
112 if ![runto_main] then {
116 gdb_test_no_output "set breakpoint always-inserted $always_inserted"
118 # Set breakpoints/watchpoints twice. With always-inserted on,
119 # GDB reinserts the exact same Z breakpoint twice... Do this
120 # to make sure the stub pays attention to idempotency even
121 # when the condition doesn't change.
If GDB end up optimizing
122 # out exact duplicate packets
, we should come up with a way to
123 # keep testing this case.
124 foreach iter
{ "once" "twice" } {
125 with_test_prefix $iter
{
126 set_breakpoint $break_command
130 # Force a breakpoint re
-set. In always
-inserted
mode, this
131 # makes GDB re
-send Z packets too...
132 force_breakpoint_re_set
134 # Now really change the condition
, which forces a reinsert by
136 gdb_test
"condition \$bpnum cond_global == 0" ".*"
138 # Now
delete breakpoints
, and let the
program execute the
139 # address where the breakpoint used to be
set.
If the target
140 # doesn
't treat insertions an idempotent way, we'll
get a
143 gdb_test
"b bar" "Breakpoint .* at .*"
144 gdb_test
"continue" "Breakpoint .*, bar .*"
148 # The testcase uses the
"file" command to force breakpoint re-set in
149 # GDB. Test both with and without PIE
, as GDB used to mishandle
150 # breakpoint re
-set when reloading PIEs.
151 foreach_with_prefix pie
{ "nopie" "pie" } {
156 set binfile
[standard_output_file $testfile
-$pie
]
158 if {[prepare_for_testing
"failed to prepare" $binfile $srcfile $opts]} {
162 if [is_remote host
] {
163 set arg [remote_download host $binfile
]
165 untested
"download failed"
170 foreach_with_prefix always_inserted
{ "off" "on" } {
171 test_break $always_inserted
"break"
173 if {![skip_hw_breakpoint_tests
]} {
174 test_break $always_inserted
"hbreak"
177 if {![skip_hw_watchpoint_tests
]} {
178 test_break $always_inserted
"watch"
181 if {![skip_hw_watchpoint_access_tests
]
182 && ![skip_hw_watchpoint_multi_tests
]} {
183 test_break $always_inserted
"rwatch"
184 test_break $always_inserted
"awatch"