From bf2813aff8f2988ad3d53e819a0415abf295c91f Mon Sep 17 00:00:00 2001 From: Guinevere Larsen Date: Fri, 1 Sep 2023 13:47:32 +0200 Subject: gdb/record: print frame information when exiting a recursive call Currently, when GDB is reverse stepping out of a function into the same function due to a recursive call, it doesn't print frame information, as reported by PR record/29178. This happens because when the inferior leaves the current frame, GDB decides to refresh the step information, clobbering the original step_frame_id, making it impossible to figure out later on that the frame has been changed. This commit changes GDB so that, if we notice we're in this exact situation, we won't refresh the step information. Because of implementation details, this change can cause some debug information to be read when it normally wouldn't before, which showed up as a regression on gdb.dwarf2/dw2-out-of-range-end-of-seq. Since that isn't a problem, the test was changed to allow for the new output. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29178 Approved-By: Tom Tromey --- gdb/infrun.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'gdb/infrun.c') diff --git a/gdb/infrun.c b/gdb/infrun.c index 08c39eb..6ba336d 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -7312,6 +7312,11 @@ process_event_stop_test (struct execution_control_state *ecs) frame = get_current_frame (); gdbarch = get_frame_arch (frame); + /* Shorthand to make if statements smaller. */ + struct frame_id original_frame_id + = ecs->event_thread->control.step_frame_id; + struct frame_id curr_frame_id = get_frame_id (get_current_frame ()); + switch (what.main_action) { case BPSTAT_WHAT_SET_LONGJMP_RESUME: @@ -8124,6 +8129,19 @@ process_event_stop_test (struct execution_control_state *ecs) "it's not the start of a statement"); } } + else if (execution_direction == EXEC_REVERSE + && curr_frame_id != original_frame_id + && original_frame_id.code_addr_p && curr_frame_id.code_addr_p + && original_frame_id.code_addr == curr_frame_id.code_addr) + { + /* If we enter here, we're leaving a recursive function call. In this + situation, we shouldn't refresh the step information, because if we + do, we'll lose the frame_id of when we started stepping, and this + will make GDB not know we need to print frame information. */ + refresh_step_info = false; + infrun_debug_printf ("reverse stepping, left a recursive call, don't " + "update step info so we remember we left a frame"); + } /* We aren't done stepping. -- cgit v1.1