* infrun.c (normal_stop): Use has_stack_frames instead of
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index 50e8fff74604189bfd3c44fbf93bcae50e040962..9cad3cb18652673fe47f047db94636ae954b21eb 100644 (file)
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008 Free Software Foundation, Inc.
+   2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -86,8 +86,6 @@ static void unset_command (char *, int);
 
 static void float_info (char *, int);
 
-static void detach_command (char *, int);
-
 static void disconnect_command (char *, int);
 
 static void unset_environment_command (char *, int);
@@ -168,11 +166,6 @@ int stopped_by_random_signal;
    in format described in environ.h.  */
 
 struct gdb_environ *inferior_environ;
-
-/* When set, no calls to target_resumed observer will be made.  */
-int suppress_resume_observer = 0;
-/* When set, normal_stop will not call the normal_stop observer.  */
-int suppress_stop_observer = 0;
 \f
 /* Accessor routines. */
 
@@ -443,8 +436,8 @@ kill_if_already_running (int from_tty)
       target_require_runnable ();
 
       if (from_tty
-         && !query ("The program being debugged has been started already.\n\
-Start it from the beginning? "))
+         && !query (_("The program being debugged has been started already.\n\
+Start it from the beginning? ")))
        error (_("Program not restarted."));
       target_kill ();
     }
@@ -458,6 +451,8 @@ static void
 run_command_1 (char *args, int from_tty, int tbreak_at_main)
 {
   char *exec_file;
+  struct cleanup *old_chain;
+  ptid_t ptid;
 
   dont_repeat ();
 
@@ -546,14 +541,29 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   target_create_inferior (exec_file, get_inferior_args (),
                          environ_vector (inferior_environ), from_tty);
 
+  /* We're starting off a new process.  When we get out of here, in
+     non-stop mode, finish the state of all threads of that process,
+     but leave other threads alone, as they may be stopped in internal
+     events --- the frontend shouldn't see them as stopped.  In
+     all-stop, always finish the state of all threads, as we may be
+     resuming more than just the new process.  */
+  if (non_stop)
+    ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+  else
+    ptid = minus_one_ptid;
+  old_chain = make_cleanup (finish_thread_state_cleanup, &ptid);
+
   /* Pass zero for FROM_TTY, because at this point the "run" command
      has done its thing; now we are setting up the running program.  */
   post_create_inferior (&current_target, 0);
 
   /* Start the target running.  */
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
-}
 
+  /* Since there was no error, there's no need to finish the thread
+     states here.  */
+  discard_cleanups (old_chain);
+}
 
 static void
 run_command (char *args, int from_tty)
@@ -606,6 +616,15 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
   return 0;
 }
 
