# step over call
-gdb_test "step" ".*NEXT OVER THIS CALL.*" "step up to call"
+gdb_test "step" ".*NEXT OVER THIS RECURSION.*" "step up to call"
+gdb_test "next" ".*NEXT OVER THIS CALL.*" "skip recursive call"
gdb_test "next" ".*STEP INTO THIS CALL.*" "next over call"
# step into call
}
}
-# next backward over call
+# Next backward over calls.
gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
+gdb_test "next" ".*NEXT OVER THIS RECURSION.*" "reverse next over recursive call"
# step/next backward with count
return myglob++; /* ARRIVED IN CALLEE */
} /* RETURN FROM CALLEE */
+/* We need to make this function take more than a single instruction
+ to run, otherwise it could hide PR gdb/16678, as reverse execution can
+ step over a single-instruction function. */
+int
+recursive_callee (int val)
+{
+ if (val == 0)
+ return 0;
+ val /= 2;
+ if (val > 1)
+ val++;
+ return recursive_callee (val); /* RECURSIVE CALL */
+} /* EXIT RECURSIVE FUNCTION */
+
/* A structure which, we hope, will need to be passed using memcpy. */
struct rhomboidal {
int rather_large[100];
y = y + 4;
z = z + 5; /* STEP TEST 2 */
+ /* Test that next goes over recursive calls too */
+ recursive_callee (32); /* NEXT OVER THIS RECURSION */
+
/* Test that "next" goes over a call */
callee(); /* NEXT OVER THIS CALL */
/* Test "stepi" */
a[5] = a[3] - a[4]; /* FINISH TEST */
callee(); /* STEPI TEST */
-
+
/* Test "nexti" */
callee(); /* NEXTI TEST */
gdb_test "next 2" ".*NEXT TEST 2.*" "next test 2"
gdb_test "step 3" ".*STEP TEST 2.*" "step test 2"
+# Next through a recursive function call.
+gdb_test "next 2" "NEXT OVER THIS CALL.*" "next over recursion"
+
# 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
set test_message "stepi back from function call"
gdb_test_multiple "stepi" "$test_message" {
- -re "NEXTI TEST.*$gdb_prompt $" {
+ -re -wrap "NEXTI TEST.*" {
pass "$test_message"
}
-re "ARRIVED IN CALLEE.*$gdb_prompt $" {
###
# Set reverse execution direction
-
gdb_test_no_output "set exec-dir reverse" "set reverse execution"
# stepi backward thru return and into a function
}
}
-# next backward over call
+# Next backward over call.
gdb_test "next" ".*NEXT OVER THIS CALL.*" "reverse next over call"
+set step_out 0
+gdb_test_multiple "next" "reverse next over recursion" {
+ -re -wrap ".*NEXT OVER THIS RECURSION.*" {
+ pass "$gdb_test_name"
+ }
+ -re -wrap ".*RECURSIVE CALL.*" {
+ fail "$gdb_test_name"
+ set step_out 1
+ }
+}
+if { "$step_out" == 1 } {
+ gdb_test_multiple "next" "stepping out of recursion" {
+ -re -wrap "NEXT OVER THIS RECURSION.*" {
+ set step_out 0
+ }
+ -re -wrap ".*" {
+ send_gdb "next\n"
+ exp_continue
+ }
+ }
+}
+
+# Step forward over recursion again so we can test stepping over calls
+# inside the recursion itself.
+gdb_test_no_output "set exec-dir forward" "forward again to test recursion"
+gdb_test "next" "NEXT OVER THIS CALL.*" "reverse next over recursion again"
+gdb_test_no_output "set exec-dir reverse" "reverse again to test recursion"
+
+gdb_test "step" ".*EXIT RECURSIVE FUNCTION.*" "enter recursive function"
+set seen_recursive_call 0
+gdb_test_multiple "next" "step over recursion inside the recursion" {
+ -re -wrap ".*RECURSIVE CALL.*" {
+ incr seen_recursive_call
+ send_gdb "next\n"
+ exp_continue
+ }
+ -re -wrap ".*NEXT OVER THIS RECURSION.*" {
+ gdb_assert {"$seen_recursive_call" == 1} \
+ "step over recursion inside the recursion"
+ }
+ -re -wrap ".*" {
+ send_gdb "next\n"
+ exp_continue
+ }
+}
+
# step/next backward with count
gdb_test "step 3" ".*REVERSE STEP TEST 1.*" "reverse step test 1"