diff options
author | Guinevere Larsen <blarsen@redhat.com> | 2023-09-01 13:47:32 +0200 |
---|---|---|
committer | Guinevere Larsen <blarsen@redhat.com> | 2023-11-20 10:54:03 +0100 |
commit | bf2813aff8f2988ad3d53e819a0415abf295c91f (patch) | |
tree | 05d1bbc97043c285887ee94f602d16651dcfd076 /gdb/infrun.c | |
parent | 11788869e0a3713e847733be8712e4b3b5e4dfd9 (diff) | |
download | fsf-binutils-gdb-bf2813aff8f2988ad3d53e819a0415abf295c91f.zip fsf-binutils-gdb-bf2813aff8f2988ad3d53e819a0415abf295c91f.tar.gz fsf-binutils-gdb-bf2813aff8f2988ad3d53e819a0415abf295c91f.tar.bz2 |
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 <tom@tromey.com>
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 18 |
1 files changed, 18 insertions, 0 deletions
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. |