+void
+ensure_valid_thread (void)
+{
+  if (ptid_equal (inferior_ptid, null_ptid)
+      || is_exited (inferior_ptid))
+    error (_("\
+Cannot execute this command without a live selected thread."));
+}
+
 void
 continue_1 (int all_threads)
 {
@@ -627,6 +646,7 @@ continue_1 (int all_threads)
     }
   else
     {
+      ensure_valid_thread ();
       ensure_not_running ();
       clear_proceed_status ();
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
@@ -771,6 +791,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
   int thread = -1;
 
   ERROR_NO_INFERIOR;
+  ensure_valid_thread ();
   ensure_not_running ();
 
   if (count_string)
@@ -801,67 +822,41 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
       make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
 
-  /* In synchronous case, all is well, just use the regular for loop. */
+  /* In synchronous case, all is well; each step_once call will step once.  */
   if (!target_can_async_p ())
     {
       for (; count > 0; count--)
        {
-         struct thread_info *tp = inferior_thread ();
-         clear_proceed_status ();
-
-         frame = get_current_frame ();
-         tp->step_frame_id = get_frame_id (frame);
+         struct thread_info *tp;
+         step_once (skip_subroutines, single_inst, count, thread);
 
-         if (!single_inst)
-           {
-             find_pc_line_pc_range (stop_pc,
-                                    &tp->step_range_start, &tp->step_range_end);
-             if (tp->step_range_end == 0)
-               {
-                 char *name;
-                 if (find_pc_partial_function (stop_pc, &name,
-                                               &tp->step_range_start,
-                                               &tp->step_range_end) == 0)
-                   error (_("Cannot find bounds of current function"));
-
-                 target_terminal_ours ();
-                 printf_filtered (_("\
-Single stepping until exit from function %s, \n\
-which has no line number information.\n"), name);
-               }
-           }
+         if (target_has_execution
+             && !ptid_equal (inferior_ptid, null_ptid))
+           tp = inferior_thread ();
          else
+           tp = NULL;
+
+         if (!tp || !tp->stop_step || !tp->step_multi)
            {
-             /* Say we are stepping, but stop after one insn whatever it does.  */
-             tp->step_range_start = tp->step_range_end = 1;
-             if (!skip_subroutines)
-               /* It is stepi.
-                  Don't step over function calls, not even to functions lacking
-                  line numbers.  */
-               tp->step_over_calls = STEP_OVER_NONE;
+             /* If we stopped for some reason that is not stepping
+                there are no further steps to make.  */
+             if (tp)
+               tp->step_multi = 0;
+             break;
            }
-
-         if (skip_subroutines)
-           tp->step_over_calls = STEP_OVER_ALL;
-
-         tp->step_multi = (count > 1);
-         proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
-
-         if (!target_has_execution
-             || !inferior_thread ()->stop_step)
-           break;
        }
 
       do_cleanups (cleanups);
-      return;
     }
-  /* In case of asynchronous target things get complicated, do only
-     one step for now, before returning control to the event loop. Let
-     the continuation figure out how many other steps we need to do,
-     and handle them one at the time, through step_once(). */
   else
     {
+      /* In the case of an asynchronous target things get complicated;
+        do only one step for now, before returning control to the
+        event loop.  Let the continuation figure out how many other
+        steps we need to do, and handle them one at the time, through
+        step_once.  */
       step_once (skip_subroutines, single_inst, count, thread);
+
       /* We are running, and the continuation is installed.  It will
         disable the longjmp breakpoint as appropriate.  */
       discard_cleanups (cleanups);
@@ -895,7 +890,8 @@ step_1_continuation (void *args)
        {
          /* There are more steps to make, and we did stop due to
             ending a stepping range.  Do another step.  */
-         step_once (a->skip_subroutines, a->single_inst, a->count - 1, a->thread);
+         step_once (a->skip_subroutines, a->single_inst,
+                    a->count - 1, a->thread);
          return;
        }
       tp->step_multi = 0;
@@ -907,18 +903,16 @@ step_1_continuation (void *args)
     delete_longjmp_breakpoint (a->thread);
 }
 
-/* Do just one step operation. If count >1 we will have to set up a
-   continuation to be done after the target stops (after this one
-   step). This is useful to implement the 'step n' kind of commands, in
-   case of asynchronous targets. We had to split step_1 into two parts,
-   one to be done before proceed() and one afterwards. This function is
-   called in case of step n with n>1, after the first step operation has
-   been completed.*/
-static void 
+/* Do just one step operation.  This is useful to implement the 'step
+   n' kind of commands.  In case of asynchronous targets, we will have
+   to set up a continuation to be done after the target stops (after
+   this one step).  For synch targets, the caller handles further
+   stepping.  */
+
+static void
 step_once (int skip_subroutines, int single_inst, int count, int thread)
 {
   struct frame_info *frame;
-  struct step_1_continuation_args *args;
 
   if (count > 0)
     {
@@ -930,13 +924,14 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
       clear_proceed_status ();
 
       frame = get_current_frame ();
-      if (!frame)              /* Avoid coredump here.  Why tho? */
-       error (_("No current frame"));
       tp->step_frame_id = get_frame_id (frame);
 
       if (!single_inst)
        {
-         find_pc_line_pc_range (stop_pc,
+         CORE_ADDR pc;
+
+         pc = get_frame_pc (frame);
+         find_pc_line_pc_range (pc,
                                 &tp->step_range_start, &tp->step_range_end);
 
          /* If we have no line info, switch to stepi mode.  */
@@ -947,7 +942,7 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
          else if (tp->step_range_end == 0)
            {
              char *name;
-             if (find_pc_partial_function (stop_pc, &name,
+             if (find_pc_partial_function (pc, &name,
                                            &tp->step_range_start,
                                            &tp->step_range_end) == 0)
                error (_("Cannot find bounds of current function"));
@@ -975,12 +970,21 @@ which has no line number information.\n"), name);
       tp->step_multi = (count > 1);
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
 
-      args = xmalloc (sizeof (*args));
-      args->skip_subroutines = skip_subroutines;
-      args->single_inst = single_inst;
-      args->count = count;
-      args->thread = thread;
-      add_intermediate_continuation (tp, step_1_continuation, args, xfree);
+      /* For async targets, register a continuation to do any
+        additional steps.  For sync targets, the caller will handle
+        further stepping.  */
+      if (target_can_async_p ())
+       {
+         struct step_1_continuation_args *args;
+
+         args = xmalloc (sizeof (*args));
+         args->skip_subroutines = skip_subroutines;
+         args->single_inst = single_inst;
+         args->count = count;
+         args->thread = thread;
+
+         add_intermediate_continuation (tp, step_1_continuation, args, xfree);
+       }
     }
 }
 
@@ -998,6 +1002,7 @@ jump_command (char *arg, int from_tty)
   int async_exec = 0;
 
   ERROR_NO_INFERIOR;
+  ensure_valid_thread ();
   ensure_not_running ();
 
   /* Find out whether we must run in the background. */
@@ -1031,7 +1036,7 @@ jump_command (char *arg, int from_tty)
   sfn = find_pc_function (sal.pc);
   if (fn != NULL && sfn != fn)
     {
-      if (!query ("Line %d is not in `%s'.  Jump anyway? ", sal.line,
+      if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
                  SYMBOL_PRINT_NAME (fn)))
        {
          error (_("Not confirmed."));
@@ -1045,7 +1050,7 @@ jump_command (char *arg, int from_tty)
       if (section_is_overlay (SYMBOL_OBJ_SECTION (sfn)) &&
          !section_is_mapped (SYMBOL_OBJ_SECTION (sfn)))
        {
-         if (!query ("WARNING!!!  Destination is in unmapped overlay!  Jump anyway? "))
+         if (!query (_("WARNING!!!  Destination is in unmapped overlay!  Jump anyway? ")))
            {
              error (_("Not confirmed."));
              /* NOTREACHED */
@@ -1099,6 +1104,7 @@ signal_command (char *signum_exp, int from_tty)
 
   dont_repeat ();              /* Too dangerous.  */
   ERROR_NO_INFERIOR;
+  ensure_valid_thread ();
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
@@ -1147,11 +1153,7 @@ signal_command (char *signum_exp, int from_tty)
     }
 
   clear_proceed_status ();
-  /* "signal 0" should not get stuck if we are stopped at a breakpoint.
-     FIXME: Neither should "signal foo" but when I tried passing
-     (CORE_ADDR)-1 unconditionally I got a testsuite failure which I haven't
-     tried to track down yet.  */
-  proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
+  proceed ((CORE_ADDR) -1, oursig, 0);
 }
 
 /* Proceed until we reach a different source line with pc greater than
@@ -1179,7 +1181,7 @@ until_next_command (int from_tty)
      than the current line (if in symbolic section) or pc (if
      not). */
 
-  pc = read_pc ();
+  pc = get_frame_pc (frame);
   func = find_pc_function (pc);
 
   if (!func)
@@ -1352,13 +1354,16 @@ static void
 finish_command_continuation (void *arg)
 {
   struct finish_command_continuation_args *a = arg;
-
+  struct thread_info *tp = NULL;
   bpstat bs = NULL;
 
   if (!ptid_equal (inferior_ptid, null_ptid)
       && target_has_execution
       && is_stopped (inferior_ptid))
-    bs = inferior_thread ()->stop_bpstat;
+    {
+      tp = inferior_thread ();
+      bs = tp->stop_bpstat;
+    }
 
   if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
       && a->function != NULL)
@@ -1375,22 +1380,15 @@ finish_command_continuation (void *arg)
     }
 
   /* We suppress normal call of normal_stop observer and do it here so
-     that that *stopped notification includes the return value.  */
-  /* NOTE: This is broken in non-stop mode.  There is no guarantee the
-     next stop will be in the same thread that we started doing a
-     finish on.  This suppressing (or some other replacement means)
-     should be a thread property.  */
-  observer_notify_normal_stop (bs);
-  suppress_stop_observer = 0;
+     that the *stopped notification includes the return value.  */
+  if (bs != NULL && tp->proceed_to_finish)
+    observer_notify_normal_stop (bs, 1 /* print frame */);
   delete_breakpoint (a->breakpoint);
 }
 
 static void
 finish_command_continuation_free_arg (void *arg)
 {
-  /* NOTE: See finish_command_continuation.  This would go away, if
-     this suppressing is made a thread property.  */
-  suppress_stop_observer = 0;
   xfree (arg);
 }
 
@@ -1403,11 +1401,13 @@ finish_backward (struct symbol *function)
   struct thread_info *tp = inferior_thread ();
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
+  CORE_ADDR pc;
   CORE_ADDR func_addr;
   int back_up;
 
-  if (find_pc_partial_function (get_frame_pc (get_current_frame ()),
-                               NULL, &func_addr, NULL) == 0)
+  pc = get_frame_pc (get_current_frame ());
+
+  if (find_pc_partial_function (pc, NULL, &func_addr, NULL) == 0)
     internal_error (__FILE__, __LINE__,
                    _("Finish: couldn't find function."));
 
@@ -1424,7 +1424,7 @@ finish_backward (struct symbol *function)
      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 ())
+  if (sal.pc != pc)
     {
       /* Set breakpoint and continue.  */
       breakpoint =
@@ -1473,8 +1473,6 @@ finish_forward (struct symbol *function, struct frame_info *frame)
   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;
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
   cargs = xmalloc (sizeof (*cargs));
@@ -1587,8 +1585,7 @@ program_info (char *args, int from_tty)
   stat = bpstat_num (&bs, &num);
 
   target_files_info ();
-  printf_filtered (_("Program stopped at %s.\n"),
-                  hex_string ((unsigned long) stop_pc));
+  printf_filtered (_("Program stopped at %s.\n"), paddress (stop_pc));
   if (tp->stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
@@ -1953,21 +1950,6 @@ registers_info (char *addr_exp, int fpregs)
          }
       }
 
-      /* A register number?  (how portable is this one?).  */
-      {
-       char *endptr;
-       int regnum = strtol (start, &endptr, 0);
-       if (endptr == end
-           && regnum >= 0
-           && regnum < gdbarch_num_regs (gdbarch)
-                       + gdbarch_num_pseudo_regs (gdbarch))
-         {
-           gdbarch_print_registers_info (gdbarch, gdb_stdout,
-                                         frame, regnum, fpregs);
-           continue;
-         }
-      }
-
       /* A register group?  */
       {
        struct reggroup *group;
@@ -2240,7 +2222,7 @@ attach_command (char *args, int from_tty)
     ;
   else if (target_has_execution)
     {
-      if (query ("A program is being debugged already.  Kill it? "))
+      if (query (_("A program is being debugged already.  Kill it? ")))
        target_kill ();
       else
        error (_("Not killed."));
@@ -2320,9 +2302,8 @@ attach_command (char *args, int from_tty)
          a->args = xstrdup (args);
          a->from_tty = from_tty;
          a->async_exec = async_exec;
-         add_continuation (inferior_thread (),
-                           attach_command_continuation, a,
-                           attach_command_continuation_free_args);
+         add_inferior_continuation (attach_command_continuation, a,
+                                    attach_command_continuation_free_args);
          discard_cleanups (back_to);
          return;
        }
@@ -2334,6 +2315,72 @@ attach_command (char *args, int from_tty)
   discard_cleanups (back_to);
 }
 
+/* We had just found out that the target was already attached to an
+   inferior.  PTID points at a thread of this new inferior, that is
+   the most likely to be stopped right now, but not necessarily so.
+   The new inferior is assumed to be already added to the inferior
+   list at this point.  If LEAVE_RUNNING, then leave the threads of
+   this inferior running, except those we've explicitly seen reported
+   as stopped.  */
+
+void
+notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
+{
+  struct cleanup* old_chain;
+  int async_exec;
+
+  old_chain = make_cleanup (null_cleanup, NULL);
+
+  /* If in non-stop, leave threads as running as they were.  If
+     they're stopped for some reason other than us telling it to, the
+     target reports a signal != TARGET_SIGNAL_0.  We don't try to
+     resume threads with such a stop signal.  */
+  async_exec = non_stop;
+
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    make_cleanup_restore_current_thread ();
+
+  switch_to_thread (ptid);
+
+  /* When we "notice" a new inferior we need to do all the things we
+     would normally do if we had just attached to it.  */
+
+  if (is_executing (inferior_ptid))
+    {
+      struct inferior *inferior = current_inferior ();
+
+      /* We're going to install breakpoints, and poke at memory,
+        ensure that the inferior is stopped for a moment while we do
+        that.  */
+      target_stop (inferior_ptid);
+
+      inferior->stop_soon = STOP_QUIETLY_REMOTE;
+
+      /* Wait for stop before proceeding.  */
+      if (target_can_async_p ())
+       {
+         struct attach_command_continuation_args *a;
+
+         a = xmalloc (sizeof (*a));
+         a->args = xstrdup ("");
+         a->from_tty = from_tty;
+         a->async_exec = async_exec;
+         add_inferior_continuation (attach_command_continuation, a,
+                                    attach_command_continuation_free_args);
+
+         do_cleanups (old_chain);
+         return;
+       }
+      else
+       wait_for_inferior (0);
+    }
+
+  async_exec = leave_running;
+  attach_command_post_wait ("" /* args */, from_tty, async_exec);
+
+  do_cleanups (old_chain);
+}
+
 /*
  * detach_command --
  * takes a program previously attached to and detaches it.
@@ -2345,10 +2392,14 @@ attach_command (char *args, int from_tty)
  * started via the normal ptrace (PTRACE_TRACEME).
  */
 
-static void
+void
 detach_command (char *args, int from_tty)
 {
   dont_repeat ();              /* Not for the faint of heart.  */
+
+  if (ptid_equal (inferior_ptid, null_ptid))
+    error (_("The program is not being run."));
+
   target_detach (args, from_tty);
 
   /* If the solist is global across inferiors, don't clear it when we
This page took 0.030139 seconds and 4 git commands to generate.