xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.base/break-idempotent.exp (revision d909946ca08dceb44d7d0f22ec9488679695d976)
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