gdb/
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index a4c6c94a47cc1bcd24cb900b8406974f67786c2f..5efbf39f965cbee08f5481b59ee97525a3f36838 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, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,6 +20,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include <signal.h>
 #include "gdb_string.h"
 #include "symtab.h"
@@ -51,6 +52,9 @@
 #include "exceptions.h"
 #include "cli/cli-decode.h"
 #include "gdbthread.h"
+#include "valprint.h"
+#include "inline-frame.h"
+#include "tracepoint.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -85,8 +89,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);
@@ -104,7 +106,8 @@ static void signal_command (char *, int);
 static void jump_command (char *, int);
 
 static void step_1 (int, int, char *);
-static void step_once (int skip_subroutines, int single_inst, int count, int thread);
+static void step_once (int skip_subroutines, int single_inst,
+                      int count, int thread);
 
 static void next_command (char *, int);
 
@@ -120,25 +123,21 @@ static int strip_bg_char (char **);
 
 void _initialize_infcmd (void);
 
-#define GO_USAGE   "Usage: go <location>\n"
-
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error (_("The program is not being run."));
 
-/* String containing arguments to give to the program, separated by spaces.
-   Empty string (pointer to '\0') means no args.  */
-
-static char *inferior_args;
+/* Scratch area where string containing arguments to give to the
+   program will be stored by 'set args'.  As soon as anything is
+   stored, notice_args_set will move it into per-inferior storage.
+   Arguments are separated by spaces.  Empty string (pointer to '\0')
+   means no args.  */
 
-/* The inferior arguments as a vector.  If INFERIOR_ARGC is nonzero,
-   then we must compute INFERIOR_ARGS from this (via the target).  */
+static char *inferior_args_scratch;
 
-static int inferior_argc;
-static char **inferior_argv;
+/* Scratch area where 'set inferior-tty' will store user-provided value.
+   We'll immediate copy it into per-inferior storage.  */
 
-/* File name for default use for standard in/out in the inferior.  */
-
-static char *inferior_io_terminal;
+static char *inferior_io_terminal_scratch;
 
 /* Pid of our debugged inferior, or 0 if no inferior now.
    Since various parts of infrun.c test this to see whether there is a program
@@ -158,93 +157,107 @@ int breakpoint_proceeded;
 
 /* Nonzero if stopped due to completion of a stack dummy routine.  */
 
-int stop_stack_dummy;
+enum stop_stack_kind stop_stack_dummy;
 
 /* Nonzero if stopped due to a random (unexpected) signal in inferior
    process.  */
 
 int stopped_by_random_signal;
 
-/* Environment to use for running inferior,
-   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. */
+/* Accessor routines.  */
+
+/* Set the io terminal for the current inferior.  Ownership of
+   TERMINAL_NAME is not transferred.  */
 
 void 
 set_inferior_io_terminal (const char *terminal_name)
 {
-  if (inferior_io_terminal)
-    xfree (inferior_io_terminal);
-
-  if (!terminal_name)
-    inferior_io_terminal = NULL;
-  else
-    inferior_io_terminal = savestring (terminal_name, strlen (terminal_name));
+  xfree (current_inferior ()->terminal);
+  current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0;
 }
 
 const char *
 get_inferior_io_terminal (void)
 {
-  return inferior_io_terminal;
+  return current_inferior ()->terminal;
+}
+
+static void
+set_inferior_tty_command (char *args, int from_tty,
+                         struct cmd_list_element *c)
+{
+  /* CLI has assigned the user-provided value to inferior_io_terminal_scratch.
+     Now route it to current inferior.  */
+  set_inferior_io_terminal (inferior_io_terminal_scratch);
+}
+
+static void
+show_inferior_tty_command (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  /* Note that we ignore the passed-in value in favor of computing it
+     directly.  */
+  const char *inferior_io_terminal = get_inferior_io_terminal ();
+
+  if (inferior_io_terminal == NULL)
+    inferior_io_terminal = "";
+  fprintf_filtered (gdb_stdout,
+                   _("Terminal for future runs of program being debugged "
+                     "is \"%s\".\n"), inferior_io_terminal);
 }
 
 char *
 get_inferior_args (void)
 {
-  if (inferior_argc != 0)
+  if (current_inferior ()->argc != 0)
     {
-      char *n, *old;
+      char *n;
 
-      n = gdbarch_construct_inferior_arguments (current_gdbarch,
-                                               inferior_argc, inferior_argv);
-      old = set_inferior_args (n);
-      xfree (old);
+      n = construct_inferior_arguments (current_inferior ()->argc,
+                                       current_inferior ()->argv);
+      set_inferior_args (n);
+      xfree (n);
     }
 
-  if (inferior_args == NULL)
-    inferior_args = xstrdup ("");
+  if (current_inferior ()->args == NULL)
+    current_inferior ()->args = xstrdup ("");
 
-  return inferior_args;
+  return current_inferior ()->args;
 }
 
-char *
+/* Set the arguments for the current inferior.  Ownership of
+   NEWARGS is not transferred.  */
+
+void
 set_inferior_args (char *newargs)
 {
-  char *saved_args = inferior_args;
-
-  inferior_args = newargs;
-  inferior_argc = 0;
-  inferior_argv = 0;
-
-  return saved_args;
+  xfree (current_inferior ()->args);
+  current_inferior ()->args = newargs ? xstrdup (newargs) : NULL;
+  current_inferior ()->argc = 0;
+  current_inferior ()->argv = 0;
 }
 
 void
 set_inferior_args_vector (int argc, char **argv)
 {
-  inferior_argc = argc;
-  inferior_argv = argv;
+  current_inferior ()->argc = argc;
+  current_inferior ()->argv = argv;
 }
 
 /* Notice when `set args' is run.  */
 static void
-notice_args_set (char *args, int from_tty, struct cmd_list_element *c)
+set_args_command (char *args, int from_tty, struct cmd_list_element *c)
 {
-  inferior_argc = 0;
-  inferior_argv = 0;
+  /* CLI has assigned the user-provided value to inferior_args_scratch.
+     Now route it to current inferior.  */
+  set_inferior_args (inferior_args_scratch);
 }
 
 /* Notice when `show args' is run.  */
 static void
