aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-05-26 15:32:38 +0000
committerPedro Alves <palves@redhat.com>2011-05-26 15:32:38 +0000
commit9da8c2a0faa07d6b876397bdb3e87509897c68cd (patch)
tree019d3043a8d4b7bab81bda6fa527f34e1f9bb1c2 /gdb/infrun.c
parent2c03e5bed3ac8158eaae4621f4b4550e4ab6d4ef (diff)
downloadgdb-9da8c2a0faa07d6b876397bdb3e87509897c68cd.zip
gdb-9da8c2a0faa07d6b876397bdb3e87509897c68cd.tar.gz
gdb-9da8c2a0faa07d6b876397bdb3e87509897c68cd.tar.bz2
2011-05-26 Pedro Alves <pedro@codesourcery.com>
gdb/ * infcmd.c (finish_backward): Set a step-resume breakpoint at the function's entry point instead of a manually managed momentary breakpoint, and only ever issue one proceed call. * infrun.c (handle_inferior_event) <BPSTAT_WHAT_STEP_RESUME>: If doing a reverse-finish, switch to stepi mode, to do another step. (insert_step_resume_breakpoint_at_sal): Make public. (normal_stop): No need to save function value return registers if going reverse. * inferior.h (insert_step_resume_breakpoint_at_sal): Declare. gdb/testsuite/ * gdb.reverse/finish-reverse-bkpt.exp: New test.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index e8ea53a..67acdc4 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -103,10 +103,6 @@ static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
-static void insert_step_resume_breakpoint_at_sal (struct gdbarch *,
- struct symtab_and_line ,
- struct frame_id);
-
static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
/* When set, stop the 'step' command if we enter a function which has
@@ -4354,6 +4350,20 @@ process_event_stop_test:
fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
delete_step_resume_breakpoint (ecs->event_thread);
+ if (ecs->event_thread->control.proceed_to_finish
+ && execution_direction == EXEC_REVERSE)
+ {
+ struct thread_info *tp = ecs->event_thread;
+
+ /* We are finishing a function in reverse, and just hit
+ the step-resume breakpoint at the start address of the
+ function, and we're almost there -- just need to back
+ up by one more single-step, which should take us back
+ to the function call. */
+ tp->control.step_range_start = tp->control.step_range_end = 1;
+ keep_going (ecs);
+ return;
+ }
if (stop_pc == ecs->stop_func_start
&& execution_direction == EXEC_REVERSE)
{
@@ -5235,7 +5245,7 @@ insert_step_resume_breakpoint_at_sal_1 (struct gdbarch *gdbarch,
= set_momentary_breakpoint (gdbarch, sr_sal, sr_id, sr_type);
}
-static void
+void
insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
struct symtab_and_line sr_sal,
struct frame_id sr_id)
@@ -5859,7 +5869,8 @@ normal_stop (void)
/* Save the function value return registers, if we care.
We might be about to restore their previous contents. */
- if (inferior_thread ()->control.proceed_to_finish)
+ if (inferior_thread ()->control.proceed_to_finish
+ && execution_direction != EXEC_REVERSE)
{
/* This should not be necessary. */
if (stop_registers)