1# Copyright 2008-2020 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# This file is part of the GDB testsuite.  It tests reverse stepping.
17# Lots of code borrowed from "step-test.exp".
18
19#
20# Test step and next with a reloaded process record file.
21#
22
23# This test suitable only for process record-replay
24if ![supports_process_record] {
25    return
26}
27
28standard_testfile step-reverse.c
29set precsave [standard_output_file step.precsave]
30
31if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
32    return -1
33}
34
35runto main
36
37if [supports_process_record] {
38    # Activate process record/replay
39    gdb_test_no_output "record" "turn on process record"
40}
41
42set end_of_main [gdb_get_line_number "end of main" ]
43gdb_test "break $end_of_main" \
44    "Breakpoint $decimal at .*$srcfile, line $end_of_main\." \
45    "breakpoint at end of main"
46
47# This can take awhile.
48with_timeout_factor 20 {
49    gdb_test_multiple "continue" "run to end of main" {
50	-re -wrap "Breakpoint .* end of main .*" {
51	    pass $gdb_test_name
52	}
53	-re -wrap "Process record does not support instruction 0xc5 at.*" {
54	    kfail "record/23188" $gdb_test_name
55	}
56	-re -wrap "Process record does not support instruction 0xfae64 at.*" {
57	    kfail "record/25038" $gdb_test_name
58	}
59    }
60}
61
62# So can this, against gdbserver, for example.
63
64with_timeout_factor 10 {
65    gdb_test "record save $precsave" \
66	"Saved core file $precsave with execution log\."  \
67	"save process recfile"
68}
69
70gdb_test "kill" "" "kill process, prepare to debug log file" \
71    "Kill the program being debugged\\? \\(y or n\\) " "y"
72
73gdb_test "record restore $precsave" \
74    "Restored records from core file .*" \
75    "reload core file"
76
77# plain vanilla step/next (no count)
78
79gdb_test "next" ".*NEXT TEST 1.*" "next test 1"
80gdb_test "step" ".*STEP TEST 1.*" "step test 1"
81
82# step/next with count
83
84gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
85gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
86
87# step over call
88
89gdb_test "step" ".*NEXT OVER THIS CALL.*" "step up to call"
90gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
91
92# step into call
93
94gdb_test "step" ".*ARRIVED IN CALLEE.*" "step into call"
95
96# finish out of call
97
98set test_message "finish out of fn call"
99gdb_test_multiple "finish" "$test_message" {
100    -re "FINISH TEST.*$gdb_prompt $" {
101	pass "$test_message"
102    }
103    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
104	send_gdb "step\n"
105	exp_continue
106    }
107}
108
109# stepi over flat code (no calls)
110
111set test_message "simple stepi"
112gdb_test_multiple "stepi" "$test_message" {
113    -re "STEPI TEST.*$gdb_prompt $" {
114	pass "$test_message"
115    }
116    -re "FINISH TEST.*$gdb_prompt $" {
117	send_gdb "stepi\n"
118	exp_continue
119    }
120    -re "NEXTI TEST.*$gdb_prompt $" {
121	fail "$test_message (too far)"
122    }
123}
124
125# stepi into a function call
126
127set test_message "stepi into function call"
128gdb_test_multiple "stepi" "$test_message" {
129    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
130	pass "$test_message"
131    }
132    -re "NEXTI TEST.*$gdb_prompt $" {
133	fail "$test_message (too far)"
134    }
135    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
136	fail "$test_message (too far)"
137    }
138    -re "ENTER CALLEE.*$gdb_prompt $" {
139	send_gdb "stepi\n"
140	exp_continue
141    }
142    -re "STEPI TEST.*$gdb_prompt $" {
143	send_gdb "stepi\n"
144	exp_continue
145    }
146}
147
148# stepi thru return of a function call
149
150set test_message "stepi back from function call"
151gdb_test_multiple "stepi" "$test_message" {
152    -re "NEXTI TEST.*$gdb_prompt $" {
153	pass "$test_message"
154    }
155    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
156	send_gdb "stepi\n"
157	exp_continue
158    }
159    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
160	send_gdb "stepi\n"
161	exp_continue
162    }
163    -re "STEPI TEST.*$gdb_prompt $" {
164	send_gdb "stepi\n"
165	exp_continue
166    }
167    -re "ENTER CALLEE.*$gdb_prompt $" {
168	fail "$test_message (too far)"
169    }
170}
171
172###
173###
174###
175
176# Set reverse execution direction
177
178gdb_test_no_output "set exec-dir reverse" "set reverse execution"
179
180# stepi backward thru return and into a function
181
182set stepi_location  [gdb_get_line_number "ARRIVED IN CALLEE" "$srcfile"]
183set test_message "reverse stepi thru function return"
184gdb_test_multiple "stepi" "$test_message" {
185    -re "NEXTI TEST.*$gdb_prompt $" {
186	fail "$test_message (start statement)"
187    }
188    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
189	send_gdb "stepi\n"
190	exp_continue
191    }
192    -re "$hex\[ \t\]*$stepi_location.*ARRIVED IN CALLEE.*$gdb_prompt $" {
193	send_gdb "stepi\n"
194	exp_continue
195    }
196    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
197	pass "$test_message"
198    }
199    -re "ENTER CALLEE.*$gdb_prompt $" {
200	fail "$test_message (too far)"
201    }
202    -re "STEPI TEST.*$gdb_prompt $" {
203	fail "$test_message (too far)"
204    }
205}
206
207# stepi backward out of a function call
208
209set stepi_location  [gdb_get_line_number "STEPI TEST" "$srcfile"]
210set test_message "reverse stepi from a function call"
211gdb_test_multiple "stepi" "$test_message" {
212    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
213	fail "$test_message (start statement)"
214    }
215    -re "ENTER CALLEE.*$gdb_prompt $" {
216	send_gdb "stepi\n"
217	exp_continue
218    }
219    -re "${hex} in main .*:$stepi_location.*STEPI TEST.*$gdb_prompt $" {
220	send_gdb "stepi\n"
221	exp_continue
222    }
223    -re "STEPI TEST.*$gdb_prompt $" {
224	pass "$test_message"
225    }
226    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
227	fail "$test_message (too far)"
228    }
229}
230
231# stepi backward over flat code (no calls)
232
233set stepi_location  [gdb_get_line_number "FINISH TEST" "$srcfile"]
234set test_message "simple reverse stepi"
235gdb_test_multiple "stepi" "$test_message" {
236    -re "STEPI TEST.*$gdb_prompt $" {
237	fail "$test_message (start statement)"
238    }
239    -re "$hex\[ \t\]*$stepi_location.* FINISH TEST.*$gdb_prompt $" {
240	send_gdb "stepi\n"
241	exp_continue
242    }
243    -re "$stepi_location.* FINISH TEST.*$gdb_prompt $" {
244	pass "$test_message"
245    }
246    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
247	fail "$test_message (too far)"
248    }
249}
250
251# step backward into function (thru return)
252
253gdb_test "step" "(RETURN FROM CALLEE|ARRIVED IN CALLEE).*" \
254    "reverse step into fn call"
255
256# step backward out of called function (thru call)
257
258set test_message "reverse step out of called fn"
259gdb_test_multiple "step" "$test_message" {
260    -re "STEP INTO THIS CALL.*.*$gdb_prompt $" {
261	pass "$test_message"
262    }
263    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
264	send_gdb "step\n"
265	exp_continue
266    }
267    -re "ENTER CALLEE.*$gdb_prompt $" {
268	send_gdb "step\n"
269	exp_continue
270    }
271}
272
273# next backward over call
274
275gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
276
277# step/next backward with count
278
279gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"
280gdb_test "next 2" ".*REVERSE NEXT TEST 1.*" "reverse next test 1"
281
282# step/next backward without count
283
284gdb_test "step" ".*STEP TEST 1.*" "reverse step test 2"
285gdb_test "next" ".*NEXT TEST 1.*" "reverse next test 2"
286
287
288
289# Finish test by running forward to the end.
290# FIXME return to this later...
291# gdb_test_no_output "set exec-dir forward" "set forward execution"
292# gdb_continue_to_end "step-reverse.exp"
293
294