2011-05-27 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index 8a85915fb11f79d82b006ed6c3ef4f4ac0ab0100..f499e3e64bf44b5b48275b31f9c6c40fa54ff4f5 100644 (file)
@@ -55,6 +55,8 @@
 #include "valprint.h"
 #include "inline-frame.h"
 #include "tracepoint.h"
+#include "inf-loop.h"
+#include "continuations.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -395,6 +397,8 @@ strip_bg_char (char **args)
 void
 post_create_inferior (struct target_ops *target, int from_tty)
 {
+  volatile struct gdb_exception ex;
+
   /* Be sure we own the terminal in case write operations are performed.  */ 
   target_terminal_ours ();
 
@@ -404,8 +408,16 @@ post_create_inferior (struct target_ops *target, int from_tty)
      don't need to.  */
   target_find_description ();
 
-  /* Now that we know the register layout, retrieve current PC.  */
-  stop_pc = regcache_read_pc (get_current_regcache ());
+  /* Now that we know the register layout, retrieve current PC.  But
+     if the PC is unavailable (e.g., we're opening a core file with
+     missing registers info), ignore it.  */
+  stop_pc = 0;
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      stop_pc = regcache_read_pc (get_current_regcache ());
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   if (exec_bfd)
     {
@@ -879,23 +891,21 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
     {
       for (; count > 0; count--)
        {
-         struct thread_info *tp;
-
          step_once (skip_subroutines, single_inst, count, thread);
 
-         if (target_has_execution
-             && !ptid_equal (inferior_ptid, null_ptid))
-           tp = inferior_thread ();
+         if (!target_has_execution)
+           break;
          else
-           tp = NULL;
-
-         if (!tp || !tp->control.stop_step || !tp->step_multi)
            {
-             /* If we stopped for some reason that is not stepping
-                there are no further steps to make.  */
-             if (tp)
-               tp->step_multi = 0;
-             break;
+             struct thread_info *tp = inferior_thread ();
+
+             if (!tp->control.stop_step || !tp->step_multi)
+               {
+                 /* If we stopped for some reason that is not stepping
+                    there are no further steps to make.  */
+                 tp->step_multi = 0;
+                 break;
+               }
            }
        }
 
@@ -986,12 +996,23 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
          if (!skip_subroutines && !single_inst
              && inline_skipped_frames (inferior_ptid))
            {
+             ptid_t resume_ptid;
+
+             /* Pretend that we've ran.  */
+             resume_ptid = user_visible_resume_ptid (1);
+             set_running (resume_ptid, 1);
+
              step_into_inline_frame (inferior_ptid);
              if (count > 1)
                step_once (skip_subroutines, single_inst, count - 1, thread);
              else
-               /* Pretend that we've stopped.  */
-               normal_stop ();
+               {
+                 /* Pretend that we've stopped.  */
+                 normal_stop ();
+
+                 if (target_can_async_p ())
+                   inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+               }
              return;
            }
 
@@ -1384,7 +1405,7 @@ print_return_value (struct type *func_type, struct type *value_type)
   /* FIXME: 2003-09-27: When returning from a nested inferior function
      call, it's possible (with no help from the architecture vector)
      to locate and return/print a "struct return" value.  This is just
-     a more complicated case of what is already being done in in the
+     a more complicated case of what is already being done in the
      inferior function call code.  In fact, when inferior function
      calls are made async, this will likely be made the norm.  */
 
@@ -1508,11 +1529,8 @@ finish_backward (struct symbol *function)
 {
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
-  struct breakpoint *breakpoint;
-  struct cleanup *old_chain;
   CORE_ADDR pc;
   CORE_ADDR func_addr;
-  int back_up;
 
   pc = get_frame_pc (get_current_frame ());
 
@@ -1522,8 +1540,7 @@ finish_backward (struct symbol *function)
 
   sal = find_pc_line (func_addr, 0);
 
-  /* We don't need a return value.  */
-  tp->control.proceed_to_finish = 0;
+  tp->control.proceed_to_finish = 1;
   /* 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
@@ -1537,33 +1554,25 @@ finish_backward (struct symbol *function)
     {
       struct frame_info *frame = get_selected_frame (NULL);
       struct gdbarch *gdbarch = get_frame_arch (frame);
+      struct symtab_and_line sr_sal;
+
+      /* Set a step-resume at the function's entry point.  Once that's
+        hit, we'll do one more step backwards.  */
+      init_sal (&sr_sal);
+      sr_sal.pc = sal.pc;
+      sr_sal.pspace = get_frame_program_space (frame);
+      insert_step_resume_breakpoint_at_sal (gdbarch,
+                                           sr_sal, null_frame_id);
 
-      /* Set breakpoint and continue.  */
-      breakpoint =
-       set_momentary_breakpoint (gdbarch, sal,
-                                 get_stack_frame_id (frame),
-                                 bp_breakpoint);
-      /* Tell the breakpoint to keep quiet.  We won't be done
-         until we've done another reverse single-step.  */
-      breakpoint_set_silent (breakpoint, 1);
-      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->control.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.  */
+      /* We're almost there -- we just need to back up by one more
+        single-step.  */
       tp->control.step_range_start = tp->control.step_range_end = 1;
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
     }
-  return;
 }
 
 /* finish_forward -- helper function for finish_command.  */
@@ -1631,10 +1640,6 @@ finish_command (char *arg, int from_tty)
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
-  /* Don't try to async in reverse.  */
-  if (async_exec && execution_direction == EXEC_REVERSE)
-    error (_("Asynchronous 'finish' not supported in reverse."));
-
   /* If we are not asked to run in the bg, then prepare to run in the
      foreground, synchronously.  */
   if (!async_exec && target_can_async_p ())
@@ -2516,7 +2521,7 @@ attach_command (char *args, int from_tty)
          return;
        }
 
-      wait_for_inferior (0);
+      wait_for_inferior ();
     }
 
   attach_command_post_wait (args, from_tty, async_exec);
@@ -2580,7 +2585,7 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
          return;
        }
       else
-       wait_for_inferior (0);
+       wait_for_inferior ();
     }
 
   async_exec = leave_running;
This page took 0.025691 seconds and 4 git commands to generate.