5fccc63539
Hi, I see this fails below on arm linux native testing and remote testing with "set remote hardware-watchpoint-limit 1", rwatch global^M There are not enough available hardware resources for this watchpoint.^M (gdb) FAIL: gdb.base/break-idempotent.exp: always-inserted off: rwatch: twice: rwatch global gdb.base/break-idempotent.exp sets two breakpoints/watchpoints on the same address. GDB isn't smart enough calculate these two HW watchpoints can fit in one HW debug register, so the error message above isn't necessary (there is one HW watchpoint register on arm). Because target_ops interface can_use_hardware_watchpoint doesn't pass enough information to the target backend. Note that if I don't "set remote hardware-watchpoint-limit 1" in remote testing, this test passes without fails. However without "set remote hardware-watchpoint-limit 1", many other watchpoint tests fail. This patch is to add a check to skip_hw_watchpoint_multi_tests for rwatch and awatch. We can add such check for watch as well, but GDB is able to switch to software watchpoint if HW resource isn't available, it doesn't cause any fail, I decide not to skip. gdb/testsuite: 2015-04-30 Yao Qi <yao.qi@linaro.org> * gdb.base/break-idempotent.exp: If skip_hw_watchpoint_multi_tests returns true, skip the tests on "rwatch" and "awatch".
182 lines
5.7 KiB
Text
182 lines
5.7 KiB
Text
# Copyright 2014-2015 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
# Test that the Zx breakpoint/watchpoint packets are idempotent.
|
|
|
|
# GDBserver used to not treat Zx breakpoints other than Z0 as
|
|
# idempotent, although it must, to avoid problems with
|
|
# retransmissions. Even without spurious transport problems, if the
|
|
# target supports target conditions or commands, GDB re-inserts Zx
|
|
# breakpoints even if they are already inserted, to update the
|
|
# target-side condition/commands. E.g., simply when a duplicate
|
|
# breakpoint is created, or when a shared library load causes a
|
|
# re-set, which creates duplicate locations while breakpoints are
|
|
# inserted, or when the condition is really changed while breakpoints
|
|
# are inserted. To make the test not depend on shared library support
|
|
# or on details of the breakpoint re-set implementation, or on GDB
|
|
# optimizing out re-sends if the condition hasn't actually changed, we
|
|
# force always-inserted on, and really change the breakpoint's
|
|
# condition. For good measure, test with both always-inserted "on"
|
|
# and "off" modes.
|
|
|
|
# The test is written in black-box style, and doesn't actually use
|
|
# anything target remote specific, so let it run on all targets.
|
|
|
|
standard_testfile
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] then {
|
|
fail "Can't run to main"
|
|
return 0
|
|
}
|
|
|
|
if [is_remote host] {
|
|
set arg [remote_download host $binfile]
|
|
if { $arg == "" } {
|
|
perror "download failed"
|
|
return -1
|
|
}
|
|
}
|
|
|
|
# Force a breakpoint re-set in GDB. Currently this is done by
|
|
# reloading symbols with the "file" command.
|
|
|
|
proc force_breakpoint_re_set {} {
|
|
global binfile gdb_prompt
|
|
|
|
set test "file \$binfile"
|
|
gdb_test_multiple "file $binfile" $test {
|
|
-re "Are you sure you want to change the file. .*y or n. $" {
|
|
send_gdb "y\n"
|
|
exp_continue
|
|
}
|
|
-re "Load new symbol table from \".*\".*y or n. $" {
|
|
send_gdb "y\n"
|
|
exp_continue
|
|
}
|
|
-re "Reading symbols from.*done.*$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
}
|
|
|
|
# Set a break/hbreak/watch/rwatch/awatch.
|
|
|
|
proc set_breakpoint { break_command } {
|
|
global gdb_prompt srcfile
|
|
|
|
if { $break_command == "break" } {
|
|
gdb_test "$break_command foo" "Breakpoint.*at.* file .*$srcfile, line.*"
|
|
} elseif { $break_command == "hbreak" } {
|
|
set test "$break_command foo"
|
|
gdb_test_multiple $test $test {
|
|
-re "No hardware breakpoint support in the target.*$gdb_prompt $" {
|
|
unsupported $test
|
|
}
|
|
-re "Hardware breakpoints used exceeds limit.*$gdb_prompt $" {
|
|
unsupported $test
|
|
}
|
|
-re "Cannot insert hardware breakpoint.*$gdb_prompt $" {
|
|
unsupported $test
|
|
}
|
|
-re "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
} elseif { [string first "watch" $break_command] != -1 } {
|
|
set test "$break_command global"
|
|
gdb_test_multiple $test $test {
|
|
-re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
|
|
unsupported $test
|
|
}
|
|
-re "Could not insert hardware watchpoint.*$gdb_prompt $" {
|
|
unsupported $test
|
|
}
|
|
-re "atchpoint \[0-9\]+: global\r\n$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
} else {
|
|
error "unhandled command: $break_command"
|
|
}
|
|
}
|
|
|
|
# Run the test proper. ALWAYS_INSERT determines whether
|
|
# always-inserted mode is on/off, and BREAK_COMMAND is the
|
|
# break/watch/etc. command being tested.
|
|
#
|
|
proc test_break { always_inserted break_command } {
|
|
set cmd [lindex [split "$break_command"] 0]
|
|
|
|
with_test_prefix "always-inserted $always_inserted: $cmd" {
|
|
delete_breakpoints
|
|
|
|
if ![runto_main] then {
|
|
fail "Can't run to main"
|
|
return
|
|
}
|
|
|
|
gdb_test_no_output "set breakpoint always-inserted $always_inserted"
|
|
|
|
# Set breakpoints/watchpoints twice. With always-inserted on,
|
|
# GDB reinserts the exact same Z breakpoint twice... Do this
|
|
# to make sure the stub pays attention to idempotency even
|
|
# when the condition doesn't change. If GDB end up optimizing
|
|
# out exact duplicate packets, we should come up with a way to
|
|
# keep testing this case.
|
|
foreach iter { "once" "twice" } {
|
|
with_test_prefix $iter {
|
|
set_breakpoint $break_command
|
|
}
|
|
}
|
|
|
|
# Force a breakpoint re-set. In always-inserted mode, this
|
|
# makes GDB re-send Z packets too...
|
|
force_breakpoint_re_set
|
|
|
|
# Now really change the condition, which forces a reinsert by
|
|
# design.
|
|
gdb_test "condition \$bpnum cond_global == 0" ".*"
|
|
|
|
# Now delete breakpoints, and let the program execute the
|
|
# address where the breakpoint used to be set. If the target
|
|
# doesn't treat insertions an idempotent way, we'll get a
|
|
# spurious SIGTRAP.
|
|
delete_breakpoints
|
|
gdb_test "b bar" "Breakpoint .* at .*"
|
|
gdb_test "continue" "Breakpoint .*, bar .*"
|
|
}
|
|
}
|
|
|
|
foreach always_inserted { "off" "on" } {
|
|
test_break $always_inserted "break"
|
|
|
|
if {![skip_hw_breakpoint_tests]} {
|
|
test_break $always_inserted "hbreak"
|
|
}
|
|
|
|
if {![skip_hw_watchpoint_tests]} {
|
|
test_break $always_inserted "watch"
|
|
}
|
|
|
|
if {![skip_hw_watchpoint_access_tests]
|
|
&& ![skip_hw_watchpoint_multi_tests]} {
|
|
test_break $always_inserted "rwatch"
|
|
test_break $always_inserted "awatch"
|
|
}
|
|
}
|