aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorGuinevere Larsen <blarsen@redhat.com>2023-09-01 13:47:32 +0200
committerGuinevere Larsen <blarsen@redhat.com>2023-11-20 10:54:03 +0100
commitbf2813aff8f2988ad3d53e819a0415abf295c91f (patch)
tree05d1bbc97043c285887ee94f602d16651dcfd076 /gdb/infrun.c
parent11788869e0a3713e847733be8712e4b3b5e4dfd9 (diff)
downloadfsf-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.c18
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.