On Wednesday 01 October 2008 20:19:28, Michael Snyder wrote: >   > +static void finish_backwards (struct symbol *, struct thread_info *); > + Minor nit. If you put the new function here, you don't need the forward declaration. >    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); >      } i18n. > + > +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."); Can't this happen in some circunstances, like the user hitting finish after stepi through no-debug-info-at-all-not-even-minimal-symbols code? > + > +  sal = find_pc_line (func_addr, 0); > + > +  /* TODO: Let's not worry about async until later.  */ If you don't want to think about it now, could you error out in the async+reverse case ? > + > +  /* 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); Would calling step_1 or step_once instead work here? It would probably avoid the kludge. I'm no reverse guru, but your comments made sense to me. > +    } > +  return; > +} > + >   >  static void >  environment_info (char *var, int from_tty) -- Pedro Alves &j!z޶9X܆[\