1 # This testcase is part of GDB
, the GNU debugger.
3 # Copyright
2014-2022 Free Software Foundation
, Inc.
5 # This
program is free software
; you can redistribute it and
/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation
; either version
3 of the License
, or
8 #
(at your option
) any later version.
10 # This
program is distributed in the hope that it will be useful
,
11 # but WITHOUT
ANY WARRANTY
; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License
for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this
program.
If not
, see
<http
://www.gnu.org
/licenses
/>.
18 # This file is part of the gdb testsuite.
20 # Test that GDB presents a hardware watchpoint stop at the first
21 # instruction right after the instruction that changes memory.
23 # Some targets trigger a hardware watchpoint after the instruction
24 # that wrote memory executes
, thus with the memory already changed and
25 # the PC pointing to the instruction after the instruction that wrote
26 # to memory. These targets are said to have
"continuable"
27 # watchpoints
, referring to the fact that to make progress after the
28 # watchpoint triggers
, GDB just needs to
continue the target.
30 # Other targets trigger a hardware watchpoint at the instruction which
31 # has attempted to write to the piece of memory under control of the
32 # watchpoint
, with the instruction actually not executed yet. To be
33 # able to check whether the watched value changed
, GDB needs to
34 # complete the memory write
, single
-stepping the target once. These
35 # targets are said to have
"non-continuable" watchpoints.
37 # This test makes sure that GDB knows which kind of watchpoint the
38 # target has
, using this sequence of steps
:
42 #
2 - set a software watchpoint
44 #
3 - continue until watchpoint triggers
46 #
4 - the PC now points to the instruction right after the instruction
47 # that actually caused the memory write. So this is the address a
48 # hardware watchpoint should present the stop to the user too.
49 # Store the PC address.
51 #
5 - replace the software watchpoint by a hardware watchpoint
53 #
6 - continue until hardware watchpoint triggers
55 #
7 - the PC must point to the same address the software watchpoint
58 #
If the target has continuable watchpoints
, but GDB thinks it has
59 # non
-continuable watchpoints
, GDB will stop the inferior two
60 # instructions after the watched value change
, rather than at the next
63 #
If the target has non
-continuable watchpoints
, while GDB thinks it
64 # has continuable watchpoints
, GDB will see a watchpoint trigger
,
65 # notice no value changed
, and immediatly
continue the target. Now
,
66 # either the target manages to step
-over the watchpoint transparently
,
67 # and GDB thus fails to present to value change to the user
, or
, the
68 # watchpoint will keep re
-triggering
, with the
program never making
73 # No use testing this
if we can
't use hardware watchpoints.
74 if {[target_info exists gdb,no_hardware_watchpoints]} {
78 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
82 if { ![runto_main] } then {
86 # Get the current PC. TEST is used as test prefix.
92 gdb_test_multiple "p /x \$pc" "$test" {
93 -re " = ($hex).*$gdb_prompt $" {
94 set addr $expect_out(1,string)
102 # So we get an immediate warning/error if the target doesn't support a
103 # given watchpoint type.
104 gdb_test_no_output
"set breakpoint always-inserted on"
106 set hw_watchpoints_supported
0
108 set test
"set probe hw watchpoint"
109 gdb_test_multiple
"watch global" $test {
110 -re
"You may have requested too many.*$gdb_prompt $" {
113 -re
"Target does not support.*$gdb_prompt $" {
116 -re
"$gdb_prompt $" {
118 set hw_watchpoints_supported
1
122 if {!$hw_watchpoints_supported
} {
123 unsupported
"no hw watchpoints support"
129 proc test
{always_inserted
} {
130 global srcfile binfile
132 with_test_prefix
"always-inserted $always_inserted" {
134 clean_restart $binfile
136 if { ![runto_main
] } then {
140 # Force use of software watchpoints.
141 gdb_test_no_output
"set can-use-hw-watchpoints 0"
143 gdb_test
"watch global" \
144 "Watchpoint .*: global" \
145 "set software watchpoint on global variable"
147 gdb_test
"continue" \
148 "Watchpoint .*: global.*Old value = 0.*New value = 1.*set_global \\(val=1\\).*$srcfile.*" \
149 "software watchpoint triggers"
151 set sw_watch_pc
[get_pc
"get sw watchpoint PC"]
155 # Allow hardware watchpoints again.
156 gdb_test_no_output
"set can-use-hw-watchpoints 1"
158 gdb_test
"watch global" \
159 "Hardware watchpoint .*: global" \
160 "set hardware watchpoint on global variable"
162 gdb_test
"continue" \
163 "Hardware watchpoint .*: global.*Old value = 1.*New value = 2.*set_global \\(val=2\\).*$srcfile.*" \
164 "hardware watchpoint triggers"
166 set hw_watch_pc
[get_pc
"get hw watchpoint PC"]
168 gdb_assert
{$sw_watch_pc
== $hw_watch_pc
} "hw watchpoint stops at right instruction"
172 foreach always_inserted
{"off" "on" } {
173 test $always_inserted