1# Copyright 2014-2015 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 37standard_testfile 38 39if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { 40 return -1 41} 42 43if ![runto_main] then { 44 fail "Can't run to main" 45 return 0 46} 47 48if [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 59proc 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.*done.*$gdb_prompt $" { 73 pass $test 74 } 75 } 76} 77 78# Set a break/hbreak/watch/rwatch/awatch. 79 80proc 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# 123proc 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 166foreach 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 test_break $always_inserted "rwatch" 179 test_break $always_inserted "awatch" 180 } 181} 182