]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.base/range-stepping.exp
d17596cfc4a1cff919b565cb5330ab8e3146808a
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / range-stepping.exp
1 # Copyright 2013 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 load_lib "range-stepping-support.exp"
17
18 standard_testfile
19 set executable $testfile
20
21 if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug}] } {
22 return -1
23 }
24
25 if ![runto_main] {
26 fail "Can't run to main"
27 return -1
28 }
29
30 # Check whether range stepping is supported by the target.
31
32 proc gdb_range_stepping_enabled { } {
33 global gdb_prompt
34
35 set command "set range-stepping on"
36 set message "probe range-stepping support"
37 gdb_test_multiple $command $message {
38 -re "Range stepping is not supported.*\r\n$gdb_prompt $" {
39 pass $message
40 return 0
41 }
42 -re "^$command\r\n$gdb_prompt $" {
43 pass $message
44 return 1
45 }
46 }
47
48 return 0
49 }
50
51 if ![gdb_range_stepping_enabled] {
52 unsupported "range stepping not supported by the target"
53 return -1
54 }
55
56 # Check that range stepping can step a range of multiple instructions.
57
58 with_test_prefix "multi insns" {
59
60 gdb_breakpoint [gdb_get_line_number "location 1"]
61 gdb_continue_to_breakpoint "location 1"
62
63 set pc_before_stepping ""
64 set test "pc before stepping"
65 gdb_test_multiple "print/x \$pc" $test {
66 -re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" {
67 set pc_before_stepping $expect_out(1,string)
68 pass $test
69 }
70 }
71
72 # When "next" is executed, GDB should send one vCont;s and vCont;r
73 # and receive two stop replies:
74 #
75 # --> vCont;s (step over breakpoint)
76 # <-- T05
77 # --> vCont;rSTART,END (range step)
78 # <-- T05
79 set result [exec_cmd_expect_vCont_count "next" 1 1]
80 if { $result } {
81 # This is the first range-stepping test, and the simplest
82 # one. If it fails, probably the rest of the tests would
83 # fail too, and the huge number of rsp packets in the test
84 # with the time-consuming loop would blow up the gdb.log file.
85 # Skip the rest of the tests.
86 return
87 }
88
89 set pc_after_stepping ""
90 set msg "pc after stepping"
91 gdb_test_multiple "print/x \$pc" $msg {
92 -re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" {
93 set pc_after_stepping $expect_out(1,string)
94 pass $msg
95 }
96 }
97
98 # There should be at least two instructions between
99 # PC_BEFORE_STEPPING and PC_AFTER_STEPPING.
100 gdb_test "disassemble ${pc_before_stepping},${pc_after_stepping}" \
101 "${hex} <main\\+${decimal}>:.*${hex} <main\\+${decimal}>:.*" \
102 "stepped multiple insns"
103 }
104
105 # Check that range stepping can step over a function.
106
107 with_test_prefix "step over func" {
108
109 set line_num [gdb_get_line_number "location 2"]
110 gdb_test "where" "main \\(\\) at .*${srcfile}:${line_num}.*"
111
112 # It's expected to get three stops and two 'vCont;r's. In the C
113 # code, the line of C source produces roughly the following
114 # instructions:
115 #
116 # addr1:
117 # insn1
118 # insn2
119 # ...
120 # call func1
121 # addr2:
122 # ...
123 # insn3
124 # addr3:
125 # insn4
126 #
127 # Something like this will happen:
128 # --> vCont;rADDR1,ADDR3 (range step from ADDR1 to ADDR3)
129 # <-- T05 (target single-stepped to func, which is out of the step range)
130 # --> $Z0,ADDR2 (place step-resume breakpoint at ADDR2)
131 # --> vCont;c (resume)
132 # <-- T05 (target stops at ADDR2)
133 # --> vCont;rADDR1,ADDR3 (continues range stepping)
134 # <-- T05
135 exec_cmd_expect_vCont_count "next" 0 2
136 }
137
138 # Check that breakpoints interrupt range stepping correctly.
139
140 with_test_prefix "breakpoint" {
141 gdb_breakpoint "func1"
142 # Something like this will happen:
143 # --> vCont;rADDR1,ADDR3
144 # <-- T05 (target single-steps to func1, which is out of the step range)
145 # --> $Z0,ADDR2 (step-resume breakpoint at ADDR2)
146 # --> vCont;c (resume)
147 # <-- T05 (target hits the breakpoint at func1)
148 exec_cmd_expect_vCont_count "next" 0 1
149
150 gdb_test "backtrace" "#0 .* func1 .*#1 .* main .*" \
151 "backtrace from func1"
152
153 # A cancelled range step should not confuse the following
154 # execution commands.
155 exec_cmd_expect_vCont_count "stepi" 1 0
156 gdb_test "finish" ".*"
157 gdb_test "next" ".*"
158 delete_breakpoints
159 }
160
161 # Check that range stepping works well even when there's a loop in the
162 # step range.
163
164 with_test_prefix "loop" {
165
166 # GDB should send one vCont;r and receive one stop reply:
167 # --> vCont;rSTART,END (range step)
168 # <-- T05
169 exec_cmd_expect_vCont_count "next" 0 1
170
171 # Confirm the loop completed.
172 gdb_test "print a" " = 15"
173 gdb_test "print e" " = 105"
174 }
175
176 # Check that range stepping works well even when the target's PC was
177 # already within the loop's body.
178
179 with_test_prefix "loop 2" {
180 # Stepi into the loop body. 15 should be large enough to make
181 # sure the program stops within the loop's body.
182 gdb_test "stepi 15" ".*"
183 # GDB should send one vCont;r and receive one stop reply:
184 # --> vCont;rSTART,END (range step)
185 # <-- T05
186 exec_cmd_expect_vCont_count "next" 0 1
187
188 # Confirm the loop completed.
189 gdb_test "print a" " = 15"
190 gdb_test "print e" " = 105"
191 }
192
193 # Check that range stepping works well even when it is interrupted by
194 # ctrl-c.
195
196 with_test_prefix "interrupt" {
197 gdb_test_no_output "set debug remote 1"
198
199 send_gdb "next\n"
200 sleep 1
201 send_gdb "\003"
202
203 # GDB should send one vCont;r and receive one stop reply for
204 # SIGINT:
205 # --> vCont;rSTART,END (range step)
206 # <-- T02 (SIGINT)
207
208 set vcont_r_counter 0
209
210 set test "send ctrl-c to GDB"
211 gdb_test_multiple "" $test {
212 -re "vCont;r\[^\r\n\]*\.\.\." {
213 incr vcont_r_counter
214 exp_continue
215 }
216 -re "Program received signal SIGINT.*$gdb_prompt $" {
217 pass $test
218 }
219 }
220 gdb_test_no_output "set debug remote 0"
221
222 # Check the number of 'vCont;r' packets.
223 if { $vcont_r_counter == 1 } {
224 pass "${test}: 1 vCont;r"
225 } else {
226 fail "${test}: 1 vCont;r"
227 }
228
229 # Break the loop earlier and continue range stepping.
230 gdb_test "set variable c = 0"
231 exec_cmd_expect_vCont_count "next" 0 1
232 }
233
234 # Check that range stepping doesn't break software watchpoints. With
235 # those, GDB needs to be notified of all single-steps, to evaluate
236 # whether the watched value changes at each step.
237 with_test_prefix "software watchpoint" {
238 gdb_test "step" "soft-watch.*" "step into multiple instruction line"
239 # A software watchpoint at PC makes the thread stop before the
240 # whole line range is over (after one single-step, actually).
241 gdb_test "watch \$pc" ".*" "set watchpoint"
242 gdb_test "step" "soft-watch.*" "step still in same line"
243 }
244
245 return 0