diff options
author | Michael Snyder <msnyder@vmware.com> | 2008-09-30 23:56:56 +0000 |
---|---|---|
committer | Michael Snyder <msnyder@vmware.com> | 2008-09-30 23:56:56 +0000 |
commit | de1aa9cde5da3431d58241d0248ef88ffb5c0b0b (patch) | |
tree | 126a8f97680fe8347671b4f958ade19a43954447 | |
parent | 621dd84b762ff978f6e20243d5683216d8d6fc1e (diff) | |
download | binutils-gdb-de1aa9cde5da3431d58241d0248ef88ffb5c0b0b.tar.gz |
2008-09-30 Michael Snyder <msnyder@vmware.com>
* breakpoint.h (breakpoint_silence): Export.
* breakpoint.c (breakpoint_silence): New function.
* infcmd.c (finish_command): Check for reverse exec direction.
(finish_backward): New function, handle finish cmd in reverse.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/breakpoint.c | 7 | ||||
-rw-r--r-- | gdb/breakpoint.h | 3 | ||||
-rw-r--r-- | gdb/infcmd.c | 90 |
4 files changed, 97 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9fed243a095..35b4961d1b2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -26,6 +26,11 @@ Handle stepping between line ranges in reverse. (print_stop_reason): Print reason for NO_HISTORY. + * breakpoint.h (breakpoint_silence): Export. + * breakpoint.c (breakpoint_silence): New function. + * infcmd.c (finish_command): Check for reverse exec direction. + (finish_backward): New function, handle finish cmd in reverse. + 2008-09-30 Paul Hilfinger <hilfinger@adacore.com> * ada-lang.c (ada_modulus): Correct to avoid sign problem with diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 6e863d7f4ae..b862d366522 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7741,6 +7741,13 @@ breakpoint_clear_ignore_counts (void) b->ignore_count = 0; } +void +breakpoint_silence (struct breakpoint *b) +{ + /* Silence the breakpoint. */ + b->silent = 1; +} + /* Command to set ignore-count of breakpoint N to COUNT. */ static void diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index db6e9724c8e..24d58906fea 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -884,4 +884,7 @@ extern int breakpoints_always_inserted_mode (void); in our opinion won't ever trigger. */ extern void breakpoint_retire_moribund (void); +/* Tell a breakpoint to be quiet. */ +extern void breakpoint_silence (struct breakpoint *); + #endif /* !defined (BREAKPOINT_H) */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 6ed6341fa2b..bd9ec758782 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1369,6 +1369,8 @@ finish_command_continuation_free_arg (void *arg) /* "finish": Set a temporary breakpoint at the place the selected frame will return to, then continue. */ +static void finish_backwards (struct symbol *, struct thread_info *); + static void finish_command (char *arg, int from_tty) { @@ -1412,13 +1414,6 @@ finish_command (char *arg, int from_tty) clear_proceed_status (); - sal = find_pc_line (get_frame_pc (frame), 0); - sal.pc = get_frame_pc (frame); - - breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish); - - old_chain = make_cleanup_delete_breakpoint (breakpoint); - /* Find the function we will return from. */ function = find_pc_function (get_frame_pc (get_selected_frame (NULL))); @@ -1427,10 +1422,29 @@ finish_command (char *arg, int from_tty) source. */ if (from_tty) { - printf_filtered (_("Run till exit from ")); + if (target_get_execution_direction () == EXEC_REVERSE) + printf_filtered ("Run back to call of "); + else + printf_filtered ("Run till exit from "); + print_stack_frame (get_selected_frame (NULL), 1, LOCATION); } + if (target_get_execution_direction () == EXEC_REVERSE) + { + /* Split off at this point. */ + finish_backwards (function, tp); + return; + } + + sal = find_pc_line (get_frame_pc (frame), 0); + sal.pc = get_frame_pc (frame); + + breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), + bp_finish); + + old_chain = make_cleanup_delete_breakpoint (breakpoint); + tp->proceed_to_finish = 1; /* We want stop_registers, please... */ make_cleanup_restore_integer (&suppress_stop_observer); suppress_stop_observer = 1; @@ -1514,6 +1528,66 @@ It stopped at a breakpoint that has since been deleted.\n")); Type \"info stack\" or \"info registers\" for more information.\n")); } } + +static void +finish_backwards (struct symbol *function, struct thread_info *tp) +{ + struct symtab_and_line sal; + struct breakpoint *breakpoint; + struct cleanup *old_chain; + CORE_ADDR func_addr; + int back_up; + + if (find_pc_partial_function (get_frame_pc (get_current_frame ()), + NULL, &func_addr, NULL) == 0) + internal_error (__FILE__, __LINE__, + "Finish: couldn't find function."); + + sal = find_pc_line (func_addr, 0); + + /* TODO: Let's not worry about async until later. */ + + /* We don't need a return value. */ + tp->proceed_to_finish = 0; + /* Special case: if we're sitting at the function entry point, + then all we need to do is take a reverse singlestep. We + don't need to set a breakpoint, and indeed it would do us + no good to do so. + + Note that this can only happen at frame #0, since there's + no way that a function up the stack can have a return address + that's equal to its entry point. */ + + if (sal.pc != read_pc ()) + { + /* Set breakpoint and continue. */ + breakpoint = + set_momentary_breakpoint (sal, + get_frame_id (get_selected_frame (NULL)), + bp_breakpoint); + /* Tell the breakpoint to keep quiet. We won't be done + until we've done another reverse single-step. */ + breakpoint_silence (breakpoint); + old_chain = make_cleanup_delete_breakpoint (breakpoint); + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); + /* We will be stopped when proceed returns. */ + back_up = bpstat_find_breakpoint (tp->stop_bpstat, breakpoint) != NULL; + do_cleanups (old_chain); + } + else + back_up = 1; + if (back_up) + { + /* If in fact we hit the step-resume breakpoint (and not + some other breakpoint), then we're almost there -- + we just need to back up by one more single-step. */ + /* (Kludgy way of letting wait_for_inferior know...) */ + tp->step_range_start = tp->step_range_end = 1; + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); + } + return; +} + static void environment_info (char *var, int from_tty) |