-notice_args_read (struct ui_file *file, int from_tty,
-                 struct cmd_list_element *c, const char *value)
+show_args_command (struct ui_file *file, int from_tty,
+                  struct cmd_list_element *c, const char *value)
 {
   /* Note that we ignore the passed-in value in favor of computing it
      directly.  */
@@ -255,7 +268,7 @@ notice_args_read (struct ui_file *file, int from_tty,
 /* Compute command-line string given argument vector.  This does the
    same shell processing as fork_inferior.  */
 char *
-construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
+construct_inferior_arguments (int argc, char **argv)
 {
   char *result;
 
@@ -271,7 +284,7 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
 
       /* We over-compute the size.  It shouldn't matter.  */
       for (i = 0; i < argc; ++i)
-       length += 2 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0');
+       length += 3 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0');
 
       result = (char *) xmalloc (length);
       out = result;
@@ -291,9 +304,21 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
            {
              for (cp = argv[i]; *cp; ++cp)
                {
-                 if (strchr (special, *cp) != NULL)
-                   *out++ = '\\';
-                 *out++ = *cp;
+                 if (*cp == '\n')
+                   {
+                     /* A newline cannot be quoted with a backslash (it
+                        just disappears), only by putting it inside
+                        quotes.  */
+                     *out++ = '\'';
+                     *out++ = '\n';
+                     *out++ = '\'';
+                   }
+                 else
+                   {
+                     if (strchr (special, *cp) != NULL)
+                       *out++ = '\\';
+                     *out++ = *cp;
+                   }
                }
            }
        }
@@ -314,7 +339,8 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
          if (cp == NULL)
            cp = strchr (argv[i], '\n');
          if (cp != NULL)
-           error (_("can't handle command-line argument containing whitespace"));
+           error (_("can't handle command-line "
+                    "argument containing whitespace"));
          length += strlen (argv[i]) + 1;
        }
 
@@ -334,8 +360,8 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
 
 /* This function detects whether or not a '&' character (indicating
    background execution) has been added as *the last* of the arguments ARGS
-   of a command. If it has, it removes it and returns 1. Otherwise it
-   does nothing and returns 0. */
+   of a command.  If it has, it removes it and returns 1.  Otherwise it
+   does nothing and returns 0.  */
 static int
 strip_bg_char (char **args)
 {
@@ -362,15 +388,6 @@ strip_bg_char (char **args)
   return 0;
 }
 
-void
-tty_command (char *file, int from_tty)
-{
-  if (file == 0)
-    error_no_arg (_("terminal name for running target process"));
-
-  set_inferior_io_terminal (file);
-}
-
 /* Common actions to take after creating any sort of inferior, by any
    means (running, attaching, connecting, et cetera).  The target
    should be stopped.  */
@@ -387,28 +404,50 @@ 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 ());
+
   if (exec_bfd)
     {
-      /* Sometimes the platform-specific hook loads initial shared
-        libraries, and sometimes it doesn't.  Try to do so first, so
-        that we can add them with the correct value for FROM_TTY.
-        If we made all the inferior hook methods consistent,
-        this call could be removed.  */
-#ifdef SOLIB_ADD
-      SOLIB_ADD (NULL, from_tty, target, auto_solib_add);
-#else
-      solib_add (NULL, from_tty, target, auto_solib_add);
-#endif
-
       /* Create the hooks to handle shared library load and unload
         events.  */
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
       SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #else
-      solib_create_inferior_hook ();
+      solib_create_inferior_hook (from_tty);
+#endif
+    }
+
+  /* If the solist is global across processes, there's no need to
+     refetch it here.  */
+  if (exec_bfd && !gdbarch_has_global_solist (target_gdbarch))
+    {
+      /* Sometimes the platform-specific hook loads initial shared
+        libraries, and sometimes it doesn't.  If it doesn't FROM_TTY will be
+        incorrectly 0 but such solib targets should be fixed anyway.  If we
+        made all the inferior hook methods consistent, this call could be
+        removed.  Call it only after the solib target has been initialized by
+        solib_create_inferior_hook.  */
+
+#ifdef SOLIB_ADD
+      SOLIB_ADD (NULL, 0, target, auto_solib_add);
+#else
+      solib_add (NULL, 0, target, auto_solib_add);
 #endif
     }
 
+  /* If the user sets watchpoints before execution having started,
+     then she gets software watchpoints, because GDB can't know which
+     target will end up being pushed, or if it supports hardware
+     watchpoints or not.  breakpoint_re_set takes care of promoting
+     watchpoints to hardware watchpoints if possible, however, if this
+     new inferior doesn't load shared libraries or we don't pull in
+     symbols from any other source on this target/arch,
+     breakpoint_re_set is never called.  Call it now so that software
+     watchpoints get a chance to be promoted to hardware watchpoints
+     if the now pushed target supports hardware watchpoints.  */
+  breakpoint_re_set ();
+
   observer_notify_inferior_created (target, from_tty);
 }
 
@@ -427,16 +466,14 @@ 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 ();
-      no_shared_libraries (NULL, from_tty);
-      init_wait_for_inferior ();
     }
 }
 
-/* Implement the "run" command. If TBREAK_AT_MAIN is set, then insert
+/* Implement the "run" command.  If TBREAK_AT_MAIN is set, then insert
    a temporary breakpoint at the begining of the main program before
    running the program.  */
 
@@ -444,10 +481,14 @@ 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 ();
 
   kill_if_already_running (from_tty);
+
+  init_wait_for_inferior ();
   clear_breakpoint_hit_counts ();
 
   /* Clean up any leftovers from other runs.  Some other things from
@@ -491,24 +532,21 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
       int async_exec = strip_bg_char (&args);
 
       /* If we get a request for running in the bg but the target
-         doesn't support it, error out. */
+         doesn't support it, error out.  */
       if (async_exec && !target_can_async_p ())
        error (_("Asynchronous execution not supported on this target."));
 
       /* If we don't get a request of running in the bg, then we need
-         to simulate synchronous (fg) execution. */
+         to simulate synchronous (fg) execution.  */
       if (!async_exec && target_can_async_p ())
        {
-         /* Simulate synchronous execution */
+         /* Simulate synchronous execution */
          async_disable_stdin ();
        }
 
-      /* If there were other args, beside '&', process them. */
+      /* If there were other args, beside '&', process them.  */
       if (args)
-       {
-          char *old_args = set_inferior_args (xstrdup (args));
-          xfree (old_args);
-       }
+       set_inferior_args (args);
     }
 
   if (from_tty)
@@ -528,16 +566,33 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
   target_create_inferior (exec_file, get_inferior_args (),
-                         environ_vector (inferior_environ), from_tty);
+                         environ_vector (current_inferior ()->environment),
+                         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);
-}
+  /* Start the target running.  Do not use -1 continuation as it would skip
+     breakpoint right at the entry point.  */
+  proceed (regcache_read_pc (get_current_regcache ()), 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)
@@ -548,8 +603,7 @@ run_command (char *args, int from_tty)
 static void
 run_no_args_command (char *args, int from_tty)
 {
-  char *old_args = set_inferior_args (xstrdup (""));
-  xfree (old_args);
+  set_inferior_args ("");
 }
 \f
 
@@ -572,24 +626,53 @@ start_command (char *args, int from_tty)
 static int
 proceed_thread_callback (struct thread_info *thread, void *arg)
 {
+  /* We go through all threads individually instead of compressing
+     into a single target `resume_all' request, because some threads
+     may be stopped in internal breakpoints/events, or stopped waiting
+     for its turn in the displaced stepping queue (that is, they are
+     running && !executing).  The target side has no idea about why
+     the thread is stopped, so a `resume_all' command would resume too
+     much.  If/when GDB gains a way to tell the target `hold this
+     thread stopped until I say otherwise', then we can optimize
+     this.  */
   if (!is_stopped (thread->ptid))
     return 0;
 
-  context_switch_to (thread->ptid);
+  switch_to_thread (thread->ptid);
   clear_proceed_status ();
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
   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."));
+}
+
+/* If the user is looking at trace frames, any resumption of execution
+   is likely to mix up recorded and live target data.  So simply
+   disallow those commands.  */
+
+void
+ensure_not_tfind_mode (void)
+{
+  if (get_traceframe_number () >= 0)
+    error (_("Cannot execute this command while looking at trace frames."));
+}
+
 void
 continue_1 (int all_threads)
 {
   ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
 
   if (non_stop && all_threads)
     {
       /* Don't error out if the current thread is running, because
-        there may be other stopped threads.  */
+        there may be other stopped threads.  */
       struct cleanup *old_chain;
 
       /* Backup current thread and selected frame.  */
@@ -602,6 +685,7 @@ continue_1 (int all_threads)
     }
   else
     {
+      ensure_valid_thread ();
       ensure_not_running ();
       clear_proceed_status ();
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
@@ -616,20 +700,20 @@ continue_command (char *args, int from_tty)
   int all_threads = 0;
   ERROR_NO_INFERIOR;
 
-  /* Find out whether we must run in the background. */
+  /* Find out whether we must run in the background.  */
   if (args != NULL)
     async_exec = strip_bg_char (&args);
 
   /* If we must run in the background, but the target can't do it,
-     error out. */
+     error out.  */
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
   /* If we are not asked to run in the bg, then prepare to run in the
-     foreground, synchronously. */
+     foreground, synchronously.  */
   if (!async_exec && target_can_async_p ())
     {
-      /* Simulate synchronous execution */
+      /* Simulate synchronous execution */
       async_disable_stdin ();
     }
 
@@ -648,8 +732,8 @@ continue_command (char *args, int from_tty)
     error (_("`-a' is meaningless in all-stop mode."));
 
   if (args != NULL && all_threads)
-    error (_("\
-Can't resume all threads and specify proceed count simultaneously."));
+    error (_("Can't resume all threads and specify "
+            "proceed count simultaneously."));
 
   /* If we have an argument left, set proceed count of breakpoint we
      stopped at.  */
@@ -661,17 +745,17 @@ Can't resume all threads and specify proceed count simultaneously."));
       struct thread_info *tp;
 
       if (non_stop)
-       tp = find_thread_pid (inferior_ptid);
+       tp = find_thread_ptid (inferior_ptid);
       else
        {
          ptid_t last_ptid;
          struct target_waitstatus ws;
 
          get_last_target_status (&last_ptid, &ws);
-         tp = find_thread_pid (last_ptid);
+         tp = find_thread_ptid (last_ptid);
        }
       if (tp != NULL)
-       bs = tp->stop_bpstat;
+       bs = tp->control.stop_bpstat;
 
       while ((stat = bpstat_num (&bs, &num)) != 0)
        if (stat > 0)
@@ -699,6 +783,17 @@ Can't resume all threads and specify proceed count simultaneously."));
   continue_1 (all_threads);
 }
 \f
+/* Record the starting point of a "step" or "next" command.  */
+
+static void
+set_step_frame (void)
+{
+  struct symtab_and_line sal;
+
+  find_frame_sal (get_current_frame (), &sal);
+  set_step_info (get_current_frame (), sal);
+}
+
 /* Step until outside of current statement.  */
 
 static void
@@ -729,7 +824,7 @@ nexti_command (char *count_string, int from_tty)
   step_1 (1, 1, count_string);
 }
 
