forked from Imagelibrary/binutils-gdb
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
194 lines
6.2 KiB
Plaintext
194 lines
6.2 KiB
Plaintext
# Copyright 2014-2024 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
|
|
|
|
# The allow_hw_watchpoint_tests starts GDB on a small test program to
|
|
# check if HW watchpoints are supported. We do not want to restart
|
|
# GDB after this test script has itself started GDB, so call
|
|
# allow_hw_watchpoint_tests first and cache the result.
|
|
set allow_hw_watchpoint_tests_p [allow_hw_watchpoint_tests]
|
|
|
|
# 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" optional
|
|
exp_continue
|
|
}
|
|
-re "Load new symbol table from \".*\".*y or n. $" {
|
|
send_gdb "y\n" optional
|
|
exp_continue
|
|
}
|
|
-re "Reading symbols from.*$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 "$cmd" {
|
|
delete_breakpoints
|
|
|
|
if {![runto_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 .*"
|
|
}
|
|
}
|
|
|
|
# The testcase uses the "file" command to force breakpoint re-set in
|
|
# GDB. Test both with and without PIE, as GDB used to mishandle
|
|
# breakpoint re-set when reloading PIEs.
|
|
foreach_with_prefix pie { "nopie" "pie" } {
|
|
|
|
set opts {debug}
|
|
lappend opts $pie
|
|
|
|
set binfile [standard_output_file $testfile-$pie]
|
|
|
|
if {[prepare_for_testing "failed to prepare" $binfile $srcfile $opts]} {
|
|
continue
|
|
}
|
|
|
|
if [is_remote host] {
|
|
set arg [remote_download host $binfile]
|
|
if { $arg == "" } {
|
|
untested "download failed"
|
|
continue
|
|
}
|
|
}
|
|
|
|
foreach_with_prefix always_inserted { "off" "on" } {
|
|
test_break $always_inserted "break"
|
|
|
|
if {[allow_hw_breakpoint_tests]} {
|
|
test_break $always_inserted "hbreak"
|
|
}
|
|
|
|
if {$allow_hw_watchpoint_tests_p} {
|
|
test_break $always_inserted "watch"
|
|
}
|
|
|
|
if {[allow_hw_watchpoint_access_tests]
|
|
&& [allow_hw_watchpoint_multi_tests]} {
|
|
test_break $always_inserted "rwatch"
|
|
test_break $always_inserted "awatch"
|
|
}
|
|
}
|
|
}
|