1 # Copyright 2008-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
16 # This file is part of the GDB testsuite. It tests reverse stepping.
17 # Lots of code borrowed from "step-test.exp".
20 # Test step and next with a reloaded process record file.
23 # This test suitable only for process record-replay
24 require supports_process_record
26 standard_testfile step-reverse.c
27 set precsave [standard_output_file step.precsave]
29 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
35 # Activate process record/replay
36 gdb_test_no_output "record" "turn on process record"
38 set end_of_main [gdb_get_line_number "end of main" ]
39 gdb_test "break $end_of_main" \
40 "Breakpoint $decimal at .*$srcfile, line $end_of_main\." \
41 "breakpoint at end of main"
43 # This can take awhile.
44 with_timeout_factor 20 {
45 gdb_test_multiple "continue" "run to end of main" {
46 -re -wrap "Breakpoint .* end of main .*" {
49 -re -wrap "Process record does not support VEX instruction.*" {
50 kfail "record/17346" $gdb_test_name
52 -re -wrap "Process record does not support instruction 0xfae64 at.*" {
53 kfail "record/25038" $gdb_test_name
55 -re -wrap "Process record does not support instruction 0x62 at.*" {
56 kfail "record/30807" $gdb_test_name
61 # So can this, against gdbserver, for example.
63 with_timeout_factor 10 {
64 gdb_test "record save $precsave" \
65 "Saved core file $precsave with execution log\." \
66 "save process recfile"
69 gdb_test "kill" "" "kill process, prepare to debug log file" \
70 "Kill the program being debugged\\? \\(y or n\\) " "y"
72 clean_restart ${binfile}
74 gdb_test "record restore $precsave" \
75 "Restored records from core file .*" \
78 # plain vanilla step/next (no count)
80 gdb_test "next" ".*NEXT TEST 1.*" "next test 1"
81 gdb_test "step" ".*STEP TEST 1.*" "step test 1"
83 # step/next with count
85 gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
86 gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
90 gdb_test "step" ".*NEXT OVER THIS RECURSION.*" "step up to call"
91 gdb_test "next" ".*NEXT OVER THIS CALL.*" "skip recursive call"
92 gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
96 gdb_test "step" ".*ARRIVED IN CALLEE.*" "step into call"
100 set test_message "finish out of fn call"
101 gdb_test_multiple "finish" "$test_message" {
102 -re "FINISH TEST.*$gdb_prompt $" {
105 -re "STEP INTO THIS CALL.*$gdb_prompt $" {
111 # stepi over flat code (no calls)
113 set test_message "simple stepi"
114 gdb_test_multiple "stepi" "$test_message" {
115 -re "STEPI TEST.*$gdb_prompt $" {
118 -re "FINISH TEST.*$gdb_prompt $" {
122 -re "NEXTI TEST.*$gdb_prompt $" {
123 fail "$test_message (too far)"
127 # stepi into a function call
129 set alphanum_re "\[a-zA-Z0-9\]"
130 set pic_thunk_re "__$alphanum_re*\\.get_pc_thunk\\.$alphanum_re* \\(\\)"
131 set test_message "stepi into function call"
132 gdb_test_multiple "stepi" "$test_message" {
133 -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
136 -re "NEXTI TEST.*$gdb_prompt $" {
137 fail "$test_message (too far)"
139 -re "RETURN FROM CALLEE.*$gdb_prompt $" {
140 fail "$test_message (too far)"
142 -re "ENTER CALLEE.*$gdb_prompt $" {
146 -re "STEPI TEST.*$gdb_prompt $" {
150 -re "$pic_thunk_re.*$gdb_prompt $" {
156 # stepi through return of a function call
158 set test_message "stepi back from function call"
159 gdb_test_multiple "stepi" "$test_message" {
160 -re "NEXTI TEST.*$gdb_prompt $" {
163 -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
167 -re "RETURN FROM CALLEE.*$gdb_prompt $" {
171 -re "STEPI TEST.*$gdb_prompt $" {
175 -re "ENTER CALLEE.*$gdb_prompt $" {
176 fail "$test_message (too far)"
184 # Set reverse execution direction
186 gdb_test_no_output "set exec-dir reverse" "set reverse execution"
188 # stepi backward through return and into a function
190 set stepi_location [gdb_get_line_number "ARRIVED IN CALLEE" "$srcfile"]
191 set test_message "reverse stepi through function return"
192 gdb_test_multiple "stepi" "$test_message" {
193 -re "NEXTI TEST.*$gdb_prompt $" {
194 fail "$test_message (start statement)"
196 -re "RETURN FROM CALLEE.*$gdb_prompt $" {
200 -re "$hex\[ \t\]*$stepi_location.*ARRIVED IN CALLEE.*$gdb_prompt $" {
204 -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
207 -re "ENTER CALLEE.*$gdb_prompt $" {
208 fail "$test_message (too far)"
210 -re "STEPI TEST.*$gdb_prompt $" {
211 fail "$test_message (too far)"
215 # stepi backward out of a function call
217 set start_pc [get_hexadecimal_valueof "\$pc" 0 "getting PC at start of stepi backwards"]
219 set stepi_location [gdb_get_line_number "STEPI TEST" "$srcfile"]
220 set test_message "reverse stepi from a function call"
221 gdb_test_multiple "stepi" "$test_message" {
222 -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
224 if { [get_hexadecimal_valueof "\$pc" 0 "getting PC after $step_count steps"] == $start_pc } {
225 fail "$test_message (start statement)"
231 -re "ENTER CALLEE.*$gdb_prompt $" {
235 -re "$pic_thunk_re.*$gdb_prompt $" {
239 -re "${hex} in main .*:$stepi_location.*STEPI TEST.*$gdb_prompt $" {
243 -re "STEPI TEST.*$gdb_prompt $" {
246 -re "STEP INTO THIS CALL.*$gdb_prompt $" {
247 fail "$test_message (too far)"
251 # stepi backward over flat code (no calls)
253 set stepi_location [gdb_get_line_number "FINISH TEST" "$srcfile"]
254 set test_message "simple reverse stepi"
255 gdb_test_multiple "stepi" "$test_message" {
256 -re "STEPI TEST.*$gdb_prompt $" {
257 fail "$test_message (start statement)"
259 -re "$hex\[ \t\]*$stepi_location.* FINISH TEST.*$gdb_prompt $" {
263 -re "$stepi_location.* FINISH TEST.*$gdb_prompt $" {
266 -re "STEP INTO THIS CALL.*$gdb_prompt $" {
267 fail "$test_message (too far)"
271 # step backward into function (through return)
273 gdb_test "step" "(RETURN FROM CALLEE|ARRIVED IN CALLEE).*" \
274 "reverse step into fn call"
276 # step backward out of called function (through call)
278 set test_message "reverse step out of called fn"
279 gdb_test_multiple "step" "$test_message" {
280 -re "STEP INTO THIS CALL.*.*$gdb_prompt $" {
283 -re "ARRIVED IN CALLEE.*$gdb_prompt $" {
287 -re "ENTER CALLEE.*$gdb_prompt $" {
293 # Next backward over calls.
295 gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
296 gdb_test "next" ".*NEXT OVER THIS RECURSION.*" "reverse next over recursive call"
298 # step/next backward with count
300 gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"
301 gdb_test "next 2" ".*REVERSE NEXT TEST 1.*" "reverse next test 1"
303 # step/next backward without count
305 gdb_test "step" ".*STEP TEST 1.*" "reverse step test 2"
306 gdb_test "next" ".*NEXT TEST 1.*" "reverse next test 2"
310 # Finish test by running forward to the end.
311 # FIXME return to this later...
312 # gdb_test_no_output "set exec-dir forward" "set forward execution"
313 # gdb_continue_to_end "step-reverse.exp"