xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.reverse/step-reverse.exp (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1# Copyright 2008-2023 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 in reverse
21#
22
23if ![supports_reverse] {
24    return
25}
26
27standard_testfile
28
29if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
30    return -1
31}
32
33runto_main
34set target_remote [gdb_is_target_remote]
35
36if [supports_process_record] {
37    # Activate process record/replay
38    gdb_test_no_output "record" "turn on process record"
39}
40
41# plain vanilla step/next (no count)
42
43gdb_test "next" ".*NEXT TEST 1.*" "next test 1"
44gdb_test "step" ".*STEP TEST 1.*" "step test 1"
45
46# step/next with count
47
48gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
49gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
50
51# Next through a recursive function call.
52gdb_test "next 2" "NEXT OVER THIS CALL.*" "next over recursion"
53
54# step over call
55
56gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
57
58# step into call
59
60gdb_test "step" ".*ARRIVED IN CALLEE.*" "step into call"
61
62# finish out of call
63
64set test_message "finish out of fn call"
65gdb_test_multiple "finish" "$test_message" {
66    -re "FINISH TEST.*$gdb_prompt $" {
67	pass "$test_message"
68    }
69    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
70	send_gdb "step\n"
71	exp_continue
72    }
73}
74
75# stepi over flat code (no calls)
76
77set test_message "simple stepi"
78gdb_test_multiple "stepi" "$test_message" {
79    -re "STEPI TEST.*$gdb_prompt $" {
80	pass "$test_message"
81    }
82    -re "FINISH TEST.*$gdb_prompt $" {
83	send_gdb "stepi\n"
84	exp_continue
85    }
86    -re "NEXTI TEST.*$gdb_prompt $" {
87	fail "$test_message (too far)"
88    }
89}
90
91# stepi into a function call
92
93set alphanum_re "\[a-zA-Z0-9\]"
94set pic_thunk_re  "__$alphanum_re*\\.get_pc_thunk\\.$alphanum_re* \\(\\)"
95set test_message "stepi into function call"
96gdb_test_multiple "stepi" "$test_message" {
97    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
98	pass "$test_message"
99    }
100    -re "NEXTI TEST.*$gdb_prompt $" {
101	fail "$test_message (too far)"
102    }
103    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
104	fail "$test_message (too far)"
105    }
106    -re "ENTER CALLEE.*$gdb_prompt $" {
107	send_gdb "stepi\n"
108	exp_continue
109    }
110    -re "STEPI TEST.*$gdb_prompt $" {
111	send_gdb "stepi\n"
112	exp_continue
113    }
114    -re "$pic_thunk_re.*$gdb_prompt $" {
115	send_gdb "stepi\n"
116	exp_continue
117    }
118}
119
120# stepi thru return of a function call
121
122set test_message "stepi back from function call"
123gdb_test_multiple "stepi" "$test_message" {
124    -re -wrap "NEXTI TEST.*" {
125	pass "$test_message"
126    }
127    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
128	send_gdb "stepi\n"
129	exp_continue
130    }
131    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
132	send_gdb "stepi\n"
133	exp_continue
134    }
135    -re "STEPI TEST.*$gdb_prompt $" {
136	send_gdb "stepi\n"
137	exp_continue
138    }
139    -re "ENTER CALLEE.*$gdb_prompt $" {
140	fail "$test_message (too far)"
141    }
142}
143
144###
145###
146###
147
148# Set reverse execution direction
149gdb_test_no_output "set exec-dir reverse" "set reverse execution"
150
151# stepi backward thru return and into a function
152
153set stepi_location  [gdb_get_line_number "ARRIVED IN CALLEE" "$srcfile"]
154set test_message "reverse stepi thru function return"
155gdb_test_multiple "stepi" "$test_message" {
156    -re "NEXTI TEST.*$gdb_prompt $" {
157	fail "$test_message (start statement)"
158    }
159    -re "RETURN FROM CALLEE.*$gdb_prompt $" {
160	send_gdb "stepi\n"
161	exp_continue
162    }
163    -re "$hex\[ \t\]*$stepi_location.*ARRIVED IN CALLEE.*$gdb_prompt $" {
164	send_gdb "stepi\n"
165	exp_continue
166    }
167    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
168	pass "$test_message"
169    }
170    -re "ENTER CALLEE.*$gdb_prompt $" {
171	fail "$test_message (too far)"
172    }
173    -re "STEPI TEST.*$gdb_prompt $" {
174	fail "$test_message (too far)"
175    }
176}
177
178# stepi backward out of a function call
179
180set stepi_location  [gdb_get_line_number "STEPI TEST" "$srcfile"]
181set test_message "reverse stepi from a function call"
182gdb_test_multiple "stepi" "$test_message" {
183    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
184	fail "$test_message (start statement)"
185    }
186    -re "ENTER CALLEE.*$gdb_prompt $" {
187	send_gdb "stepi\n"
188	exp_continue
189    }
190    -re "$pic_thunk_re.*$gdb_prompt $" {
191	send_gdb "stepi\n"
192	exp_continue
193    }
194    -re "${hex} in main .*:$stepi_location.*STEPI TEST.*$gdb_prompt $" {
195	send_gdb "stepi\n"
196	exp_continue
197    }
198    -re "STEPI TEST.*$gdb_prompt $" {
199	pass "$test_message"
200    }
201    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
202	fail "$test_message (too far)"
203    }
204}
205
206# stepi backward over flat code (no calls)
207
208set stepi_location  [gdb_get_line_number "FINISH TEST" "$srcfile"]
209set test_message "simple reverse stepi"
210gdb_test_multiple "stepi" "$test_message" {
211    -re "STEPI TEST.*$gdb_prompt $" {
212	fail "$test_message (start statement)"
213    }
214    -re "$hex\[ \t\]*$stepi_location.* FINISH TEST.*$gdb_prompt $" {
215	send_gdb "stepi\n"
216	exp_continue
217    }
218    -re "$stepi_location.* FINISH TEST.*$gdb_prompt $" {
219	pass "$test_message"
220    }
221    -re "STEP INTO THIS CALL.*$gdb_prompt $" {
222	fail "$test_message (too far)"
223    }
224}
225
226# step backward into function (thru return)
227
228gdb_test "step" "(RETURN FROM CALLEE|ARRIVED IN CALLEE).*" \
229    "reverse step into fn call"
230
231# step backward out of called function (thru call)
232
233set test_message "reverse step out of called fn"
234gdb_test_multiple "step" "$test_message" {
235    -re "STEP INTO THIS CALL.*.*$gdb_prompt $" {
236	pass "$test_message"
237    }
238    -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
239	send_gdb "step\n"
240	exp_continue
241    }
242    -re "ENTER CALLEE.*$gdb_prompt $" {
243	send_gdb "step\n"
244	exp_continue
245    }
246}
247
248# Next backward over call.
249
250gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
251
252set step_out 0
253gdb_test_multiple "next" "reverse next over recursion" {
254    -re -wrap ".*NEXT OVER THIS RECURSION.*" {
255	pass "$gdb_test_name"
256    }
257    -re -wrap ".*RECURSIVE CALL.*" {
258	fail "$gdb_test_name"
259	set step_out 1
260    }
261}
262if { "$step_out" == 1 } {
263    gdb_test_multiple "next" "stepping out of recursion" {
264	-re -wrap "NEXT OVER THIS RECURSION.*" {
265	    set step_out 0
266	}
267	-re -wrap ".*" {
268	    send_gdb "next\n"
269	    exp_continue
270	}
271    }
272}
273
274# Step forward over recursion again so we can test stepping over calls
275# inside the recursion itself.
276gdb_test_no_output "set exec-dir forward" "forward again to test recursion"
277if {$target_remote} {
278    # gdb doesn't record the change of return pointer for remote targets,
279    # so we can't next forward over functions.
280    setup_kfail gdb/29745 *-*-*
281}
282gdb_test "next" "NEXT OVER THIS CALL.*" "reverse next over recursion again"
283gdb_test_no_output "set exec-dir reverse" "reverse again to test recursion"
284
285if {$target_remote} {
286    # Because of the above mentioned KFAIL, the inferior is now out of sync
287    setup_kfail gdb/29745 *-*-*
288}
289gdb_test "step" ".*EXIT RECURSIVE FUNCTION.*" "enter recursive function"
290set seen_recursive_call 0
291if {$target_remote} {
292    # Because of the above mentioned KFAIL, the inferior is now out of sync
293    # The fail state below will resync the inferior.
294    setup_kfail gdb/29745 *-*-*
295}
296gdb_test_multiple "next" "step over recursion inside the recursion" {
297    -re -wrap ".*RECURSIVE CALL.*" {
298	incr seen_recursive_call
299	send_gdb "next\n"
300	exp_continue
301    }
302    -re -wrap ".*NEXT OVER THIS RECURSION.*" {
303	gdb_assert {"$seen_recursive_call" == 1} \
304	    "step over recursion inside the recursion"
305    }
306    -re -wrap ".*" {
307	send_gdb "next\n"
308	exp_continue
309    }
310}
311
312# step/next backward with count
313
314gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"
315gdb_test "next 2" ".*REVERSE NEXT TEST 1.*" "reverse next test 1"
316
317# step/next backward without count
318
319gdb_test "step" ".*STEP TEST 1.*" "reverse step test 2"
320gdb_test "next" ".*NEXT TEST 1.*" "reverse next test 2"
321
322
323
324# Finish test by running forward to the end.
325# FIXME return to this later...
326# gdb_test_no_output "set exec-dir forward" "set forward execution"
327# gdb_continue_to_end "step-reverse.exp"
328
329