-static void
+void
 delete_longjmp_breakpoint_cleanup (void *arg)
 {
   int thread = * (int *) arg;
@@ -740,103 +835,81 @@ static void
 step_1 (int skip_subroutines, int single_inst, char *count_string)
 {
   int count = 1;
-  struct frame_info *frame;
   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
   int async_exec = 0;
   int thread = -1;
 
   ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
   ensure_not_running ();
 
   if (count_string)
     async_exec = strip_bg_char (&count_string);
 
   /* If we get a request for running in the bg but the target
-     doesn't support it, error out. */
+     doesn't support it, error out.  */
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
   /* If we don't get a request of running in the bg, then we need
-     to simulate synchronous (fg) execution. */
+     to simulate synchronous (fg) execution.  */
   if (!async_exec && target_can_async_p ())
     {
-      /* Simulate synchronous execution */
+      /* Simulate synchronous execution */
       async_disable_stdin ();
     }
 
   count = count_string ? parse_and_eval_long (count_string) : 1;
 
-  if (!single_inst || skip_subroutines)                /* leave si command alone */
+  if (!single_inst || skip_subroutines)                /* Leave si command alone.  */
     {
+      struct thread_info *tp = inferior_thread ();
+
       if (in_thread_list (inferior_ptid))
        thread = pid_to_thread_id (inferior_ptid);
 
-      set_longjmp_breakpoint ();
+      set_longjmp_breakpoint (tp, get_frame_id (get_current_frame ()));
 
       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 ();
+         struct thread_info *tp;
 
-         frame = get_current_frame ();
-         tp->step_frame_id = get_frame_id (frame);
+         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->control.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);
@@ -853,9 +926,9 @@ struct step_1_continuation_args
 
 /* Called after we are done with one step operation, to check whether
    we need to step again, before we print the prompt and return control
-   to the user. If count is > 1, we will need to do one more call to
-   proceed(), via step_once(). Basically it is like step_once and
-   step_1_continuation are co-recursive. */
+   to the user.  If count is > 1, we will need to do one more call to
+   proceed(), via step_once().  Basically it is like step_once and
+   step_1_continuation are co-recursive.  */
 static void
 step_1_continuation (void *args)
 {
@@ -866,11 +939,12 @@ step_1_continuation (void *args)
       struct thread_info *tp;
 
       tp = inferior_thread ();
-      if (tp->step_multi && tp->stop_step)
+      if (tp->step_multi && tp->control.stop_step)
        {
          /* 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;
@@ -882,18 +956,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;
+  struct frame_info *frame = get_current_frame ();
 
   if (count > 0)
     {
@@ -902,60 +974,82 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
         INFERIOR_PTID thread instead, which is the same thread when
         THREAD is set.  */
       struct thread_info *tp = inferior_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);
+      clear_proceed_status ();
+      set_step_frame ();
 
       if (!single_inst)
        {
-         find_pc_line_pc_range (stop_pc,
-                                &tp->step_range_start, &tp->step_range_end);
+         CORE_ADDR pc;
 
-         /* If we have no line info, switch to stepi mode.  */
-         if (tp->step_range_end == 0 && step_stop_if_no_debug)
+         /* Step at an inlined function behaves like "down".  */
+         if (!skip_subroutines && !single_inst
+             && inline_skipped_frames (inferior_ptid))
            {
-             tp->step_range_start = tp->step_range_end = 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 ();
+             return;
            }
-         else if (tp->step_range_end == 0)
+
+         pc = get_frame_pc (frame);
+         find_pc_line_pc_range (pc,
+                                &tp->control.step_range_start,
+                                &tp->control.step_range_end);
+
+         /* If we have no line info, switch to stepi mode.  */
+         if (tp->control.step_range_end == 0 && step_stop_if_no_debug)
+           tp->control.step_range_start = tp->control.step_range_end = 1;
+         else if (tp->control.step_range_end == 0)
            {
              char *name;
-             if (find_pc_partial_function (stop_pc, &name,
-                                           &tp->step_range_start,
-                                           &tp->step_range_end) == 0)
+
+             if (find_pc_partial_function (pc, &name,
+                                           &tp->control.step_range_start,
+                                           &tp->control.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);
+             printf_filtered (_("Single stepping until exit from function %s,"
+                                "\nwhich has no line number information.\n"),
+                              name);
            }
        }
       else
        {
          /* Say we are stepping, but stop after one insn whatever it does.  */
-         tp->step_range_start = tp->step_range_end = 1;
+         tp->control.step_range_start = tp->control.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;
+           tp->control.step_over_calls = STEP_OVER_NONE;
        }
 
       if (skip_subroutines)
-       tp->step_over_calls = STEP_OVER_ALL;
+       tp->control.step_over_calls = STEP_OVER_ALL;
 
-      inferior_thread ()->step_multi = (count > 1);
+      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 (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);
+       }
     }
 }
 
@@ -965,6 +1059,7 @@ which has no line number information.\n"), name);
 static void
 jump_command (char *arg, int from_tty)
 {
+  struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR addr;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
@@ -973,14 +1068,16 @@ jump_command (char *arg, int from_tty)
   int async_exec = 0;
 
   ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
   ensure_not_running ();
 
-  /* Find out whether we must run in the background. */
+  /* Find out whether we must run in the background.  */
   if (arg != NULL)
     async_exec = strip_bg_char (&arg);
 
   /* If we must run in the background, but the target can't do it,
-     error out. */
+     error out.  */
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
@@ -999,14 +1096,14 @@ jump_command (char *arg, int from_tty)
   if (sal.symtab == 0 && sal.pc == 0)
     error (_("No source file has been specified."));
 
-  resolve_sal_pc (&sal);       /* May error out */
+  resolve_sal_pc (&sal);       /* May error out */
 
-  /* See if we are trying to jump to another function. */
+  /* See if we are trying to jump to another function.  */
   fn = get_frame_function (get_current_frame ());
   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."));
@@ -1020,7 +1117,8 @@ 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 */
@@ -1033,15 +1131,15 @@ jump_command (char *arg, int from_tty)
   if (from_tty)
     {
       printf_filtered (_("Continuing at "));
-      fputs_filtered (paddress (addr), gdb_stdout);
+      fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
       printf_filtered (".\n");
     }
 
   /* If we are not asked to run in the bg, then prepare to run in the
-     foreground, synchronously. */
+     foreground, synchronously.  */
   if (!async_exec && target_can_async_p ())
     {
-      /* Simulate synchronous execution */
+      /* Simulate synchronous execution */
       async_disable_stdin ();
     }
 
@@ -1050,12 +1148,12 @@ jump_command (char *arg, int from_tty)
 }
 \f
 
-/* Go to line or address in current procedure */
+/* Go to line or address in current procedure */
 static void
 go_command (char *line_no, int from_tty)
 {
   if (line_no == (char *) NULL || !*line_no)
-    printf_filtered (GO_USAGE);
+    printf_filtered (_("Usage: go <location>\n"));
   else
     {
       tbreak_command (line_no, from_tty);
@@ -1074,6 +1172,8 @@ signal_command (char *signum_exp, int from_tty)
 
   dont_repeat ();              /* Too dangerous.  */
   ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
@@ -1122,11 +1222,17 @@ 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);
+}
+
+/* A continuation callback for until_next_command.  */
+
+static void
+until_next_continuation (void *arg)
+{
+  struct thread_info *tp = arg;
+
+  delete_longjmp_breakpoint (tp->num);
 }
 
 /* Proceed until we reach a different source line with pc greater than
@@ -1145,16 +1251,19 @@ until_next_command (int from_tty)
   struct symbol *func;
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
+  int thread = tp->num;
+  struct cleanup *old_chain;
 
   clear_proceed_status ();
+  set_step_frame ();
 
   frame = get_current_frame ();
 
   /* Step until either exited from this function or greater
      than the current line (if in symbolic section) or pc (if
-     not). */
+     not).  */
 
