diff --git a/gdb/infrun.c b/gdb/infrun.c index 9a9f42fc903..fcc4d80fc73 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -7130,7 +7130,7 @@ process_event_stop_test (struct execution_control_state *ecs) sr_sal.pc = ecs->stop_func_start; sr_sal.pspace = get_frame_program_space (frame); insert_step_resume_breakpoint_at_sal (gdbarch, - sr_sal, null_frame_id); + sr_sal, get_stack_frame_id (frame)); } } else diff --git a/gdb/testsuite/gdb.reverse/step-precsave.exp b/gdb/testsuite/gdb.reverse/step-precsave.exp index 0836ed2629f..3279b6ce879 100644 --- a/gdb/testsuite/gdb.reverse/step-precsave.exp +++ b/gdb/testsuite/gdb.reverse/step-precsave.exp @@ -86,7 +86,8 @@ 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 "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 @@ -280,9 +281,10 @@ gdb_test_multiple "step" "$test_message" { } } -# 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 diff --git a/gdb/testsuite/gdb.reverse/step-reverse.c b/gdb/testsuite/gdb.reverse/step-reverse.c index aea2a98541d..809c7d16dc9 100644 --- a/gdb/testsuite/gdb.reverse/step-reverse.c +++ b/gdb/testsuite/gdb.reverse/step-reverse.c @@ -26,6 +26,20 @@ int callee() { /* ENTER CALLEE */ 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]; @@ -51,6 +65,9 @@ int main () { 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 */ @@ -60,7 +77,7 @@ int main () { /* Test "stepi" */ a[5] = a[3] - a[4]; /* FINISH TEST */ callee(); /* STEPI TEST */ - + /* Test "nexti" */ callee(); /* NEXTI TEST */ diff --git a/gdb/testsuite/gdb.reverse/step-reverse.exp b/gdb/testsuite/gdb.reverse/step-reverse.exp index 997b62604d5..c28e1f6db4f 100644 --- a/gdb/testsuite/gdb.reverse/step-reverse.exp +++ b/gdb/testsuite/gdb.reverse/step-reverse.exp @@ -47,9 +47,11 @@ gdb_test "step" ".*STEP TEST 1.*" "step test 1" 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 @@ -118,7 +120,7 @@ gdb_test_multiple "stepi" "$test_message" { 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 $" { @@ -143,7 +145,6 @@ gdb_test_multiple "stepi" "$test_message" { ### # Set reverse execution direction - gdb_test_no_output "set exec-dir reverse" "set reverse execution" # stepi backward thru return and into a function @@ -243,10 +244,56 @@ gdb_test_multiple "step" "$test_message" { } } -# 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"