binutils-gdb/gdb/testsuite/gdb.base/watchpoint-unaligned.exp

185 lines
5.5 KiB
Plaintext
Raw Normal View History

aarch64: PR 19806: watchpoints: false negatives + PR 20207 contiguous ones Some unaligned watchpoints were currently missed. On old kernels as specified in kernel RFE: aarch64: ptrace: BAS: Support any contiguous range (edit) https://sourceware.org/bugzilla/show_bug.cgi?id=20207 after this patch some other unaligned watchpoints will get reported as false positives. With new kernels all the watchpoints should work exactly. There may be a regresion that it now less merges watchpoints so that with multiple overlapping watchpoints it may run out of the 4 hardware watchpoint registers. But as discussed in the original thread GDB needs some generic watchpoints merging framework to be used by all the target specific code. Even current FSF GDB code does not merge it perfectly. Also with the more precise watchpoints one can technically merge them less. And I do not think it matters too much to improve mergeability only for old kernels. Still even on new kernels some better merging logic would make sense. There remains one issue: kernel-4.15.14-300.fc27.armv7hl FAIL: gdb.base/watchpoint-unaligned.exp: continue FAIL: gdb.base/watchpoint-unaligned.exp: continue (gdb) continue Continuing. Unexpected error setting watchpoint: Invalid argument. (gdb) FAIL: gdb.base/watchpoint-unaligned.exp: continue But that looks as a kernel bug to me. (1) It is not a regression by this patch. (2) It is unrelated to this patch. gdb/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> PR breakpoints/19806 and support for PR external/20207. * NEWS: Mention Aarch64 watchpoint improvements. * aarch64-linux-nat.c (aarch64_linux_stopped_data_address): Fix missed watchpoints and PR external/20207 watchpoints. * nat/aarch64-linux-hw-point.c (kernel_supports_any_contiguous_range): New. (aarch64_watchpoint_offset): New. (aarch64_watchpoint_length): Support PR external/20207 watchpoints. (aarch64_point_encode_ctrl_reg): New parameter offset, new asserts. (aarch64_point_is_aligned): Support PR external/20207 watchpoints. (aarch64_align_watchpoint): New parameters aligned_offset_p and next_addr_orig_p. Support PR external/20207 watchpoints. (aarch64_downgrade_regs): New. (aarch64_dr_state_insert_one_point): New parameters offset and addr_orig. (aarch64_dr_state_remove_one_point): Likewise. (aarch64_handle_breakpoint): Update caller. (aarch64_handle_aligned_watchpoint): Likewise. (aarch64_handle_unaligned_watchpoint): Support addr_orig and aligned_offset. (aarch64_linux_set_debug_regs): Remove const from state. Call aarch64_downgrade_regs. (aarch64_show_debug_reg_state): Print also dr_addr_orig_wp. * nat/aarch64-linux-hw-point.h (DR_CONTROL_LENGTH): Rename to ... (DR_CONTROL_MASK): ... this. (struct aarch64_debug_reg_state): New field dr_addr_orig_wp. (unsigned int aarch64_watchpoint_offset): New prototype. (aarch64_linux_set_debug_regs): Remove const from state. * utils.c (align_up, align_down): Move to ... * common/common-utils.c (align_up, align_down): ... here. * utils.h (align_up, align_down): Move to ... * common/common-utils.h (align_up, align_down): ... here. gdb/gdbserver/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> * linux-aarch64-low.c (aarch64_stopped_data_address): Likewise. gdb/testsuite/ChangeLog 2018-05-04 Jan Kratochvil <jan.kratochvil@redhat.com> Pedro Alves <palves@redhat.com> PR breakpoints/19806 and support for PR external/20207. * gdb.base/watchpoint-unaligned.c: New file. * gdb.base/watchpoint-unaligned.exp: New file.
2018-05-04 22:22:04 +02:00
# Copyright 2017-2018 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/>.
#
# This file is part of the gdb testsuite.
# Test inserting read watchpoints on unaligned addresses.
standard_testfile
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
return -1
}
if ![runto_main] {
untested "could not run to main"
return -1
}
gdb_breakpoint [gdb_get_line_number "start_again"] "Breakpoint $decimal at $hex" "start_again"
set sizes {1 2 4 8}
array set alignedend {1 1 2 2 3 4 4 4 5 8 6 8 7 8 8 8}
set rwatch "rwatch"
set rwatch_exp "Hardware read watchpoint"
if {[istarget "s390*-*-*"]} {
# Target does not support this type of hardware watchpoint."
set rwatch "watch"
set rwatch_exp "Hardware watchpoint"
}
foreach wpsize $sizes {
for {set wpoffset 0} {$wpoffset < 8 / $wpsize} {incr wpoffset} {
set wpstart [expr $wpoffset * $wpsize]
set wpend [expr ($wpoffset + 1) * $wpsize]
set wpendaligned $alignedend($wpend)
foreach rdsize $sizes {
for {set rdoffset 0} {$rdoffset < 8 / $rdsize} {incr rdoffset} {
set rdstart [expr $rdoffset * $rdsize]
set rdend [expr ($rdoffset + 1) * $rdsize]
set expect_hit [expr max ($wpstart, $rdstart) < min ($wpend, $rdend)]
set test "$rwatch data.u.size$wpsize\[$wpoffset\]"
set wpnum ""
gdb_test_multiple $test $test {
-re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" {
set wpnum $expect_out(1,string)
}
-re "Expression cannot be implemented with read/access watchpoint.\r\n$gdb_prompt $" {
if {$wpsize == 8 && [istarget "arm*-*-*"]} {
untested $test
continue
}
fail $test
}
}
gdb_test_no_output "set variable size = $rdsize" ""
gdb_test_no_output "set variable offset = $rdoffset" ""
set test "continue"
set got_hit 0
gdb_test_multiple $test $test {
-re "$rwatch_exp $wpnum:.*alue = .*\r\n$gdb_prompt $" {
set got_hit 1
send_gdb "continue\n"
exp_continue
}
-re " start_again .*\r\n$gdb_prompt $" {
}
}
gdb_test_no_output "delete $wpnum" ""
set test "wp(size=$wpsize offset=$wpoffset) rd(size=$rdsize offset=$rdoffset) expect=$expect_hit"
if {$expect_hit == $got_hit} {
pass $test
} else {
# We do not know if we run on a fixed Linux kernel
# or not. Report XFAIL only in the FAIL case.
if {$expect_hit == 0 && $rdstart < $wpendaligned} {
setup_xfail external/20207 "aarch64*-*-linux*"
}
if {!$expect_hit && [expr max ($wpstart / 8, $rdstart / 8) < min (($wpend + 7) / 8, ($rdend + 7) / 8)]} {
setup_xfail breakpoints/23131 "powerpc*-*-*"
}
fail $test
}
}
}
}
}
foreach wpcount {4 7} {
array set wpoffset_to_wpnum {}
for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} {
set test "$rwatch data.u.size1\[$wpoffset\]"
set wpnum ""
gdb_test_multiple $test $test {
-re "$rwatch_exp (\[0-9\]+): .*\r\n$gdb_prompt $" {
set wpoffset_to_wpnum($wpoffset) $expect_out(1,string)
}
-re "There are not enough available hardware resources for this watchpoint.\r\n$gdb_prompt $" {
if {$wpoffset > 1} {
setup_xfail breakpoints/23131 "powerpc*-*-*"
setup_xfail breakpoints/23131 "arm*-*-*"
}
fail $test
set wpoffset_to_wpnum($wpoffset) 0
}
}
}
gdb_test_no_output "set variable size = 1" ""
gdb_test_no_output "set variable offset = 1" ""
set test "continue"
set got_hit 0
gdb_test_multiple $test $test {
-re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" {
}
-re "$rwatch_exp $wpoffset_to_wpnum(1):.*alue = .*\r\n$gdb_prompt $" {
set got_hit 1
send_gdb "continue\n"
exp_continue
}
-re " start_again .*\r\n$gdb_prompt $" {
}
}
for {set wpoffset 1} {$wpoffset <= $wpcount} {incr wpoffset} {
if {$wpoffset_to_wpnum($wpoffset)} {
gdb_test_no_output "delete $wpoffset_to_wpnum($wpoffset)" ""
}
}
set test "wpcount($wpcount)"
if {!$wpoffset_to_wpnum([expr $wpcount - 1])} {
untested $test
continue
}
if {$wpcount > 4} {
if {![istarget "s390*-*-*"]} {
setup_kfail tdep/22389 *-*-*
}
}
gdb_assert $got_hit $test
}
if ![runto_main] {
return -1
}
gdb_breakpoint [gdb_get_line_number "final_return"] "Breakpoint $decimal at $hex" "final_return"
set test {watch data.u.size8twice[1]}
set wpnum ""
gdb_test_multiple $test $test {
-re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
set wpnum $expect_out(1,string)
}
-re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" {
if {[istarget "arm*-*-*"]} {
untested $test
set wpnum 0
}
}
}
if {$wpnum} {
set test "continue"
set got_hit 0
gdb_test_multiple $test $test {
-re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" {
}
-re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" {
set got_hit 1
send_gdb "continue\n"
exp_continue
}
-re " final_return .*\r\n$gdb_prompt $" {
}
}
gdb_assert $got_hit "size8twice write"
}