Imported Upstream version 7.9
[platform/upstream/gdb.git] / gdb / testsuite / gdb.base / range-stepping.exp
1 # Copyright 2013-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 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