-  pc = read_pc ();
+  pc = get_frame_pc (frame);
   func = find_pc_function (pc);
 
   if (!func)
@@ -1164,23 +1273,33 @@ until_next_command (int from_tty)
       if (msymbol == NULL)
        error (_("Execution is not within a known function."));
 
-      tp->step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
-      tp->step_range_end = pc;
+      tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
+      tp->control.step_range_end = pc;
     }
   else
     {
       sal = find_pc_line (pc, 0);
 
-      tp->step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
-      tp->step_range_end = sal.end;
+      tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+      tp->control.step_range_end = sal.end;
     }
 
-  tp->step_over_calls = STEP_OVER_ALL;
-  tp->step_frame_id = get_frame_id (frame);
+  tp->control.step_over_calls = STEP_OVER_ALL;
 
   tp->step_multi = 0;          /* Only one call to proceed */
 
+  set_longjmp_breakpoint (tp, get_frame_id (frame));
+  old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+
+  if (target_can_async_p () && is_running (inferior_ptid))
+    {
+      discard_cleanups (old_chain);
+      add_continuation (tp, until_next_continuation, tp, NULL);
+    }
+  else
+    do_cleanups (old_chain);
 }
 
 static void
@@ -1188,23 +1307,25 @@ until_command (char *arg, int from_tty)
 {
   int async_exec = 0;
 
-  if (!target_has_execution)
-    error (_("The program is not running."));
+  ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
+  ensure_not_running ();
 
-  /* Find out whether we must run in the background. */
+  /* Find out whether we must run in the background.  */
   if (arg != NULL)
     async_exec = strip_bg_char (&arg);
 
   /* If we must run in the background, but the target can't do it,
-     error out. */
+     error out.  */
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
   /* If we are not asked to run in the bg, then prepare to run in the
-     foreground, synchronously. */
+     foreground, synchronously.  */
   if (!async_exec && target_can_async_p ())
     {
-      /* Simulate synchronous execution */
+      /* Simulate synchronous execution */
       async_disable_stdin ();
     }
 
@@ -1219,8 +1340,10 @@ advance_command (char *arg, int from_tty)
 {
   int async_exec = 0;
 
-  if (!target_has_execution)
-    error (_("The program is not running."));
+  ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
+  ensure_not_running ();
 
   if (arg == NULL)
     error_no_arg (_("a location"));
@@ -1250,7 +1373,7 @@ advance_command (char *arg, int from_tty)
 static void
 print_return_value (struct type *func_type, struct type *value_type)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
+  struct gdbarch *gdbarch = get_regcache_arch (stop_registers);
   struct cleanup *old_chain;
   struct ui_stream *stb;
   struct value *value;
@@ -1284,6 +1407,8 @@ print_return_value (struct type *func_type, struct type *value_type)
 
   if (value)
     {
+      struct value_print_options opts;
+
       /* Print it.  */
       stb = ui_out_stream_new (uiout);
       old_chain = make_cleanup_ui_out_stream_delete (stb);
@@ -1291,7 +1416,8 @@ print_return_value (struct type *func_type, struct type *value_type)
       ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
                        record_latest_value (value));
       ui_out_text (uiout, " = ");
-      value_print (value, stb->stream, 0, Val_no_prettyprint);
+      get_raw_print_options (&opts);
+      value_print (value, stb->stream, &opts);
       ui_out_field_stream (uiout, "return-value", stb);
       ui_out_text (uiout, "\n");
       do_cleanups (old_chain);
@@ -1311,7 +1437,7 @@ print_return_value (struct type *func_type, struct type *value_type)
    impossible to do all the stuff as part of the finish_command
    function itself.  The only chance we have to complete this command
    is in fetch_inferior_event, which is called by the event loop as
-   soon as it detects that the target has stopped. This function is
+   soon as it detects that the target has stopped.  This function is
    called via the cmd_continuation pointer.  */
 
 struct finish_command_continuation_args
@@ -1324,13 +1450,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->control.stop_bpstat;
+    }
 
   if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
       && a->function != NULL)
@@ -1343,45 +1472,156 @@ finish_command_continuation (void *arg)
                        _("finish_command: function has no target type"));
 
       if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
-       print_return_value (SYMBOL_TYPE (a->function), value_type);
+       {
+         volatile struct gdb_exception ex;
+
+         TRY_CATCH (ex, RETURN_MASK_ALL)
+           {
+             /* print_return_value can throw an exception in some
+                circumstances.  We need to catch this so that we still
+                delete the breakpoint.  */
+             print_return_value (SYMBOL_TYPE (a->function), value_type);
+           }
+         if (ex.reason < 0)
+           exception_print (gdb_stdout, ex);
+       }
     }
 
   /* 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->control.proceed_to_finish)
+    observer_notify_normal_stop (bs, 1 /* print frame */);
   delete_breakpoint (a->breakpoint);
+  delete_longjmp_breakpoint (inferior_thread ()->num);
 }
 
 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);
 }
 
+/* finish_backward -- helper function for finish_command.  */
+
+static void
+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 ());
+
+  if (find_pc_partial_function (pc, NULL, &func_addr, NULL) == 0)
+    internal_error (__FILE__, __LINE__,
+                   _("Finish: couldn't find function."));
+
+  sal = find_pc_line (func_addr, 0);
+
+  /* We don't need a return value.  */
+  tp->control.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 != pc)
+    {
+      struct frame_info *frame = get_selected_frame (NULL);
+      struct gdbarch *gdbarch = get_frame_arch (frame);
+
+      /* 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.  */
+      make_breakpoint_silent (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->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.  */
+      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.  */
+
+static void
+finish_forward (struct symbol *function, struct frame_info *frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct symtab_and_line sal;
+  struct thread_info *tp = inferior_thread ();
+  struct breakpoint *breakpoint;
+  struct cleanup *old_chain;
+  struct finish_command_continuation_args *cargs;
+  int thread = tp->num;
+
+  sal = find_pc_line (get_frame_pc (frame), 0);
+  sal.pc = get_frame_pc (frame);
+
+  breakpoint = set_momentary_breakpoint (gdbarch, sal,
+                                        get_stack_frame_id (frame),
+                                         bp_finish);
+
+  old_chain = make_cleanup_delete_breakpoint (breakpoint);
+
+  set_longjmp_breakpoint (tp, get_frame_id (frame));
+  make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+
+  /* We want stop_registers, please...  */
+  tp->control.proceed_to_finish = 1;
+  cargs = xmalloc (sizeof (*cargs));
+
+  cargs->breakpoint = breakpoint;
+  cargs->function = function;
+  add_continuation (tp, finish_command_continuation, cargs,
+                    finish_command_continuation_free_arg);
+  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+
+  discard_cleanups (old_chain);
+  if (!target_can_async_p ())
+    do_all_continuations ();
+}
+
 /* "finish": Set a temporary breakpoint at the place the selected
    frame will return to, then continue.  */
 
 static void
 finish_command (char *arg, int from_tty)
 {
-  struct symtab_and_line sal;
   struct frame_info *frame;
   struct symbol *function;
-  struct breakpoint *breakpoint;
-  struct cleanup *old_chain;
-  struct finish_command_continuation_args *cargs;
-  struct thread_info *tp;
 
   int async_exec = 0;
 
+  ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
+  ensure_not_running ();
+
   /* Find out whether we must run in the background.  */
   if (arg != NULL)
     async_exec = strip_bg_char (&arg);
@@ -1391,6 +1631,10 @@ 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 ())
@@ -1401,23 +1645,44 @@ finish_command (char *arg, int from_tty)
 
   if (arg)
     error (_("The \"finish\" command does not take any arguments."));
-  if (!target_has_execution)
-    error (_("The program is not running."));
 
   frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
 
-  tp = inferior_thread ();
-
   clear_proceed_status ();
 
-  sal = find_pc_line (get_frame_pc (frame), 0);
-  sal.pc = get_frame_pc (frame);
+  /* Finishing from an inline frame is completely different.  We don't
+     try to show the "return value" - no way to locate it.  So we do
+     not need a completion.  */
+  if (get_frame_type (get_selected_frame (_("No selected frame.")))
+      == INLINE_FRAME)
+    {
+      /* Claim we are stepping in the calling frame.  An empty step
+        range means that we will stop once we aren't in a function
+        called by that frame.  We don't use the magic "1" value for
+        step_range_end, because then infrun will think this is nexti,
+        and not step over the rest of this inlined function call.  */
+      struct thread_info *tp = inferior_thread ();
+      struct symtab_and_line empty_sal;
 
-  breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish);
+      init_sal (&empty_sal);
+      set_step_info (frame, empty_sal);
+      tp->control.step_range_start = get_frame_pc (frame);
+      tp->control.step_range_end = tp->control.step_range_start;
+      tp->control.step_over_calls = STEP_OVER_ALL;
 
-  old_chain = make_cleanup_delete_breakpoint (breakpoint);
+      /* Print info on the selected frame, including level number but not
+        source.  */
+      if (from_tty)
+       {
+         printf_filtered (_("Run till exit from "));
+         print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+       }
+
+      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+      return;
+    }
 
   /* Find the function we will return from.  */
 
@@ -1427,25 +1692,18 @@ finish_command (char *arg, int from_tty)
      source.  */
   if (from_tty)
     {
-      printf_filtered (_("Run till exit from "));
+      if (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);
     }
 
-  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));
-
-  cargs->breakpoint = breakpoint;
-  cargs->function = function;
-  add_continuation (finish_command_continuation, cargs,
-                   finish_command_continuation_free_arg);
-
-  discard_cleanups (old_chain);
-  if (!target_can_async_p ())
-    do_all_continuations ();
+  if (execution_direction == EXEC_REVERSE)
+    finish_backward (function);
+  else
+    finish_forward (function, frame);
 }
 \f
 
