2022-01-01 22:56:03 +08:00
|
|
|
# Copyright 2008-2022 Free Software Foundation, Inc.
|
2009-06-28 02:49:20 +08:00
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
# This file is part of the GDB testsuite. It tests reverse stepping.
|
|
|
|
# Lots of code borrowed from "step-test.exp".
|
|
|
|
|
|
|
|
#
|
|
|
|
# Test step and next in reverse
|
|
|
|
#
|
|
|
|
|
2011-11-08 16:23:49 +08:00
|
|
|
if ![supports_reverse] {
|
2009-06-28 02:49:20 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2012-06-27 01:54:59 +08:00
|
|
|
standard_testfile
|
2009-06-28 02:49:20 +08:00
|
|
|
|
2016-12-24 00:52:18 +08:00
|
|
|
if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
|
2009-06-28 02:49:20 +08:00
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2020-09-03 05:57:54 +08:00
|
|
|
runto_main
|
2009-06-28 02:49:20 +08:00
|
|
|
|
2011-11-08 16:23:49 +08:00
|
|
|
if [supports_process_record] {
|
2009-06-28 02:49:20 +08:00
|
|
|
# Activate process record/replay
|
2016-12-02 04:42:48 +08:00
|
|
|
gdb_test_no_output "record" "turn on process record"
|
2009-06-28 02:49:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
# plain vanilla step/next (no count)
|
|
|
|
|
|
|
|
gdb_test "next" ".*NEXT TEST 1.*" "next test 1"
|
|
|
|
gdb_test "step" ".*STEP TEST 1.*" "step test 1"
|
|
|
|
|
|
|
|
# step/next with count
|
|
|
|
|
|
|
|
gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
|
|
|
|
gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
|
|
|
|
|
|
|
|
# step over call
|
|
|
|
|
|
|
|
gdb_test "step" ".*NEXT OVER THIS CALL.*" "step up to call"
|
|
|
|
gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
|
|
|
|
|
|
|
|
# step into call
|
|
|
|
|
|
|
|
gdb_test "step" ".*ARRIVED IN CALLEE.*" "step into call"
|
|
|
|
|
|
|
|
# finish out of call
|
|
|
|
|
|
|
|
set test_message "finish out of fn call"
|
|
|
|
gdb_test_multiple "finish" "$test_message" {
|
|
|
|
-re "FINISH TEST.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
|
|
|
send_gdb "step\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# stepi over flat code (no calls)
|
|
|
|
|
|
|
|
set test_message "simple stepi"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "FINISH TEST.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "NEXTI TEST.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# stepi into a function call
|
|
|
|
|
2021-11-02 16:27:48 +08:00
|
|
|
set alphanum_re "\[a-zA-Z0-9\]"
|
|
|
|
set pic_thunk_re "__$alphanum_re*\\.get_pc_thunk\\.$alphanum_re* \\(\\)"
|
2009-06-28 02:49:20 +08:00
|
|
|
set test_message "stepi into function call"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "NEXTI TEST.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
-re "ENTER CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
2009-07-15 04:17:26 +08:00
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
2021-11-02 16:27:48 +08:00
|
|
|
-re "$pic_thunk_re.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
2009-06-28 02:49:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
# stepi thru return of a function call
|
|
|
|
|
|
|
|
set test_message "stepi back from function call"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "NEXTI TEST.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "ENTER CALLEE.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
###
|
|
|
|
###
|
|
|
|
###
|
|
|
|
|
|
|
|
# Set reverse execution direction
|
|
|
|
|
2010-05-29 02:26:41 +08:00
|
|
|
gdb_test_no_output "set exec-dir reverse" "set reverse execution"
|
2009-06-28 02:49:20 +08:00
|
|
|
|
|
|
|
# stepi backward thru return and into a function
|
|
|
|
|
|
|
|
set stepi_location [gdb_get_line_number "ARRIVED IN CALLEE" "$srcfile"]
|
|
|
|
set test_message "reverse stepi thru function return"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "NEXTI TEST.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (start statement)"
|
|
|
|
}
|
|
|
|
-re "RETURN FROM CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "$hex\[ \t\]*$stepi_location.*ARRIVED IN CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "ENTER CALLEE.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# stepi backward out of a function call
|
|
|
|
|
2009-07-15 04:17:26 +08:00
|
|
|
set stepi_location [gdb_get_line_number "STEPI TEST" "$srcfile"]
|
2009-06-28 02:49:20 +08:00
|
|
|
set test_message "reverse stepi from a function call"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (start statement)"
|
|
|
|
}
|
|
|
|
-re "ENTER CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
2021-11-02 16:27:48 +08:00
|
|
|
-re "$pic_thunk_re.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
2009-07-15 04:17:26 +08:00
|
|
|
-re "${hex} in main .*:$stepi_location.*STEPI TEST.*$gdb_prompt $" {
|
2009-06-28 02:49:20 +08:00
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# stepi backward over flat code (no calls)
|
|
|
|
|
|
|
|
set stepi_location [gdb_get_line_number "FINISH TEST" "$srcfile"]
|
|
|
|
set test_message "simple reverse stepi"
|
|
|
|
gdb_test_multiple "stepi" "$test_message" {
|
|
|
|
-re "STEPI TEST.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (start statement)"
|
|
|
|
}
|
|
|
|
-re "$hex\[ \t\]*$stepi_location.* FINISH TEST.*$gdb_prompt $" {
|
|
|
|
send_gdb "stepi\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
|
|
|
-re "$stepi_location.* FINISH TEST.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "STEP INTO THIS CALL.*$gdb_prompt $" {
|
|
|
|
fail "$test_message (too far)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# step backward into function (thru return)
|
|
|
|
|
Tweak gdb.reverse/step-precsave.exp and gdb.reverse/step-reverse.exp
I see the following test fail in arm-linux with -marm and -fomit-frame-pointer,
step
callee () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:27
27 } /* RETURN FROM CALLEE */
(gdb) step
main () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:58
58 callee(); /* STEP INTO THIS CALL */
(gdb) FAIL: gdb.reverse/step-precsave.exp: reverse step into fn call
As we can see, the "step" has already stepped into the function callee,
but in the last line. The second "step" attempts to step to function
body, but it goes out of callee, which isn't expected.
The program is compiled with -marm and -fomit-frame-pointer, the
function callee is prologue-less, because nothing needs to be saved
on stack,
(gdb) disassemble callee
Dump of assembler code for function callee:
0x00010680 <+0>: movw r3, #2364 ; 0x93c
0x00010684 <+4>: movt r3, #2
0x00010688 <+8>: ldr r3, [r3]
0x0001068c <+12>: add r2, r3, #1
0x00010690 <+16>: movw r3, #2364 ; 0x93c
0x00010694 <+20>: movt r3, #2
0x00010698 <+24>: str r2, [r3]
0x0001069c <+28>: mov r3, #0
0x000106a0 <+32>: mov r0, r3
0x000106a4 <+36>: bx lr
program stops at the 0x106a0 (passed the epilogue) after the first
"step". When second "step" is executed, the stepping range is
[0x10680-0x106a0], which starts from the first instruction of function
callee (because it doesn't have prologue).
infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [LWP 2461] at 0x1069c^M
infrun: prepare_to_wait^M
infrun: target_wait (-1.0.0, status) =^M
infrun: 2461.2461.0 [LWP 2461],^M
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP^M
infrun: TARGET_WAITKIND_STOPPED^M
infrun: stop_pc = 0x10698^M
infrun: stepping inside range [0x10680-0x106a0]
When program goes out of the range, it stops at the caller of callee,
and test fails. IOW, if function callee has prologue, the stepping
range won't start from the first instruction of the function, and
program stops at the prologue and test passes.
IMO, GDB does nothing wrong, but test shouldn't expect the program
stops in callee after the second "step". I decide to fix test rather
than GDB. In this patch, I change to test to do one "step", and check
the program is still in callee, then, do multiple "step" until program
goes out of the callee.
gdb/testsuite:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* gdb.reverse/step-precsave.exp: Do one step and test program
stops in "callee" and do multiple steps until program goes out
of "callee".
* gdb.reverse/step-reverse.exp: Likewise.
2016-04-22 19:14:40 +08:00
|
|
|
gdb_test "step" "(RETURN FROM CALLEE|ARRIVED IN CALLEE).*" \
|
|
|
|
"reverse step into fn call"
|
|
|
|
|
|
|
|
# step backward out of called function (thru call)
|
|
|
|
|
|
|
|
set test_message "reverse step out of called fn"
|
2009-06-28 02:49:20 +08:00
|
|
|
gdb_test_multiple "step" "$test_message" {
|
Tweak gdb.reverse/step-precsave.exp and gdb.reverse/step-reverse.exp
I see the following test fail in arm-linux with -marm and -fomit-frame-pointer,
step
callee () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:27
27 } /* RETURN FROM CALLEE */
(gdb) step
main () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:58
58 callee(); /* STEP INTO THIS CALL */
(gdb) FAIL: gdb.reverse/step-precsave.exp: reverse step into fn call
As we can see, the "step" has already stepped into the function callee,
but in the last line. The second "step" attempts to step to function
body, but it goes out of callee, which isn't expected.
The program is compiled with -marm and -fomit-frame-pointer, the
function callee is prologue-less, because nothing needs to be saved
on stack,
(gdb) disassemble callee
Dump of assembler code for function callee:
0x00010680 <+0>: movw r3, #2364 ; 0x93c
0x00010684 <+4>: movt r3, #2
0x00010688 <+8>: ldr r3, [r3]
0x0001068c <+12>: add r2, r3, #1
0x00010690 <+16>: movw r3, #2364 ; 0x93c
0x00010694 <+20>: movt r3, #2
0x00010698 <+24>: str r2, [r3]
0x0001069c <+28>: mov r3, #0
0x000106a0 <+32>: mov r0, r3
0x000106a4 <+36>: bx lr
program stops at the 0x106a0 (passed the epilogue) after the first
"step". When second "step" is executed, the stepping range is
[0x10680-0x106a0], which starts from the first instruction of function
callee (because it doesn't have prologue).
infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [LWP 2461] at 0x1069c^M
infrun: prepare_to_wait^M
infrun: target_wait (-1.0.0, status) =^M
infrun: 2461.2461.0 [LWP 2461],^M
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP^M
infrun: TARGET_WAITKIND_STOPPED^M
infrun: stop_pc = 0x10698^M
infrun: stepping inside range [0x10680-0x106a0]
When program goes out of the range, it stops at the caller of callee,
and test fails. IOW, if function callee has prologue, the stepping
range won't start from the first instruction of the function, and
program stops at the prologue and test passes.
IMO, GDB does nothing wrong, but test shouldn't expect the program
stops in callee after the second "step". I decide to fix test rather
than GDB. In this patch, I change to test to do one "step", and check
the program is still in callee, then, do multiple "step" until program
goes out of the callee.
gdb/testsuite:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* gdb.reverse/step-precsave.exp: Do one step and test program
stops in "callee" and do multiple steps until program goes out
of "callee".
* gdb.reverse/step-reverse.exp: Likewise.
2016-04-22 19:14:40 +08:00
|
|
|
-re "STEP INTO THIS CALL.*.*$gdb_prompt $" {
|
|
|
|
pass "$test_message"
|
|
|
|
}
|
|
|
|
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
|
2009-06-28 02:49:20 +08:00
|
|
|
send_gdb "step\n"
|
|
|
|
exp_continue
|
|
|
|
}
|
Tweak gdb.reverse/step-precsave.exp and gdb.reverse/step-reverse.exp
I see the following test fail in arm-linux with -marm and -fomit-frame-pointer,
step
callee () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:27
27 } /* RETURN FROM CALLEE */
(gdb) step
main () at /home/yao/SourceCode/gnu/gdb/git/gdb/testsuite/gdb.reverse/step-reverse.c:58
58 callee(); /* STEP INTO THIS CALL */
(gdb) FAIL: gdb.reverse/step-precsave.exp: reverse step into fn call
As we can see, the "step" has already stepped into the function callee,
but in the last line. The second "step" attempts to step to function
body, but it goes out of callee, which isn't expected.
The program is compiled with -marm and -fomit-frame-pointer, the
function callee is prologue-less, because nothing needs to be saved
on stack,
(gdb) disassemble callee
Dump of assembler code for function callee:
0x00010680 <+0>: movw r3, #2364 ; 0x93c
0x00010684 <+4>: movt r3, #2
0x00010688 <+8>: ldr r3, [r3]
0x0001068c <+12>: add r2, r3, #1
0x00010690 <+16>: movw r3, #2364 ; 0x93c
0x00010694 <+20>: movt r3, #2
0x00010698 <+24>: str r2, [r3]
0x0001069c <+28>: mov r3, #0
0x000106a0 <+32>: mov r0, r3
0x000106a4 <+36>: bx lr
program stops at the 0x106a0 (passed the epilogue) after the first
"step". When second "step" is executed, the stepping range is
[0x10680-0x106a0], which starts from the first instruction of function
callee (because it doesn't have prologue).
infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [LWP 2461] at 0x1069c^M
infrun: prepare_to_wait^M
infrun: target_wait (-1.0.0, status) =^M
infrun: 2461.2461.0 [LWP 2461],^M
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP^M
infrun: TARGET_WAITKIND_STOPPED^M
infrun: stop_pc = 0x10698^M
infrun: stepping inside range [0x10680-0x106a0]
When program goes out of the range, it stops at the caller of callee,
and test fails. IOW, if function callee has prologue, the stepping
range won't start from the first instruction of the function, and
program stops at the prologue and test passes.
IMO, GDB does nothing wrong, but test shouldn't expect the program
stops in callee after the second "step". I decide to fix test rather
than GDB. In this patch, I change to test to do one "step", and check
the program is still in callee, then, do multiple "step" until program
goes out of the callee.
gdb/testsuite:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* gdb.reverse/step-precsave.exp: Do one step and test program
stops in "callee" and do multiple steps until program goes out
of "callee".
* gdb.reverse/step-reverse.exp: Likewise.
2016-04-22 19:14:40 +08:00
|
|
|
-re "ENTER CALLEE.*$gdb_prompt $" {
|
|
|
|
send_gdb "step\n"
|
|
|
|
exp_continue
|
2009-06-28 02:49:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# next backward over call
|
|
|
|
|
|
|
|
gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
|
|
|
|
|
|
|
|
# step/next backward with count
|
|
|
|
|
|
|
|
gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"
|
|
|
|
gdb_test "next 2" ".*REVERSE NEXT TEST 1.*" "reverse next test 1"
|
|
|
|
|
|
|
|
# step/next backward without count
|
|
|
|
|
|
|
|
gdb_test "step" ".*STEP TEST 1.*" "reverse step test 2"
|
|
|
|
gdb_test "next" ".*NEXT TEST 1.*" "reverse next test 2"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Finish test by running forward to the end.
|
|
|
|
# FIXME return to this later...
|
2010-05-29 02:26:41 +08:00
|
|
|
# gdb_test_no_output "set exec-dir forward" "set forward execution"
|
2009-06-28 02:49:20 +08:00
|
|
|
# gdb_continue_to_end "step-reverse.exp"
|
|
|
|
|