@@ -1468,6 +1726,7 @@ program_info (char *args, int from_tty)
   else
     {
       struct target_waitstatus ws;
+
       get_last_target_status (&ptid, &ws);
     }
 
@@ -1476,14 +1735,14 @@ program_info (char *args, int from_tty)
   else if (is_running (ptid))
     error (_("Selected thread is running."));
 
-  tp = find_thread_pid (ptid);
-  bs = tp->stop_bpstat;
+  tp = find_thread_ptid (ptid);
+  bs = tp->control.stop_bpstat;
   stat = bpstat_num (&bs, &num);
 
   target_files_info ();
   printf_filtered (_("Program stopped at %s.\n"),
-                  hex_string ((unsigned long) stop_pc));
-  if (tp->stop_step)
+                  paddress (target_gdbarch, stop_pc));
+  if (tp->control.stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
     {
@@ -1493,25 +1752,25 @@ program_info (char *args, int from_tty)
        {
          if (stat < 0)
            {
-             printf_filtered (_("\
-It stopped at a breakpoint that has since been deleted.\n"));
+             printf_filtered (_("It stopped at a breakpoint "
+                                "that has since been deleted.\n"));
            }
          else
            printf_filtered (_("It stopped at breakpoint %d.\n"), num);
          stat = bpstat_num (&bs, &num);
        }
     }
-  else if (tp->stop_signal != TARGET_SIGNAL_0)
+  else if (tp->suspend.stop_signal != TARGET_SIGNAL_0)
     {
       printf_filtered (_("It stopped with signal %s, %s.\n"),
-                      target_signal_to_name (tp->stop_signal),
-                      target_signal_to_string (tp->stop_signal));
+                      target_signal_to_name (tp->suspend.stop_signal),
+                      target_signal_to_string (tp->suspend.stop_signal));
     }
 
   if (!from_tty)
     {
-      printf_filtered (_("\
-Type \"info stack\" or \"info registers\" for more information.\n"));
+      printf_filtered (_("Type \"info stack\" or \"info "
+                        "registers\" for more information.\n"));
     }
 }
 \f
@@ -1520,7 +1779,8 @@ environment_info (char *var, int from_tty)
 {
   if (var)
     {
-      char *val = get_in_environ (inferior_environ, var);
+      char *val = get_in_environ (current_inferior ()->environment, var);
+
       if (val)
        {
          puts_filtered (var);
@@ -1537,7 +1797,8 @@ environment_info (char *var, int from_tty)
     }
   else
     {
-      char **vector = environ_vector (inferior_environ);
+      char **vector = environ_vector (current_inferior ()->environment);
+
       while (*vector)
        {
          puts_filtered (*vector++);
@@ -1555,7 +1816,7 @@ set_environment_command (char *arg, int from_tty)
   if (arg == 0)
     error_no_arg (_("environment variable and value"));
 
-  /* Find seperation between variable name and value */
+  /* Find seperation between variable name and value */
   p = (char *) strchr (arg, '=');
   val = (char *) strchr (arg, ' ');
 
@@ -1563,7 +1824,7 @@ set_environment_command (char *arg, int from_tty)
     {
       /* We have both a space and an equals.  If the space is before the
          equals, walk forward over the spaces til we see a nonspace 
-         (possibly the equals). */
+         (possibly the equals).  */
       if (p > val)
        while (*val == ' ')
          val++;
@@ -1583,11 +1844,11 @@ set_environment_command (char *arg, int from_tty)
     {
       nullset = 1;
       if (p == 0)
-       p = arg + strlen (arg); /* So that savestring below will work */
+       p = arg + strlen (arg); /* So that savestring below will work */
     }
   else
     {
-      /* Not setting variable value to null */
+      /* Not setting variable value to null */
       val = p + 1;
       while (*val == ' ' || *val == '\t')
        val++;
@@ -1599,13 +1860,13 @@ set_environment_command (char *arg, int from_tty)
   var = savestring (arg, p - arg);
   if (nullset)
     {
-      printf_filtered (_("\
-Setting environment variable \"%s\" to null value.\n"),
+      printf_filtered (_("Setting environment variable "
+                        "\"%s\" to null value.\n"),
                       var);
-      set_in_environ (inferior_environ, var, "");
+      set_in_environ (current_inferior ()->environment, var, "");
     }
   else
-    set_in_environ (inferior_environ, var, val);
+    set_in_environ (current_inferior ()->environment, var, val);
   xfree (var);
 }
 
@@ -1618,15 +1879,15 @@ unset_environment_command (char *var, int from_tty)
          Ask for confirmation if reading from the terminal.  */
       if (!from_tty || query (_("Delete all environment variables? ")))
        {
-         free_environ (inferior_environ);
-         inferior_environ = make_environ ();
+         free_environ (current_inferior ()->environment);
+         current_inferior ()->environment = make_environ ();
        }
     }
   else
-    unset_in_environ (inferior_environ, var);
+    unset_in_environ (current_inferior ()->environment, var);
 }
 
-/* Handle the execution path (PATH variable) */
+/* Handle the execution path (PATH variable) */
 
 static const char path_var_name[] = "PATH";
 
@@ -1634,7 +1895,8 @@ static void
 path_info (char *args, int from_tty)
 {
   puts_filtered ("Executable and object file path: ");
-  puts_filtered (get_in_environ (inferior_environ, path_var_name));
+  puts_filtered (get_in_environ (current_inferior ()->environment,
+                                path_var_name));
   puts_filtered ("\n");
 }
 
@@ -1645,21 +1907,22 @@ path_command (char *dirname, int from_tty)
 {
   char *exec_path;
   char *env;
+
   dont_repeat ();
-  env = get_in_environ (inferior_environ, path_var_name);
-  /* Can be null if path is not set */
+  env = get_in_environ (current_inferior ()->environment, path_var_name);
+  /* Can be null if path is not set */
   if (!env)
     env = "";
   exec_path = xstrdup (env);
   mod_path (dirname, &exec_path);
-  set_in_environ (inferior_environ, path_var_name, exec_path);
+  set_in_environ (current_inferior ()->environment, path_var_name, exec_path);
   xfree (exec_path);
   if (from_tty)
     path_info ((char *) NULL, from_tty);
 }
 \f
 
-/* Print out the machine register regnum. If regnum is -1, print all
+/* Print out the machine register regnum.  If regnum is -1, print all
    registers (print_all == 1) or all non-float and non-vector
    registers (print_all == 0).
 
@@ -1679,10 +1942,12 @@ default_print_registers_info (struct gdbarch *gdbarch,
   int i;
   const int numregs = gdbarch_num_regs (gdbarch)
                      + gdbarch_num_pseudo_regs (gdbarch);
-  gdb_byte buffer[MAX_REGISTER_SIZE];
 
   for (i = 0; i < numregs; i++)
     {
+      struct type *regtype;
+      struct value *val;
+
       /* Decide between printing all regs, non-float / vector regs, or
          specific reg.  */
       if (regnum == -1)
@@ -1714,8 +1979,11 @@ default_print_registers_info (struct gdbarch *gdbarch,
       print_spaces_filtered (15 - strlen (gdbarch_register_name
                                          (gdbarch, i)), file);
 
+      regtype = register_type (gdbarch, i);
+      val = allocate_value (regtype);
+
       /* Get the data in raw format.  */
-      if (! frame_register_read (frame, i, buffer))
+      if (! frame_register_read (frame, i, value_contents_raw (val)))
        {
          fprintf_filtered (file, "*value not available*\n");
          continue;
@@ -1723,38 +1991,56 @@ default_print_registers_info (struct gdbarch *gdbarch,
 
       /* If virtual format is floating, print it that way, and in raw
          hex.  */
-      if (TYPE_CODE (register_type (gdbarch, i)) == TYPE_CODE_FLT
-         || TYPE_CODE (register_type (gdbarch, i)) == TYPE_CODE_DECFLOAT)
+      if (TYPE_CODE (regtype) == TYPE_CODE_FLT
+         || TYPE_CODE (regtype) == TYPE_CODE_DECFLOAT)
        {
          int j;
+         struct value_print_options opts;
+         const gdb_byte *valaddr = value_contents_for_printing (val);
 
-         val_print (register_type (gdbarch, i), buffer, 0, 0,
-                    file, 0, 1, 0, Val_pretty_default, current_language);
+         get_user_print_options (&opts);
+         opts.deref_ref = 1;
+
+         val_print (regtype,
+                    value_contents_for_printing (val),
+                    value_embedded_offset (val), 0,
+                    file, 0, val, &opts, current_language);
 
          fprintf_filtered (file, "\t(raw 0x");
          for (j = 0; j < register_size (gdbarch, i); j++)
            {
              int idx;
+
              if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
                idx = j;
              else
                idx = register_size (gdbarch, i) - 1 - j;
-             fprintf_filtered (file, "%02x", (unsigned char) buffer[idx]);
+             fprintf_filtered (file, "%02x", (unsigned char) valaddr[idx]);
            }
          fprintf_filtered (file, ")");
        }
       else
        {
+         struct value_print_options opts;
+
          /* Print the register in hex.  */
-         val_print (register_type (gdbarch, i), buffer, 0, 0,
-                    file, 'x', 1, 0, Val_pretty_default, current_language);
+         get_formatted_print_options (&opts, 'x');
+         opts.deref_ref = 1;
+         val_print (regtype,
+                    value_contents_for_printing (val),
+                    value_embedded_offset (val), 0,
+                    file, 0, val, &opts, current_language);
           /* If not a vector register, print it also according to its
              natural format.  */
-         if (TYPE_VECTOR (register_type (gdbarch, i)) == 0)
+         if (TYPE_VECTOR (regtype) == 0)
            {
+             get_user_print_options (&opts);
+             opts.deref_ref = 1;
              fprintf_filtered (file, "\t");
-             val_print (register_type (gdbarch, i), buffer, 0, 0,
-                        file, 0, 1, 0, Val_pretty_default, current_language);
+             val_print (regtype,
+                        value_contents_for_printing (val),
+                        value_embedded_offset (val), 0,
+                        file, 0, val, &opts, current_language);
            }
        }
 
@@ -1767,8 +2053,6 @@ registers_info (char *addr_exp, int fpregs)
 {
   struct frame_info *frame;
   struct gdbarch *gdbarch;
-  int regnum, numregs;
-  char *end;
 
   if (!target_has_registers)
     error (_("The program has no registers now."));
@@ -1812,6 +2096,7 @@ registers_info (char *addr_exp, int fpregs)
       /* A register name?  */
       {
        int regnum = user_reg_map_name_to_regnum (gdbarch, start, end - start);
+
        if (regnum >= 0)
          {
            /* User registers lie completely outside of the range of
@@ -1820,12 +2105,16 @@ registers_info (char *addr_exp, int fpregs)
            if (regnum >= gdbarch_num_regs (gdbarch)
                          + gdbarch_num_pseudo_regs (gdbarch))
              {
+               struct value_print_options opts;
                struct value *val = value_of_user_reg (regnum, frame);
 
                printf_filtered ("%s: ", start);
-               print_scalar_formatted (value_contents (val),
-                                       check_typedef (value_type (val)),
-                                       'x', 0, gdb_stdout);
+               get_formatted_print_options (&opts, 'x');
+               val_print_scalar_formatted (check_typedef (value_type (val)),
+                                           value_contents_for_printing (val),
+                                           value_embedded_offset (val),
+                                           val,
+                                           &opts, 0, gdb_stdout);
                printf_filtered ("\n");
              }
            else
@@ -1835,24 +2124,10 @@ 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;
+
        for (group = reggroup_next (gdbarch, NULL);
             group != NULL;
             group = reggroup_next (gdbarch, group))
@@ -1866,6 +2141,7 @@ registers_info (char *addr_exp, int fpregs)
        if (group != NULL)
          {
            int regnum;
+
            for (regnum = 0;
                 regnum < gdbarch_num_regs (gdbarch)
                          + gdbarch_num_pseudo_regs (gdbarch);
@@ -1898,9 +2174,11 @@ nofp_registers_info (char *addr_exp, int from_tty)
 }
 
 static void
-print_vector_info (struct gdbarch *gdbarch, struct ui_file *file,
+print_vector_info (struct ui_file *file,
                   struct frame_info *frame, const char *args)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+
   if (gdbarch_print_vector_info_p (gdbarch))
     gdbarch_print_vector_info (gdbarch, file, frame, args);
   else
@@ -1930,10 +2208,82 @@ vector_info (char *args, int from_tty)
   if (!target_has_registers)
     error (_("The program has no registers now."));
 
-  print_vector_info (current_gdbarch, gdb_stdout,
-                    get_selected_frame (NULL), args);
+  print_vector_info (gdb_stdout, get_selected_frame (NULL), args);
 }
 \f
+/* Kill the inferior process.  Make us have no inferior.  */
+
+static void
+kill_command (char *arg, int from_tty)
+{
+  /* FIXME:  This should not really be inferior_ptid (or target_has_execution).
+     It should be a distinct flag that indicates that a target is active, cuz
+     some targets don't have processes!  */
+
+  if (ptid_equal (inferior_ptid, null_ptid))
+    error (_("The program is not being run."));
+  if (!query (_("Kill the program being debugged? ")))
+    error (_("Not confirmed."));
+  target_kill ();
+
+  /* If we still have other inferiors to debug, then don't mess with
+     with their threads.  */
+  if (!have_inferiors ())
+    {
+      init_thread_list ();             /* Destroy thread info.  */
+
+      /* Killing off the inferior can leave us with a core file.  If
+        so, print the state we are left in.  */
+      if (target_has_stack)
+       {
+         printf_filtered (_("In %s,\n"), target_longname);
+         print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+       }
+    }
+  bfd_cache_close_all ();
+}
+
+/* Used in `attach&' command.  ARG is a point to an integer
+   representing a process id.  Proceed threads of this process iff
+   they stopped due to debugger request, and when they did, they
+   reported a clean stop (TARGET_SIGNAL_0).  Do not proceed threads
+   that have been explicitly been told to stop.  */
+
+static int
+proceed_after_attach_callback (struct thread_info *thread,
+                              void *arg)
+{
+  int pid = * (int *) arg;
+
+  if (ptid_get_pid (thread->ptid) == pid
+      && !is_exited (thread->ptid)
+      && !is_executing (thread->ptid)
+      && !thread->stop_requested
+      && thread->suspend.stop_signal == TARGET_SIGNAL_0)
+    {
+      switch_to_thread (thread->ptid);
+      clear_proceed_status ();
+      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+    }
+
+  return 0;
+}
+
+static void
+proceed_after_attach (int pid)
+{
+  /* Don't error out if the current thread is running, because
+     there may be other stopped threads.  */
+  struct cleanup *old_chain;
+
+  /* Backup current thread and selected frame.  */
+  old_chain = make_cleanup_restore_current_thread ();
+
+  iterate_over_threads (proceed_after_attach_callback, &pid);
+
+  /* Restore selected ptid.  */
+  do_cleanups (old_chain);
+}
 
 /*
  * TODO:
@@ -1945,8 +2295,7 @@ vector_info (char *args, int from_tty)
  * This only needs to be done if we are attaching to a process.
  */
 
-/*
-   attach_command --
+/* attach_command --
    takes a program started up outside of gdb and ``attaches'' to it.
    This stops it cold in its tracks and allows us to start debugging it.
    and wait for the trace-trap that results from attaching.  */
@@ -1956,8 +2305,10 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 {
   char *exec_file;
   char *full_exec_path = NULL;
+  struct inferior *inferior;
 
-  stop_soon = NO_STOP_QUIETLY;
+  inferior = current_inferior ();
+  inferior->control.stop_soon = NO_STOP_QUIETLY;
 
   /* If no exec file is yet known, try to determine it from the
      process itself.  */
@@ -1973,10 +2324,10 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 
             Attempt to qualify the filename against the source path.
             (If that fails, we'll just fall back on the original
-            filename.  Not much more we can do...)
-          */
+            filename.  Not much more we can do...)  */
+
          if (!source_full_path_of (exec_file, &full_exec_path))
-           full_exec_path = savestring (exec_file, strlen (exec_file));
+           full_exec_path = xstrdup (exec_file);
 
          exec_file_attach (full_exec_path, from_tty);
          symbol_file_add_main (full_exec_path, from_tty);
@@ -1997,11 +2348,44 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
   target_terminal_inferior ();
 
   if (async_exec)
-    proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+    {
+      /* The user requested an `attach&', so be sure to leave threads
+        that didn't get a signal running.  */
+
+      /* Immediatelly resume all suspended threads of this inferior,
+        and this inferior only.  This should have no effect on
+        already running threads.  If a thread has been stopped with a
+        signal, leave it be.  */
+      if (non_stop)
+       proceed_after_attach (inferior->pid);
+      else
+       {
+         if (inferior_thread ()->suspend.stop_signal == TARGET_SIGNAL_0)
+           {
+             clear_proceed_status ();
+             proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+           }
+       }
+    }
   else
     {
+      /* The user requested a plain `attach', so be sure to leave
+        the inferior stopped.  */
+
       if (target_can_async_p ())
        async_enable_stdin ();
+
+      /* At least the current thread is already stopped.  */
+
+      /* In all-stop, by definition, all threads have to be already
+        stopped at this point.  In non-stop, however, although the
+        selected thread is stopped, others may still be executing.
+        Be sure to explicitly stop all threads of the process.  This
+        should have no effect on already stopped threads.  */
+      if (non_stop)
+       target_stop (pid_to_ptid (inferior->pid));
+
+      /* Tell the user/frontend where we're stopped.  */
       normal_stop ();
       if (deprecated_attach_hook)
        deprecated_attach_hook ();
@@ -2019,6 +2403,7 @@ static void
 attach_command_continuation (void *args)
 {
   struct attach_command_continuation_args *a = args;
+
   attach_command_post_wait (a->args, a->from_tty, a->async_exec);
 }
 
@@ -2026,6 +2411,7 @@ static void
 attach_command_continuation_free_args (void *args)
 {
   struct attach_command_continuation_args *a = args;
+
   xfree (a->args);
   xfree (a);
 }
@@ -2033,15 +2419,18 @@ attach_command_continuation_free_args (void *args)
 void
 attach_command (char *args, int from_tty)
 {
-  char *exec_file;
-  char *full_exec_path = NULL;
   int async_exec = 0;
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
 
   dont_repeat ();              /* Not for the faint of heart */
 
-  if (target_has_execution)
+  if (gdbarch_has_global_solist (target_gdbarch))
+    /* Don't complain if all processes share the same symbol
+       space.  */
+    ;
+  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."));
@@ -2059,7 +2448,7 @@ attach_command (char *args, int from_tty)
       async_exec = strip_bg_char (&args);
 
       /* If we get a request for running in the bg but the target
-         doesn't support it, error out. */
+         doesn't support it, error out.  */
       if (async_exec && !target_can_async_p ())
        error (_("Asynchronous execution not supported on this target."));
     }
@@ -2068,8 +2457,9 @@ attach_command (char *args, int from_tty)
      to simulate synchronous (fg) execution.  */
   if (!async_exec && target_can_async_p ())
     {
-      /* Simulate synchronous execution */
+      /* Simulate synchronous execution */
       async_disable_stdin ();
+      make_cleanup ((make_cleanup_ftype *)async_enable_stdin, NULL);
     }
 
   target_attach (args, from_tty);
@@ -2083,16 +2473,33 @@ attach_command (char *args, int from_tty)
   init_wait_for_inferior ();
   clear_proceed_status ();
 
+  if (non_stop)
+    {
+      /* If we find that the current thread isn't stopped, explicitly
+        do so now, because we're going to install breakpoints and
+        poke at memory.  */
+
+      if (async_exec)
+       /* The user requested an `attach&'; stop just one thread.  */
+       target_stop (inferior_ptid);
+      else
+       /* The user requested an `attach', so stop all threads of this
+          inferior.  */
+       target_stop (pid_to_ptid (ptid_get_pid (inferior_ptid)));
+    }
+
   /* Some system don't generate traps when attaching to inferior.
      E.g. Mach 3 or GNU hurd.  */
   if (!target_attach_no_wait)
     {
-      /* Careful here. See comments in inferior.h.  Basically some
+      struct inferior *inferior = current_inferior ();
+
+      /* Careful here.  See comments in inferior.h.  Basically some
         OSes don't ignore SIGSTOPs on continue requests anymore.  We
         need a way for handle_inferior_event to reset the stop_signal
         variable after an attach, and this is what
         STOP_QUIETLY_NO_SIGSTOP is for.  */
-      stop_soon = STOP_QUIETLY_NO_SIGSTOP;
+      inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
 
       if (target_can_async_p ())
        {
@@ -2103,8 +2510,9 @@ attach_command (char *args, int from_tty)
          a->args = xstrdup (args);
          a->from_tty = from_tty;
          a->async_exec = async_exec;
-         add_continuation (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;
        }
 
@@ -2112,6 +2520,73 @@ attach_command (char *args, int from_tty)
     }
 
   attach_command_post_wait (args, from_tty, async_exec);
+  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->control.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);
 }
 
 /*
@@ -2125,13 +2600,28 @@ 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."));
+
+  disconnect_tracing (from_tty);
+
   target_detach (args, from_tty);
-  no_shared_libraries (NULL, from_tty);
-  init_thread_list ();
+
+  /* If the solist is global across inferiors, don't clear it when we
+     detach from a single inferior.  */
+  if (!gdbarch_has_global_solist (target_gdbarch))
+    no_shared_libraries (NULL, from_tty);
+
+  /* If we still have inferiors to debug, then don't mess with their
+     threads.  */
+  if (!have_inferiors ())
+    init_thread_list ();
+
   if (deprecated_detach_hook)
     deprecated_detach_hook ();
 }
@@ -2147,7 +2637,7 @@ detach_command (char *args, int from_tty)
 static void
 disconnect_command (char *args, int from_tty)
 {
-  dont_repeat ();              /* Not for the faint of heart */
+  dont_repeat ();              /* Not for the faint of heart */
   target_disconnect (args, from_tty);
   no_shared_libraries (NULL, from_tty);
   init_thread_list ();
@@ -2159,11 +2649,21 @@ void
 interrupt_target_1 (int all_threads)
 {
   ptid_t ptid;
+
   if (all_threads)
     ptid = minus_one_ptid;
   else
     ptid = inferior_ptid;
   target_stop (ptid);
+
+  /* Tag the thread as having been explicitly requested to stop, so
+     other parts of gdb know not to resume this thread automatically,
+     if it was stopped due to an internal event.  Limit this to
+     non-stop mode, as when debugging a multi-threaded application in
+     all-stop mode, we will only get one stop event --- it's undefined
+     which thread will report the event.  */
+  if (non_stop)
+    set_stop_requested (ptid, 1);
 }
 
 /* Stop the execution of the target while running in async mode, in
@@ -2179,7 +2679,7 @@ interrupt_target_command (char *args, int from_tty)
     {
       int all_threads = 0;
 
-      dont_repeat ();          /* Not for the faint of heart */
+      dont_repeat ();          /* Not for the faint of heart */
 
       if (args != NULL
          && strncmp (args, "-a", sizeof ("-a") - 1) == 0)
@@ -2193,9 +2693,11 @@ interrupt_target_command (char *args, int from_tty)
 }
 
 static void
-print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
+print_float_info (struct ui_file *file,
                  struct frame_info *frame, const char *args)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+
   if (gdbarch_print_float_info_p (gdbarch))
     gdbarch_print_float_info (gdbarch, file, frame, args);
   else
@@ -2215,8 +2717,8 @@ print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
            }
        }
       if (!printed_something)
-       fprintf_filtered (file, "\
-No floating-point info available for this processor.\n");
+       fprintf_filtered (file, "No floating-point info "
+                         "available for this processor.\n");
     }
 }
 
@@ -2226,15 +2728,14 @@ float_info (char *args, int from_tty)
   if (!target_has_registers)
     error (_("The program has no registers now."));
 
-  print_float_info (current_gdbarch, gdb_stdout, 
-                   get_selected_frame (NULL), args);
+  print_float_info (gdb_stdout, get_selected_frame (NULL), args);
 }
 \f
 static void
 unset_command (char *args, int from_tty)
 {
-  printf_filtered (_("\
-\"unset\" must be followed by the name of an unset subcommand.\n"));
+  printf_filtered (_("\"unset\" must be followed by the "
+                    "name of an unset subcommand.\n"));
   help_list (unsetlist, "unset ", -1, gdb_stdout);
 }
 
@@ -2243,21 +2744,24 @@ _initialize_infcmd (void)
 {
   struct cmd_list_element *c = NULL;
 
-  /* add the filename of the terminal connected to inferior I/O */
+  /* Add the filename of the terminal connected to inferior I/O.  */
   add_setshow_filename_cmd ("inferior-tty", class_run,
-                           &inferior_io_terminal, _("\
+                           &inferior_io_terminal_scratch, _("\
 Set terminal for future runs of program being debugged."), _("\
 Show terminal for future runs of program being debugged."), _("\
-Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist);
+Usage: set inferior-tty /dev/pts/1"),
+                           set_inferior_tty_command,
+                           show_inferior_tty_command,
+                           &setlist, &showlist);
   add_com_alias ("tty", "set inferior-tty", class_alias, 0);
 
   add_setshow_optional_filename_cmd ("args", class_run,
-                                    &inferior_args, _("\
+                                    &inferior_args_scratch, _("\
 Set argument list to give program being debugged when it is started."), _("\
 Show argument list to give program being debugged when it is started."), _("\
 Follow this command with any number of args, to be passed to the program."),
-                                    notice_args_set,
-                                    notice_args_read,
+                                    set_args_command,
+                                    show_args_command,
                                     &setlist, &showlist);
 
   c = add_cmd ("environment", no_class, environment_info, _("\
@@ -2290,7 +2794,8 @@ Add directory DIR(s) to beginning of search path for object files.\n\
 $cwd in the path means the current working directory.\n\
 This path is equivalent to the $PATH shell variable.  It is a list of\n\
 directories, separated by colons.  These directories are searched to find\n\
-fully linked executable files and separately compiled object files as needed."));
+fully linked executable files and separately compiled object files as \
+needed."));
   set_cmd_completer (c, filename_completer);
 
   c = add_cmd ("paths", no_class, path_info, _("\
@@ -2298,10 +2803,15 @@ Current search path for finding object files.\n\
 $cwd in the path means the current working directory.\n\
 This path is equivalent to the $PATH shell variable.  It is a list of\n\
 directories, separated by colons.  These directories are searched to find\n\
-fully linked executable files and separately compiled object files as needed."),
+fully linked executable files and separately compiled object files as \
+needed."),
               &showlist);
   set_cmd_completer (c, noop_completer);
 
+  add_prefix_cmd ("kill", class_run, kill_command,
+                 _("Kill execution of program being debugged."),
+                 &killlist, "kill ", 0, &cmdlist);
+
   add_com ("attach", class_run, attach_command, _("\
 Attach to a process or file outside of GDB.\n\
 This command attaches to another target, of the same type as your last\n\
@@ -2332,12 +2842,14 @@ An argument of \"0\" means continue program without giving it a signal."));
 
   add_com ("stepi", class_run, stepi_command, _("\
 Step one instruction exactly.\n\
-Argument N means do this N times (or till program stops for another reason)."));
+Argument N means do this N times (or till program stops for another \
+reason)."));
   add_com_alias ("si", "stepi", class_alias, 0);
 
   add_com ("nexti", class_run, nexti_command, _("\
 Step one instruction, but proceed through subroutine calls.\n\
-Argument N means do this N times (or till program stops for another reason)."));
+Argument N means do this N times (or till program stops for another \
+reason)."));
   add_com_alias ("ni", "nexti", class_alias, 0);
 
   add_com ("finish", class_run, finish_command, _("\
@@ -2349,24 +2861,28 @@ Upon return, the value returned is printed and put in the value history."));
 Step program, proceeding through subroutine calls.\n\
 Like the \"step\" command as long as subroutine calls do not happen;\n\
 when they do, the call is treated as one instruction.\n\
-Argument N means do this N times (or till program stops for another reason)."));
+Argument N means do this N times (or till program stops for another \
+reason)."));
   add_com_alias ("n", "next", class_run, 1);
   if (xdb_commands)
     add_com_alias ("S", "next", class_run, 1);
 
   add_com ("step", class_run, step_command, _("\
 Step program until it reaches a different source line.\n\
-Argument N means do this N times (or till program stops for another reason)."));
+Argument N means do this N times (or till program stops for another \
+reason)."));
   add_com_alias ("s", "step", class_run, 1);
 
   c = add_com ("until", class_run, until_command, _("\
 Execute until the program reaches a source line greater than the current\n\
-or a specified location (same args as break command) within the current frame."));
+or a specified location (same args as break command) within the current \
+frame."));
   set_cmd_completer (c, location_completer);
   add_com_alias ("u", "until", class_run, 1);
 
   c = add_com ("advance", class_run, advance_command, _("\
-Continue the program up to the given location (same form as args for break command).\n\
+Continue the program up to the given location (same form as args for break \
+command).\n\
 Execution will also stop upon exit from the current stack frame."));
   set_cmd_completer (c, location_completer);
 
@@ -2407,8 +2923,10 @@ Specifying -a and an ignore count simultaneously is an error."));
   c = add_com ("run", class_run, run_command, _("\
 Start debugged program.  You may specify arguments to give it.\n\
 Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\
-Input and output redirection with \">\", \"<\", or \">>\" are also allowed.\n\n\
-With no arguments, uses arguments last specified (with \"run\" or \"set args\").\n\
+Input and output redirection with \">\", \"<\", or \">>\" are also \
+allowed.\n\n\
+With no arguments, uses arguments last specified (with \"run\" \
+or \"set args\").\n\
 To cancel previous arguments and run with no arguments,\n\
 use \"set args\" without arguments."));
   set_cmd_completer (c, filename_completer);
@@ -2450,7 +2968,4 @@ Register name as argument means describe only that register."));
 
   add_info ("vector", vector_info,
            _("Print the status of the vector unit\n"));
-
-  inferior_environ = make_environ ();
-  init_environ (inferior_environ);
 }
This page took 0.055496 seconds and 4 git commands to generate.