Fix issues with multiple inferiors
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index 085903dcb014fea7645b845059514e5f9795c3a0..2bf21e26f1924e0af1b3c94ff88e677a3be80909 100644 (file)
@@ -1,6 +1,6 @@
 /* Memory-access and commands for "inferior" process, for GDB.
 
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "arch-utils.h"
-#include <signal.h>
-#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "frame.h"
 #include "inferior.h"
-#include "environ.h"
+#include "infrun.h"
+#include "gdbsupport/environ.h"
 #include "value.h"
 #include "gdbcmd.h"
 #include "symfile.h"
 #include "gdbcore.h"
 #include "target.h"
 #include "language.h"
-#include "symfile.h"
 #include "objfiles.h"
 #include "completer.h"
 #include "ui-out.h"
-#include "event-top.h"
-#include "parser-defs.h"
 #include "regcache.h"
 #include "reggroups.h"
 #include "block.h"
 #include "solib.h"
 #include <ctype.h>
-#include "gdb_assert.h"
-#include "observer.h"
+#include "observable.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
-#include "exceptions.h"
-#include "cli/cli-decode.h"
 #include "gdbthread.h"
 #include "valprint.h"
 #include "inline-frame.h"
 #include "inf-loop.h"
 #include "continuations.h"
 #include "linespec.h"
+#include "thread-fsm.h"
+#include "top.h"
+#include "interps.h"
+#include "skip.h"
+#include "gdbsupport/gdb_optional.h"
+#include "source.h"
+#include "cli/cli-style.h"
 
 /* Local functions: */
 
-static void nofp_registers_info (char *, int);
-
-static void print_return_value (struct value *function,
-                               struct type *value_type);
-
 static void until_next_command (int);
 
-static void until_command (char *, int);
-
-static void path_info (char *, int);
-
-static void path_command (char *, int);
-
-static void unset_command (char *, int);
-
-static void float_info (char *, int);
-
-static void disconnect_command (char *, int);
-
-static void unset_environment_command (char *, int);
-
-static void set_environment_command (char *, int);
-
-static void environment_info (char *, int);
-
-static void program_info (char *, int);
-
-static void finish_command (char *, int);
-
-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 next_command (char *, int);
-
-static void step_command (char *, int);
-
-static void run_command (char *, int);
-
-static void run_no_args_command (char *args, int from_tty);
-
-static void go_command (char *line_no, int from_tty);
-
-static int strip_bg_char (char **);
-
-void _initialize_infcmd (void);
+static void step_1 (int, int, const char *);
 
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error (_("The program is not being run."));
@@ -121,6 +74,10 @@ void _initialize_infcmd (void);
 
 static char *inferior_args_scratch;
 
+/* Scratch area where the new cwd will be stored by 'set cwd'.  */
+
+static char *inferior_cwd_scratch;
+
 /* Scratch area where 'set inferior-tty' will store user-provided value.
    We'll immediate copy it into per-inferior storage.  */
 
@@ -133,15 +90,6 @@ static char *inferior_io_terminal_scratch;
 
 ptid_t inferior_ptid;
 
-/* Address at which inferior stopped.  */
-
-CORE_ADDR stop_pc;
-
-/* Flag indicating that a command has proceeded the inferior past the
-   current breakpoint.  */
-
-int breakpoint_proceeded;
-
 /* Nonzero if stopped due to completion of a stack dummy routine.  */
 
 enum stop_stack_kind stop_stack_dummy;
@@ -161,7 +109,11 @@ void
 set_inferior_io_terminal (const char *terminal_name)
 {
   xfree (current_inferior ()->terminal);
-  current_inferior ()->terminal = terminal_name ? xstrdup (terminal_name) : 0;
+
+  if (terminal_name != NULL && *terminal_name != '\0')
+    current_inferior ()->terminal = xstrdup (terminal_name);
+  else
+    current_inferior ()->terminal = NULL;
 }
 
 const char *
@@ -171,7 +123,7 @@ get_inferior_io_terminal (void)
 }
 
 static void
-set_inferior_tty_command (char *args, int from_tty,
+set_inferior_tty_command (const char *args, int from_tty,
                          struct cmd_list_element *c)
 {
   /* CLI has assigned the user-provided value to inferior_io_terminal_scratch.
@@ -194,7 +146,7 @@ show_inferior_tty_command (struct ui_file *file, int from_tty,
                      "is \"%s\".\n"), inferior_io_terminal);
 }
 
-char *
+const char *
 get_inferior_args (void)
 {
   if (current_inferior ()->argc != 0)
@@ -217,7 +169,7 @@ get_inferior_args (void)
    NEWARGS is not transferred.  */
 
 void
-set_inferior_args (char *newargs)
+set_inferior_args (const char *newargs)
 {
   xfree (current_inferior ()->args);
   current_inferior ()->args = newargs ? xstrdup (newargs) : NULL;
@@ -233,8 +185,9 @@ set_inferior_args_vector (int argc, char **argv)
 }
 
 /* Notice when `set args' is run.  */
+
 static void
-set_args_command (char *args, int from_tty, struct cmd_list_element *c)
+set_args_command (const char *args, int from_tty, struct cmd_list_element *c)
 {
   /* CLI has assigned the user-provided value to inferior_args_scratch.
      Now route it to current inferior.  */
@@ -242,6 +195,7 @@ set_args_command (char *args, int from_tty, struct cmd_list_element *c)
 }
 
 /* Notice when `show args' is run.  */
+
 static void
 show_args_command (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
@@ -251,27 +205,82 @@ show_args_command (struct ui_file *file, int from_tty,
   deprecated_show_value_hack (file, from_tty, c, get_inferior_args ());
 }
 
+/* See gdbsupport/common-inferior.h.  */
+
+void
+set_inferior_cwd (const char *cwd)
+{
+  struct inferior *inf = current_inferior ();
+
+  gdb_assert (inf != NULL);
+
+  if (cwd == NULL)
+    inf->cwd.reset ();
+  else
+    inf->cwd.reset (xstrdup (cwd));
+}
+
+/* See gdbsupport/common-inferior.h.  */
+
+const char *
+get_inferior_cwd ()
+{
+  return current_inferior ()->cwd.get ();
+}
+
+/* Handle the 'set cwd' command.  */
+
+static void
+set_cwd_command (const char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (*inferior_cwd_scratch == '\0')
+    set_inferior_cwd (NULL);
+  else
+    set_inferior_cwd (inferior_cwd_scratch);
+}
+
+/* Handle the 'show cwd' command.  */
+
+static void
+show_cwd_command (struct ui_file *file, int from_tty,
+                 struct cmd_list_element *c, const char *value)
+{
+  const char *cwd = get_inferior_cwd ();
+
+  if (cwd == NULL)
+    fprintf_filtered (gdb_stdout,
+                     _("\
+You have not set the inferior's current working directory.\n\
+The inferior will inherit GDB's cwd if native debugging, or the remote\n\
+server's cwd if remote debugging.\n"));
+  else
+    fprintf_filtered (gdb_stdout,
+                     _("Current working directory that will be used "
+                       "when starting the inferior is \"%s\".\n"), cwd);
+}
+
 \f
 /* Compute command-line string given argument vector.  This does the
    same shell processing as fork_inferior.  */
+
 char *
 construct_inferior_arguments (int argc, char **argv)
 {
   char *result;
 
-  if (STARTUP_WITH_SHELL)
+  if (startup_with_shell)
     {
 #ifdef __MINGW32__
       /* This holds all the characters considered special to the
         Windows shells.  */
-      char *special = "\"!&*|[]{}<>?`~^=;, \t\n";
-      const char quote = '"';
+      static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
+      static const char quote = '"';
 #else
       /* This holds all the characters considered special to the
         typical Unix shells.  We include `^' because the SunOS
         /bin/sh treats it as a synonym for `|'.  */
-      char *special = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
-      const char quote = '\'';
+      static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
+      static const char quote = '\'';
 #endif
       int i;
       int length = 0;
@@ -370,34 +379,41 @@ construct_inferior_arguments (int argc, char **argv)
 }
 \f
 
-/* 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.  */
-static int
-strip_bg_char (char **args)
+/* This function strips the '&' character (indicating background
+   execution) that is added as *the last* of the arguments ARGS of a
+   command.  A copy of the incoming ARGS without the '&' is returned,
+   unless the resulting string after stripping is empty, in which case
+   NULL is returned.  *BG_CHAR_P is an output boolean that indicates
+   whether the '&' character was found.  */
+
+static gdb::unique_xmalloc_ptr<char>
+strip_bg_char (const char *args, int *bg_char_p)
 {
-  char *p = NULL;
+  const char *p;
 
-  p = strchr (*args, '&');
+  if (args == NULL || *args == '\0')
+    {
+      *bg_char_p = 0;
+      return NULL;
+    }
 
-  if (p)
+  p = args + strlen (args);
+  if (p[-1] == '&')
     {
-      if (p == (*args + strlen (*args) - 1))
-       {
-         if (strlen (*args) > 1)
-           {
-             do
-               p--;
-             while (*p == ' ' || *p == '\t');
-             *(p + 1) = '\0';
-           }
-         else
-           *args = 0;
-         return 1;
-       }
+      p--;
+      while (p > args && isspace (p[-1]))
+       p--;
+
+      *bg_char_p = 1;
+      if (p != args)
+       return gdb::unique_xmalloc_ptr<char>
+         (savestring (args, p - args));
+      else
+       return gdb::unique_xmalloc_ptr<char> (nullptr);
     }
-  return 0;
+
+  *bg_char_p = 0;
+  return make_unique_xstrdup (args);
 }
 
 /* Common actions to take after creating any sort of inferior, by any
@@ -407,10 +423,9 @@ strip_bg_char (char **args)
 void
 post_create_inferior (struct target_ops *target, int from_tty)
 {
-  volatile struct gdb_exception ex;
 
   /* Be sure we own the terminal in case write operations are performed.  */ 
-  target_terminal_ours ();
+  target_terminal::ours_for_output ();
 
   /* If the target hasn't taken care of this already, do it now.
      Targets which need to access registers during to_open,
@@ -421,13 +436,18 @@ post_create_inferior (struct target_ops *target, int from_tty)
   /* Now that we know the register layout, retrieve current PC.  But
      if the PC is unavailable (e.g., we're opening a core file with
      missing registers info), ignore it.  */
-  stop_pc = 0;
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  thread_info *thr = inferior_thread ();
+
+  thr->suspend.stop_pc = 0;
+  try
+    {
+      thr->suspend.stop_pc = regcache_read_pc (get_current_regcache ());
+    }
+  catch (const gdb_exception_error &ex)
     {
-      stop_pc = regcache_read_pc (get_current_regcache ());
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw;
     }
-  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
-    throw_exception (ex);
 
   if (exec_bfd)
     {
@@ -436,11 +456,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
 
       /* 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 (from_tty);
-#endif
 
       if (current_program_space->solib_add_generation == solib_add_generation)
        {
@@ -456,13 +472,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
          /* If the solist is global across processes, there's no need to
             refetch it here.  */
          if (!gdbarch_has_global_solist (target_gdbarch ()))
-           {
-#ifdef SOLIB_ADD
-             SOLIB_ADD (NULL, 0, target, auto_solib_add);
-#else
-             solib_add (NULL, 0, target, auto_solib_add);
-#endif
-           }
+           solib_add (NULL, 0, auto_solib_add);
        }
     }
 
@@ -478,7 +488,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
      if the now pushed target supports hardware watchpoints.  */
   breakpoint_re_set ();
 
-  observer_notify_inferior_created (target, from_tty);
+  gdb::observers::inferior_created.notify (target, from_tty);
 }
 
 /* Kill the inferior if already running.  This function is designed
@@ -489,7 +499,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
 static void
 kill_if_already_running (int from_tty)
 {
-  if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
+  if (inferior_ptid != null_ptid && target_has_execution)
     {
       /* Bail out before killing the program if we will not be able to
         restart it.  */
@@ -503,17 +513,50 @@ Start it from the beginning? ")))
     }
 }
 
-/* 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.  */
+/* See inferior.h.  */
+
+void
+prepare_execution_command (struct target_ops *target, int background)
+{
+  /* If we get a request for running in the bg but the target
+     doesn't support it, error out.  */
+  if (background && !target->can_async_p ())
+    error (_("Asynchronous execution not supported on this target."));
+
+  if (!background)
+    {
+      /* If we get a request for running in the fg, then we need to
+        simulate synchronous (fg) execution.  Note no cleanup is
+        necessary for this.  stdin is re-enabled whenever an error
+        reaches the top level.  */
+      all_uis_on_sync_execution_starting ();
+    }
+}
+
+/* Determine how the new inferior will behave.  */
+
+enum run_how
+  {
+    /* Run program without any explicit stop during startup.  */
+    RUN_NORMAL,
+
+    /* Stop at the beginning of the program's main function.  */
+    RUN_STOP_AT_MAIN,
+
+    /* Stop at the first instruction of the program.  */
+    RUN_STOP_AT_FIRST_INSN
+  };
+
+/* Implement the "run" command.  Force a stop during program start if
+   requested by RUN_HOW.  */
 
 static void
-run_command_1 (char *args, int from_tty, int tbreak_at_main)
+run_command_1 (const char *args, int from_tty, enum run_how run_how)
 {
-  char *exec_file;
-  struct cleanup *old_chain;
-  ptid_t ptid;
+  const char *exec_file;
   struct ui_out *uiout = current_uiout;
+  struct target_ops *run_target;
+  int async_exec;
 
   dont_repeat ();
 
@@ -536,15 +579,30 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   reopen_exec_file ();
   reread_symbols ();
 
-  /* Insert the temporary breakpoint if a location was specified.  */
-  if (tbreak_at_main)
-    tbreak_command (main_name (), 0);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
-  exec_file = (char *) get_exec_file (0);
+  /* Do validation and preparation before possibly changing anything
+     in the inferior.  */
 
-  if (non_stop && !target_supports_non_stop ())
+  run_target = find_run_target ();
+
+  prepare_execution_command (run_target, async_exec);
+
+  if (non_stop && !run_target->supports_non_stop ())
     error (_("The target does not support running in non-stop mode."));
 
+  /* Done.  Can now set breakpoints, change inferior args, etc.  */
+
+  /* Insert temporary breakpoint in main function if requested.  */
+  if (run_how == RUN_STOP_AT_MAIN)
+    {
+      std::string arg = string_printf ("-qualified %s", main_name ());
+      tbreak_command (arg.c_str (), 0);
+    }
+
+  exec_file = get_exec_file (0);
+
   /* We keep symbols from add-symbol-file, on the grounds that the
      user might want to add some symbols before running the program
      (right?).  But sometimes (dynamic loading where the user manually
@@ -553,52 +611,33 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
      the user has to manually nuke all symbols between runs if they
      want them to go away (PR 2207).  This is probably reasonable.  */
 
-  if (!args)
-    {
-      if (target_can_async_p ())
-       async_disable_stdin ();
-    }
-  else
-    {
-      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.  */
-      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.  */
-      if (!async_exec && target_can_async_p ())
-       {
-         /* Simulate synchronous execution.  */
-         async_disable_stdin ();
-       }
-
-      /* If there were other args, beside '&', process them.  */
-      if (args)
-       set_inferior_args (args);
-    }
+  /* If there were other args, beside '&', process them.  */
+  if (args != NULL)
+    set_inferior_args (args);
 
   if (from_tty)
     {
-      ui_out_field_string (uiout, NULL, "Starting program");
-      ui_out_text (uiout, ": ");
+      uiout->field_string (NULL, "Starting program");
+      uiout->text (": ");
       if (exec_file)
-       ui_out_field_string (uiout, "execfile", exec_file);
-      ui_out_spaces (uiout, 1);
+       uiout->field_string ("execfile", exec_file);
+      uiout->spaces (1);
       /* We call get_inferior_args() because we might need to compute
         the value now.  */
-      ui_out_field_string (uiout, "infargs", get_inferior_args ());
-      ui_out_text (uiout, "\n");
-      ui_out_flush (uiout);
+      uiout->field_string ("infargs", get_inferior_args ());
+      uiout->text ("\n");
+      uiout->flush ();
     }
 
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
-  target_create_inferior (exec_file, get_inferior_args (),
-                         environ_vector (current_inferior ()->environment),
-                         from_tty);
+  run_target->create_inferior (exec_file,
+                              std::string (get_inferior_args ()),
+                              current_inferior ()->environment.envp (),
+                              from_tty);
+  /* to_create_inferior should push the target, so after this point we
+     shouldn't refer to run_target again.  */
+  run_target = NULL;
 
   /* 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,
@@ -606,43 +645,53 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
      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.  */
+  process_stratum_target *finish_target;
+  ptid_t finish_ptid;
   if (non_stop)
-    ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+    {
+      finish_target = current_inferior ()->process_target ();
+      finish_ptid = ptid_t (current_inferior ()->pid);
+    }
   else
-    ptid = minus_one_ptid;
-  old_chain = make_cleanup (finish_thread_state_cleanup, &ptid);
+    {
+      finish_target = nullptr;
+      finish_ptid = minus_one_ptid;
+    }
+  scoped_finish_thread_state finish_state (finish_target, finish_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);
+  post_create_inferior (current_top_target (), 0);
+
+  /* Queue a pending event so that the program stops immediately.  */
+  if (run_how == RUN_STOP_AT_FIRST_INSN)
+    {
+      thread_info *thr = inferior_thread ();
+      thr->suspend.waitstatus_pending_p = 1;
+      thr->suspend.waitstatus.kind = TARGET_WAITKIND_STOPPED;
+      thr->suspend.waitstatus.value.sig = GDB_SIGNAL_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 ()), GDB_SIGNAL_0, 0);
+  proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0);
 
   /* Since there was no error, there's no need to finish the thread
      states here.  */
-  discard_cleanups (old_chain);
+  finish_state.release ();
 }
 
 static void
-run_command (char *args, int from_tty)
+run_command (const char *args, int from_tty)
 {
-  run_command_1 (args, from_tty, 0);
+  run_command_1 (args, from_tty, RUN_NORMAL);
 }
 
-static void
-run_no_args_command (char *args, int from_tty)
-{
-  set_inferior_args ("");
-}
-\f
-
 /* Start the execution of the program up until the beginning of the main
    program.  */
 
 static void
-start_command (char *args, int from_tty)
+start_command (const char *args, int from_tty)
 {
   /* Some languages such as Ada need to search inside the program
      minimal symbols for the location where to put the temporary
@@ -651,7 +700,16 @@ start_command (char *args, int from_tty)
     error (_("No symbol table loaded.  Use the \"file\" command."));
 
   /* Run the program until reaching the main procedure...  */
-  run_command_1 (args, from_tty, 1);
+  run_command_1 (args, from_tty, RUN_STOP_AT_MAIN);
+}
+
+/* Start the execution of the program stopping at the first
+   instruction.  */
+
+static void
+starti_command (const char *args, int from_tty)
+{
+  run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN);
 } 
 
 static int
@@ -666,20 +724,23 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
      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))
+  if (thread->state != THREAD_STOPPED)
+    return 0;
+
+  if (!thread->inf->has_execution ())
     return 0;
 
-  switch_to_thread (thread->ptid);
-  clear_proceed_status ();
-  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+  switch_to_thread (thread);
+  clear_proceed_status (0);
+  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
   return 0;
 }
 
 static void
 ensure_valid_thread (void)
 {
-  if (ptid_equal (inferior_ptid, null_ptid)
-      || is_exited (inferior_ptid))
+  if (inferior_ptid == null_ptid
+      || inferior_thread ()->state == THREAD_EXITED)
     error (_("Cannot execute this command without a live selected thread."));
 }
 
@@ -708,7 +769,7 @@ error_is_running (void)
 static void
 ensure_not_running (void)
 {
-  if (is_running (inferior_ptid))
+  if (inferior_thread ()->state == THREAD_RUNNING)
     error_is_running ();
 }
 
@@ -722,65 +783,69 @@ continue_1 (int all_threads)
     {
       /* 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 ();
+      /* Backup current thread and selected frame and restore on scope
+        exit.  */
+      scoped_restore_current_thread restore_thread;
 
       iterate_over_threads (proceed_thread_callback, NULL);
 
-      /* Restore selected ptid.  */
-      do_cleanups (old_chain);
+      if (current_ui->prompt_state == PROMPT_BLOCKED)
+       {
+         /* If all threads in the target were already running,
+            proceed_thread_callback ends up never calling proceed,
+            and so nothing calls this to put the inferior's terminal
+            settings in effect and remove stdin from the event loop,
+            which we must when running a foreground command.  E.g.:
+
+             (gdb) c -a&
+             Continuing.
+             <all threads are running now>
+             (gdb) c -a
+             Continuing.
+             <no thread was resumed, but the inferior now owns the terminal>
+         */
+         target_terminal::inferior ();
+       }
     }
   else
     {
       ensure_valid_thread ();
       ensure_not_running ();
-      clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+      clear_proceed_status (0);
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
 }
 
 /* continue [-a] [proceed-count] [&]  */
+
 static void
-continue_command (char *args, int from_tty)
+continue_command (const char *args, int from_tty)
 {
-  int async_exec = 0;
-  int all_threads = 0;
+  int async_exec;
+  bool all_threads_p = false;
+
   ERROR_NO_INFERIOR;
 
   /* 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.  */
-  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.  */
-  if (!async_exec && target_can_async_p ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
   if (args != NULL)
     {
-      if (strncmp (args, "-a", sizeof ("-a") - 1) == 0)
+      if (startswith (args, "-a"))
        {
-         all_threads = 1;
+         all_threads_p = true;
          args += sizeof ("-a") - 1;
          if (*args == '\0')
            args = NULL;
        }
     }
 
-  if (!non_stop && all_threads)
+  if (!non_stop && all_threads_p)
     error (_("`-a' is meaningless in all-stop mode."));
 
-  if (args != NULL && all_threads)
+  if (args != NULL && all_threads_p)
     error (_("Can't resume all threads and specify "
             "proceed count simultaneously."));
 
@@ -794,14 +859,14 @@ continue_command (char *args, int from_tty)
       struct thread_info *tp;
 
       if (non_stop)
-       tp = find_thread_ptid (inferior_ptid);
+       tp = inferior_thread ();
       else
        {
+         process_stratum_target *last_target;
          ptid_t last_ptid;
-         struct target_waitstatus ws;
 
-         get_last_target_status (&last_ptid, &ws);
-         tp = find_thread_ptid (last_ptid);
+         get_last_target_status (&last_target, &last_ptid, nullptr);
+         tp = find_thread_ptid (last_target, last_ptid);
        }
       if (tp != NULL)
        bs = tp->control.stop_bpstat;
@@ -826,10 +891,21 @@ continue_command (char *args, int from_tty)
        }
     }
 
+  ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+
+  if (!non_stop || !all_threads_p)
+    {
+      ensure_valid_thread ();
+      ensure_not_running ();
+    }
+
+  prepare_execution_command (current_top_target (), async_exec);
+
   if (from_tty)
     printf_filtered (_("Continuing.\n"));
 
-  continue_1 (all_threads);
+  continue_1 (all_threads_p);
 }
 \f
 /* Record the starting point of a "step" or "next" command.  */
@@ -837,16 +913,20 @@ continue_command (char *args, int from_tty)
 static void
 set_step_frame (void)
 {
-  struct symtab_and_line sal;
+  frame_info *frame = get_current_frame ();
 
-  find_frame_sal (get_current_frame (), &sal);
-  set_step_info (get_current_frame (), sal);
+  symtab_and_line sal = find_frame_sal (frame);
+  set_step_info (frame, sal);
+
+  CORE_ADDR pc = get_frame_pc (frame);
+  thread_info *tp = inferior_thread ();
+  tp->control.step_start_function = find_pc_function (pc);
 }
 
 /* Step until outside of current statement.  */
 
 static void
-step_command (char *count_string, int from_tty)
+step_command (const char *count_string, int from_tty)
 {
   step_1 (0, 0, count_string);
 }
@@ -854,7 +934,7 @@ step_command (char *count_string, int from_tty)
 /* Likewise, but skip over subroutine calls as if single instructions.  */
 
 static void
-next_command (char *count_string, int from_tty)
+next_command (const char *count_string, int from_tty)
 {
   step_1 (1, 0, count_string);
 }
@@ -862,197 +942,206 @@ next_command (char *count_string, int from_tty)
 /* Likewise, but step only one instruction.  */
 
 static void
-stepi_command (char *count_string, int from_tty)
+stepi_command (const char *count_string, int from_tty)
 {
   step_1 (0, 1, count_string);
 }
 
 static void
-nexti_command (char *count_string, int from_tty)
+nexti_command (const char *count_string, int from_tty)
 {
   step_1 (1, 1, count_string);
 }
 
-void
-delete_longjmp_breakpoint_cleanup (void *arg)
+/* Data for the FSM that manages the step/next/stepi/nexti
+   commands.  */
+
+struct step_command_fsm : public thread_fsm
+{
+  /* How many steps left in a "step N"-like command.  */
+  int count;
+
+  /* If true, this is a next/nexti, otherwise a step/stepi.  */
+  int skip_subroutines;
+
+  /* If true, this is a stepi/nexti, otherwise a step/step.  */
+  int single_inst;
+
+  explicit step_command_fsm (struct interp *cmd_interp)
+    : thread_fsm (cmd_interp)
+  {
+  }
+
+  void clean_up (struct thread_info *thread) override;
+  bool should_stop (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
+};
+
+/* Prepare for a step/next/etc. command.  Any target resource
+   allocated here is undone in the FSM's clean_up method.  */
+
+static void
+step_command_fsm_prepare (struct step_command_fsm *sm,
+                         int skip_subroutines, int single_inst,
+                         int count, struct thread_info *thread)
 {
-  int thread = * (int *) arg;
-  delete_longjmp_breakpoint (thread);
+  sm->skip_subroutines = skip_subroutines;
+  sm->single_inst = single_inst;
+  sm->count = count;
+
+  /* Leave the si command alone.  */
+  if (!sm->single_inst || sm->skip_subroutines)
+    set_longjmp_breakpoint (thread, get_frame_id (get_current_frame ()));
+
+  thread->control.stepping_command = 1;
 }
 
+static int prepare_one_step (struct step_command_fsm *sm);
+
 static void
-step_1 (int skip_subroutines, int single_inst, char *count_string)
+step_1 (int skip_subroutines, int single_inst, const char *count_string)
 {
-  int count = 1;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
-  int async_exec = 0;
-  int thread = -1;
+  int count;
+  int async_exec;
+  struct thread_info *thr;
+  struct step_command_fsm *step_sm;
 
   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.  */
-  if (async_exec && !target_can_async_p ())
-    error (_("Asynchronous execution not supported on this target."));
+  gdb::unique_xmalloc_ptr<char> stripped
+    = strip_bg_char (count_string, &async_exec);
+  count_string = stripped.get ();
 
-  /* If we don't get a request of running in the bg, then we need
-     to simulate synchronous (fg) execution.  */
-  if (!async_exec && target_can_async_p ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  prepare_execution_command (current_top_target (), async_exec);
 
   count = count_string ? parse_and_eval_long (count_string) : 1;
 
-  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 (tp, get_frame_id (get_current_frame ()));
+  clear_proceed_status (1);
 
-      make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
-    }
-
-  /* In synchronous case, all is well; each step_once call will step once.  */
-  if (!target_can_async_p ())
-    {
-      for (; count > 0; count--)
-       {
-         step_once (skip_subroutines, single_inst, count, thread);
+  /* Setup the execution command state machine to handle all the COUNT
+     steps.  */
+  thr = inferior_thread ();
+  step_sm = new step_command_fsm (command_interp ());
+  thr->thread_fsm = step_sm;
 
-         if (!target_has_execution)
-           break;
-         else
-           {
-             struct thread_info *tp = inferior_thread ();
+  step_command_fsm_prepare (step_sm, skip_subroutines,
+                           single_inst, count, thr);
 
-             if (!tp->control.stop_step || !tp->step_multi)
-               {
-                 /* If we stopped for some reason that is not stepping
-                    there are no further steps to make.  */
-                 tp->step_multi = 0;
-                 break;
-               }
-           }
-       }
-
-      do_cleanups (cleanups);
-    }
+  /* 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.  */
+  if (!prepare_one_step (step_sm))
+    proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
   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);
+      int proceeded;
 
-      /* We are running, and the continuation is installed.  It will
-        disable the longjmp breakpoint as appropriate.  */
-      discard_cleanups (cleanups);
+      /* Stepped into an inline frame.  Pretend that we've
+        stopped.  */
+      thr->thread_fsm->clean_up (thr);
+      proceeded = normal_stop ();
+      if (!proceeded)
+       inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+      all_uis_check_sync_execution_done ();
     }
 }
 
-struct step_1_continuation_args
-{
-  int count;
-  int skip_subroutines;
-  int single_inst;
-  int thread;
-};
+/* Implementation of the 'should_stop' FSM method for stepping
+   commands.  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, returns false, as we
+   will need to keep going.  */
 
-/* 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.  */
-static void
-step_1_continuation (void *args, int err)
+bool
+step_command_fsm::should_stop (struct thread_info *tp)
 {
-  struct step_1_continuation_args *a = args;
-
-  if (target_has_execution)
+  if (tp->control.stop_step)
     {
-      struct thread_info *tp;
+      /* There are more steps to make, and we did stop due to
+        ending a stepping range.  Do another step.  */
+      if (--count > 0)
+       return prepare_one_step (this);
 
-      tp = inferior_thread ();
-      if (!err
-         && 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);
-         return;
-       }
-      tp->step_multi = 0;
+      set_finished ();
     }
 
-  /* We either hit an error, or stopped for some reason that is
-     not stepping, or there are no further steps to make.
-     Cleanup.  */
-  if (!a->single_inst || a->skip_subroutines)
-    delete_longjmp_breakpoint (a->thread);
+  return true;
 }
 
-/* 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.  */
+/* Implementation of the 'clean_up' FSM method for stepping commands.  */
 
-static void
-step_once (int skip_subroutines, int single_inst, int count, int thread)
+void
+step_command_fsm::clean_up (struct thread_info *thread)
 {
-  struct frame_info *frame = get_current_frame ();
+  if (!single_inst || skip_subroutines)
+    delete_longjmp_breakpoint (thread->global_num);
+}
+
+/* Implementation of the 'async_reply_reason' FSM method for stepping
+   commands.  */
 
-  if (count > 0)
+enum async_reply_reason
+step_command_fsm::do_async_reply_reason ()
+{
+  return EXEC_ASYNC_END_STEPPING_RANGE;
+}
+
+/* Prepare for one step in "step N".  The actual target resumption is
+   done by the caller.  Return true if we're done and should thus
+   report a stop to the user.  Returns false if the target needs to be
+   resumed.  */
+
+static int
+prepare_one_step (struct step_command_fsm *sm)
+{
+  if (sm->count > 0)
     {
+      struct frame_info *frame = get_current_frame ();
+
       /* Don't assume THREAD is a valid thread id.  It is set to -1 if
         the longjmp breakpoint was not required.  Use the
         INFERIOR_PTID thread instead, which is the same thread when
         THREAD is set.  */
       struct thread_info *tp = inferior_thread ();
 
-      clear_proceed_status ();
       set_step_frame ();
 
-      if (!single_inst)
+      if (!sm->single_inst)
        {
          CORE_ADDR pc;
 
          /* Step at an inlined function behaves like "down".  */
-         if (!skip_subroutines && !single_inst
-             && inline_skipped_frames (inferior_ptid))
+         if (!sm->skip_subroutines
+             && inline_skipped_frames (tp))
            {
              ptid_t resume_ptid;
+             const char *fn = NULL;
+             symtab_and_line sal;
+             struct symbol *sym;
 
              /* Pretend that we've ran.  */
              resume_ptid = user_visible_resume_ptid (1);
-             set_running (resume_ptid, 1);
+             set_running (tp->inf->process_target (), resume_ptid, true);
 
-             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 ();
+             step_into_inline_frame (tp);
+
+             frame = get_current_frame ();
+             sal = find_frame_sal (frame);
+             sym = get_frame_function (frame);
+
+             if (sym != NULL)
+               fn = sym->print_name ();
 
-                 if (target_can_async_p ())
-                   inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+             if (sal.line == 0
+                 || !function_name_is_marked_for_skip (fn, sal))
+               {
+                 sm->count--;
+                 return prepare_one_step (sm);
                }
-             return;
            }
 
          pc = get_frame_pc (frame);
@@ -1060,9 +1149,14 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
                                 &tp->control.step_range_start,
                                 &tp->control.step_range_end);
 
+         tp->control.may_range_step = 1;
+
          /* 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;
+           {
+             tp->control.step_range_start = tp->control.step_range_end = 1;
+             tp->control.may_range_step = 0;
+           }
          else if (tp->control.step_range_end == 0)
            {
              const char *name;
@@ -1072,7 +1166,7 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
                                            &tp->control.step_range_end) == 0)
                error (_("Cannot find bounds of current function"));
 
-             target_terminal_ours ();
+             target_terminal::ours_for_output ();
              printf_filtered (_("Single stepping until exit from function %s,"
                                 "\nwhich has no line number information.\n"),
                               name);
@@ -1082,50 +1176,35 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
        {
          /* Say we are stepping, but stop after one insn whatever it does.  */
          tp->control.step_range_start = tp->control.step_range_end = 1;
-         if (!skip_subroutines)
+         if (!sm->skip_subroutines)
            /* It is stepi.
               Don't step over function calls, not even to functions lacking
               line numbers.  */
            tp->control.step_over_calls = STEP_OVER_NONE;
        }
 
-      if (skip_subroutines)
+      if (sm->skip_subroutines)
        tp->control.step_over_calls = STEP_OVER_ALL;
 
-      tp->step_multi = (count > 1);
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
-
-      /* 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);
-       }
+      return 0;
     }
+
+  /* Done.  */
+  sm->set_finished ();
+  return 1;
 }
 
 \f
 /* Continue program at specified address.  */
 
 static void
-jump_command (char *arg, int from_tty)
+jump_command (const char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR addr;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
   struct symbol *fn;
   struct symbol *sfn;
-  int async_exec = 0;
+  int async_exec;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1133,25 +1212,20 @@ jump_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  if (arg != NULL)
-    async_exec = strip_bg_char (&arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
-  /* If we must run in the background, but the target can't do it,
-     error out.  */
-  if (async_exec && !target_can_async_p ())
-    error (_("Asynchronous execution not supported on this target."));
+  prepare_execution_command (current_top_target (), async_exec);
 
   if (!arg)
     error_no_arg (_("starting address"));
 
-  sals = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
-  if (sals.nelts != 1)
-    {
-      error (_("Unreasonable jump request"));
-    }
+  std::vector<symtab_and_line> sals
+    = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
+  if (sals.size () != 1)
+    error (_("Unreasonable jump request"));
 
-  sal = sals.sals[0];
-  xfree (sals.sals);
+  symtab_and_line &sal = sals[0];
 
   if (sal.symtab == 0 && sal.pc == 0)
     error (_("No source file has been specified."));
@@ -1164,7 +1238,7 @@ jump_command (char *arg, int from_tty)
   if (fn != NULL && sfn != fn)
     {
       if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
-                 SYMBOL_PRINT_NAME (fn)))
+                 fn->print_name ()))
        {
          error (_("Not confirmed."));
          /* NOTREACHED */
@@ -1173,9 +1247,12 @@ jump_command (char *arg, int from_tty)
 
   if (sfn != NULL)
     {
+      struct obj_section *section;
+
       fixup_symbol_section (sfn, 0);
-      if (section_is_overlay (SYMBOL_OBJ_SECTION (sfn)) &&
-         !section_is_mapped (SYMBOL_OBJ_SECTION (sfn)))
+      section = SYMBOL_OBJ_SECTION (symbol_objfile (sfn), sfn);
+      if (section_is_overlay (section)
+         && !section_is_mapped (section))
        {
          if (!query (_("WARNING!!!  Destination is in "
                        "unmapped overlay!  Jump anyway? ")))
@@ -1195,40 +1272,17 @@ jump_command (char *arg, int from_tty)
       printf_filtered (".\n");
     }
 
-  /* 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 ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
-
-  clear_proceed_status ();
-  proceed (addr, GDB_SIGNAL_0, 0);
-}
-\f
-
-/* 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 (_("Usage: go <location>\n"));
-  else
-    {
-      tbreak_command (line_no, from_tty);
-      jump_command (line_no, from_tty);
-    }
+  clear_proceed_status (0);
+  proceed (addr, GDB_SIGNAL_0);
 }
 \f
-
 /* Continue program giving it specified signal.  */
 
 static void
-signal_command (char *signum_exp, int from_tty)
+signal_command (const char *signum_exp, int from_tty)
 {
   enum gdb_signal oursig;
-  int async_exec = 0;
+  int async_exec;
 
   dont_repeat ();              /* Too dangerous.  */
   ERROR_NO_INFERIOR;
@@ -1237,21 +1291,11 @@ signal_command (char *signum_exp, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  if (signum_exp != NULL)
-    async_exec = strip_bg_char (&signum_exp);
-
-  /* If we must run in the background, but the target can't do it,
-     error out.  */
-  if (async_exec && !target_can_async_p ())
-    error (_("Asynchronous execution not supported on this target."));
+  gdb::unique_xmalloc_ptr<char> stripped
+    = strip_bg_char (signum_exp, &async_exec);
+  signum_exp = stripped.get ();
 
-  /* 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 ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  prepare_execution_command (current_top_target (), async_exec);
 
   if (!signum_exp)
     error_no_arg (_("signal number"));
@@ -1272,6 +1316,50 @@ signal_command (char *signum_exp, int from_tty)
        oursig = gdb_signal_from_command (num);
     }
 
+  /* Look for threads other than the current that this command ends up
+     resuming too (due to schedlock off), and warn if they'll get a
+     signal delivered.  "signal 0" is used to suppress a previous
+     signal, but if the current thread is no longer the one that got
+     the signal, then the user is potentially suppressing the signal
+     of the wrong thread.  */
+  if (!non_stop)
+    {
+      int must_confirm = 0;
+
+      /* This indicates what will be resumed.  Either a single thread,
+        a whole process, or all threads of all processes.  */
+      ptid_t resume_ptid = user_visible_resume_ptid (0);
+      process_stratum_target *resume_target
+       = user_visible_resume_target (resume_ptid);
+
+      thread_info *current = inferior_thread ();
+
+      for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid))
+       {
+         if (tp == current)
+           continue;
+
+         if (tp->suspend.stop_signal != GDB_SIGNAL_0
+             && signal_pass_state (tp->suspend.stop_signal))
+           {
+             if (!must_confirm)
+               printf_unfiltered (_("Note:\n"));
+             printf_unfiltered (_("  Thread %s previously stopped with signal %s, %s.\n"),
+                                print_thread_id (tp),
+                                gdb_signal_to_name (tp->suspend.stop_signal),
+                                gdb_signal_to_string (tp->suspend.stop_signal));
+             must_confirm = 1;
+           }
+       }
+
+      if (must_confirm
+         && !query (_("Continuing thread %s (the current thread) with specified signal will\n"
+                      "still deliver the signals noted above to their respective threads.\n"
+                      "Continue anyway? "),
+                    print_thread_id (inferior_thread ())))
+       error (_("Not confirmed."));
+    }
+
   if (from_tty)
     {
       if (oursig == GDB_SIGNAL_0)
@@ -1281,26 +1369,97 @@ signal_command (char *signum_exp, int from_tty)
                         gdb_signal_to_name (oursig));
     }
 
-  clear_proceed_status ();
-  proceed ((CORE_ADDR) -1, oursig, 0);
+  clear_proceed_status (0);
+  proceed ((CORE_ADDR) -1, oursig);
 }
 
-/* Continuation args to be passed to the "until" command
-   continuation.  */
-struct until_next_continuation_args
+/* Queue a signal to be delivered to the current thread.  */
+
+static void
+queue_signal_command (const char *signum_exp, int from_tty)
 {
-  /* The thread that was current when the command was executed.  */
+  enum gdb_signal oursig;
+  struct thread_info *tp;
+
+  ERROR_NO_INFERIOR;
+  ensure_not_tfind_mode ();
+  ensure_valid_thread ();
+  ensure_not_running ();
+
+  if (signum_exp == NULL)
+    error_no_arg (_("signal number"));
+
+  /* It would be even slicker to make signal names be valid expressions,
+     (the type could be "enum $signal" or some such), then the user could
+     assign them to convenience variables.  */
+  oursig = gdb_signal_from_name (signum_exp);
+
+  if (oursig == GDB_SIGNAL_UNKNOWN)
+    {
+      /* No, try numeric.  */
+      int num = parse_and_eval_long (signum_exp);
+
+      if (num == 0)
+       oursig = GDB_SIGNAL_0;
+      else
+       oursig = gdb_signal_from_command (num);
+    }
+
+  if (oursig != GDB_SIGNAL_0
+      && !signal_pass_state (oursig))
+    error (_("Signal handling set to not pass this signal to the program."));
+
+  tp = inferior_thread ();
+  tp->suspend.stop_signal = oursig;
+}
+
+/* Data for the FSM that manages the until (with no argument)
+   command.  */
+
+struct until_next_fsm : public thread_fsm
+{
+  /* The thread that as current when the command was executed.  */
   int thread;
+
+  until_next_fsm (struct interp *cmd_interp, int thread)
+    : thread_fsm (cmd_interp),
+      thread (thread)
+  {
+  }
+
+  bool should_stop (struct thread_info *thread) override;
+  void clean_up (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-/* A continuation callback for until_next_command.  */
+/* Implementation of the 'should_stop' FSM method for the until (with
+   no arg) command.  */
 
-static void
-until_next_continuation (void *arg, int err)
+bool
+until_next_fsm::should_stop (struct thread_info *tp)
 {
-  struct until_next_continuation_args *a = arg;
+  if (tp->control.stop_step)
+    set_finished ();
+
+  return true;
+}
 
-  delete_longjmp_breakpoint (a->thread);
+/* Implementation of the 'clean_up' FSM method for the until (with no
+   arg) command.  */
+
+void
+until_next_fsm::clean_up (struct thread_info *thread)
+{
+  delete_longjmp_breakpoint (thread->global_num);
+}
+
+/* Implementation of the 'async_reply_reason' FSM method for the until
+   (with no arg) command.  */
+
+enum async_reply_reason
+until_next_fsm::do_async_reply_reason ()
+{
+  return EXEC_ASYNC_END_STEPPING_RANGE;
 }
 
 /* Proceed until we reach a different source line with pc greater than
@@ -1319,10 +1478,10 @@ 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;
+  int thread = tp->global_num;
+  struct until_next_fsm *sm;
 
-  clear_proceed_status ();
+  clear_proceed_status (0);
   set_step_frame ();
 
   frame = get_current_frame ();
@@ -1336,49 +1495,41 @@ until_next_command (int from_tty)
 
   if (!func)
     {
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+      struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
 
-      if (msymbol == NULL)
+      if (msymbol.minsym == NULL)
        error (_("Execution is not within a known function."));
 
-      tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
-      tp->control.step_range_end = pc;
+      tp->control.step_range_start = BMSYMBOL_VALUE_ADDRESS (msymbol);
+      /* The upper-bound of step_range is exclusive.  In order to make PC
+        within the range, set the step_range_end with PC + 1.  */
+      tp->control.step_range_end = pc + 1;
     }
   else
     {
       sal = find_pc_line (pc, 0);
 
-      tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+      tp->control.step_range_start = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func));
       tp->control.step_range_end = sal.end;
     }
+  tp->control.may_range_step = 1;
 
   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);
+  delete_longjmp_breakpoint_cleanup lj_deleter (thread);
 
-  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+  sm = new until_next_fsm (command_interp (), tp->global_num);
+  tp->thread_fsm = sm;
+  lj_deleter.release ();
 
-  if (target_can_async_p () && is_running (inferior_ptid))
-    {
-      struct until_next_continuation_args *cont_args;
-
-      discard_cleanups (old_chain);
-      cont_args = XNEW (struct until_next_continuation_args);
-      cont_args->thread = inferior_thread ()->num;
-
-      add_continuation (tp, until_next_continuation, cont_args, xfree);
-    }
-  else
-    do_cleanups (old_chain);
+  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
 }
 
 static void
-until_command (char *arg, int from_tty)
+until_command (const char *arg, int from_tty)
 {
-  int async_exec = 0;
+  int async_exec;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1386,21 +1537,10 @@ until_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
-  if (arg != NULL)
-    async_exec = strip_bg_char (&arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
-  /* If we must run in the background, but the target can't do it,
-     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.  */
-  if (!async_exec && target_can_async_p ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  prepare_execution_command (current_top_target (), async_exec);
 
   if (arg)
     until_break_command (arg, from_tty, 0);
@@ -1409,9 +1549,9 @@ until_command (char *arg, int from_tty)
 }
 
 static void
-advance_command (char *arg, int from_tty)
+advance_command (const char *arg, int from_tty)
 {
-  int async_exec = 0;
+  int async_exec;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1422,47 +1562,26 @@ advance_command (char *arg, int from_tty)
     error_no_arg (_("a location"));
 
   /* Find out whether we must run in the background.  */
-  if (arg != NULL)
-    async_exec = strip_bg_char (&arg);
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
-  /* If we must run in the background, but the target can't do it,
-     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.  */
-  if (!async_exec && target_can_async_p ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  prepare_execution_command (current_top_target (), async_exec);
 
   until_break_command (arg, from_tty, 1);
 }
 \f
 /* Return the value of the result of a function at the end of a 'finish'
-   command/BP.  */
+   command/BP.  DTOR_DATA (if not NULL) can represent inferior registers
+   right after an inferior call has finished.  */
 
 struct value *
 get_return_value (struct value *function, struct type *value_type)
 {
-  struct regcache *stop_regs = stop_registers;
-  struct gdbarch *gdbarch;
+  regcache *stop_regs = get_current_regcache ();
+  struct gdbarch *gdbarch = stop_regs->arch ();
   struct value *value;
-  struct ui_out *uiout = current_uiout;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
 
-  /* If stop_registers were not saved, use the current registers.  */
-  if (!stop_regs)
-    {
-      stop_regs = regcache_dup (get_current_regcache ());
-      cleanup = make_cleanup_regcache_xfree (stop_regs);
-    }
-
-  gdbarch = get_regcache_arch (stop_regs);
-
-  CHECK_TYPEDEF (value_type);
+  value_type = check_typedef (value_type);
   gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
 
   /* FIXME: 2003-09-27: When returning from a nested inferior function
@@ -1489,130 +1608,190 @@ get_return_value (struct value *function, struct type *value_type)
       internal_error (__FILE__, __LINE__, _("bad switch"));
     }
 
-  do_cleanups (cleanup);
-
   return value;
 }
 
-/* Print the result of a function at the end of a 'finish' command.  */
+/* The captured function return value/type and its position in the
+   value history.  */
+
+struct return_value_info
+{
+  /* The captured return value.  May be NULL if we weren't able to
+     retrieve it.  See get_return_value.  */
+  struct value *value;
+
+  /* The return type.  In some cases, we'll not be able extract the
+     return value, but we always know the type.  */
+  struct type *type;
+
+  /* If we captured a value, this is the value history index.  */
+  int value_history_index;
+};
+
+/* Helper for print_return_value.  */
+
+static void
+print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
+{
+  if (rv->value != NULL)
+    {
+      struct value_print_options opts;
+
+      /* Print it.  */
+      uiout->text ("Value returned is ");
+      uiout->field_fmt ("gdb-result-var", "$%d",
+                        rv->value_history_index);
+      uiout->text (" = ");
+      get_user_print_options (&opts);
+
+      if (opts.finish_print)
+       {
+         string_file stb;
+         value_print (rv->value, &stb, &opts);
+         uiout->field_stream ("return-value", stb);
+       }
+      else
+       uiout->field_string ("return-value", _("<not displayed>"),
+                            metadata_style.style ());
+      uiout->text ("\n");
+    }
+  else
+    {
+      std::string type_name = type_to_string (rv->type);
+      uiout->text ("Value returned has type: ");
+      uiout->field_string ("return-type", type_name.c_str ());
+      uiout->text (".");
+      uiout->text (" Cannot determine contents\n");
+    }
+}
+
+/* Print the result of a function at the end of a 'finish' command.
+   RV points at an object representing the captured return value/type
+   and its position in the value history.  */
 
-static void
-print_return_value (struct value *function, struct type *value_type)
+void
+print_return_value (struct ui_out *uiout, struct return_value_info *rv)
 {
-  struct value *value = get_return_value (function, value_type);
-  struct ui_out *uiout = current_uiout;
+  if (rv->type == NULL
+      || TYPE_CODE (check_typedef (rv->type)) == TYPE_CODE_VOID)
+    return;
 
-  if (value)
+  try
     {
-      struct value_print_options opts;
-      struct ui_file *stb;
-      struct cleanup *old_chain;
-
-      /* Print it.  */
-      stb = mem_fileopen ();
-      old_chain = make_cleanup_ui_file_delete (stb);
-      ui_out_text (uiout, "Value returned is ");
-      ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
-                       record_latest_value (value));
-      ui_out_text (uiout, " = ");
-      get_raw_print_options (&opts);
-      value_print (value, stb, &opts);
-      ui_out_field_stream (uiout, "return-value", stb);
-      ui_out_text (uiout, "\n");
-      do_cleanups (old_chain);
+      /* print_return_value_1 can throw an exception in some
+        circumstances.  We need to catch this so that we still
+        delete the breakpoint.  */
+      print_return_value_1 (uiout, rv);
     }
-  else
+  catch (const gdb_exception &ex)
     {
-      ui_out_text (uiout, "Value returned has type: ");
-      ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
-      ui_out_text (uiout, ".");
-      ui_out_text (uiout, " Cannot determine contents\n");
+      exception_print (gdb_stdout, ex);
     }
 }
 
-/* Stuff that needs to be done by the finish command after the target
-   has stopped.  In asynchronous mode, we wait for the target to stop
-   in the call to poll or select in the event loop, so it is
-   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.  */
+/* Data for the FSM that manages the finish command.  */
 
-struct finish_command_continuation_args
+struct finish_command_fsm : public thread_fsm
 {
-  /* The thread that as current when the command was executed.  */
-  int thread;
-  struct breakpoint *breakpoint;
-  struct symbol *function;
+  /* The momentary breakpoint set at the function's return address in
+     the caller.  */
+  breakpoint_up breakpoint;
+
+  /* The function that we're stepping out of.  */
+  struct symbol *function = nullptr;
+
+  /* If the FSM finishes successfully, this stores the function's
+     return value.  */
+  struct return_value_info return_value_info {};
+
+  explicit finish_command_fsm (struct interp *cmd_interp)
+    : thread_fsm (cmd_interp)
+  {
+  }
+
+  bool should_stop (struct thread_info *thread) override;
+  void clean_up (struct thread_info *thread) override;
+  struct return_value_info *return_value () override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-static void
-finish_command_continuation (void *arg, int err)
+/* Implementation of the 'should_stop' FSM method for the finish
+   commands.  Detects whether the thread stepped out of the function
+   successfully, and if so, captures the function's return value and
+   marks the FSM finished.  */
+
+bool
+finish_command_fsm::should_stop (struct thread_info *tp)
 {
-  struct finish_command_continuation_args *a = arg;
+  struct return_value_info *rv = &return_value_info;
 
-  if (!err)
+  if (function != NULL
+      && bpstat_find_breakpoint (tp->control.stop_bpstat,
+                                breakpoint.get ()) != NULL)
     {
-      struct thread_info *tp = NULL;
-      bpstat bs = NULL;
+      /* We're done.  */
+      set_finished ();
 
-      if (!ptid_equal (inferior_ptid, null_ptid)
-         && target_has_execution
-         && is_stopped (inferior_ptid))
-       {
-         tp = inferior_thread ();
-         bs = tp->control.stop_bpstat;
-       }
+      rv->type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
+      if (rv->type == NULL)
+       internal_error (__FILE__, __LINE__,
+                       _("finish_command: function has no target type"));
 
-      if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
-         && a->function != NULL)
+      if (TYPE_CODE (check_typedef (rv->type)) != TYPE_CODE_VOID)
        {
-         struct type *value_type;
+         struct value *func;
 
-         value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
-         if (!value_type)
-           internal_error (__FILE__, __LINE__,
-                           _("finish_command: function has no target type"));
+         func = read_var_value (function, NULL, get_current_frame ());
+         rv->value = get_return_value (func, rv->type);
+         if (rv->value != NULL)
+           rv->value_history_index = record_latest_value (rv->value);
+       }
+    }
+  else if (tp->control.stop_step)
+    {
+      /* Finishing from an inline frame, or reverse finishing.  In
+        either case, there's no way to retrieve the return value.  */
+      set_finished ();
+    }
 
-         if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
-           {
-             volatile struct gdb_exception ex;
-             struct value *func;
+  return true;
+}
 
-             func = read_var_value (a->function, get_current_frame ());
-             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 (func, value_type);
-               }
-             if (ex.reason < 0)
-               exception_print (gdb_stdout, ex);
-           }
-       }
+/* Implementation of the 'clean_up' FSM method for the finish
+   commands.  */
 
-      /* We suppress normal call of normal_stop observer and do it
-        here so that the *stopped notification includes the return
-        value.  */
-      if (bs != NULL && tp->control.proceed_to_finish)
-       observer_notify_normal_stop (bs, 1 /* print frame */);
-    }
+void
+finish_command_fsm::clean_up (struct thread_info *thread)
+{
+  breakpoint.reset ();
+  delete_longjmp_breakpoint (thread->global_num);
+}
+
+/* Implementation of the 'return_value' FSM method for the finish
+   commands.  */
 
-  delete_breakpoint (a->breakpoint);
-  delete_longjmp_breakpoint (a->thread);
+struct return_value_info *
+finish_command_fsm::return_value ()
+{
+  return &return_value_info;
 }
 
-static void
-finish_command_continuation_free_arg (void *arg)
+/* Implementation of the 'async_reply_reason' FSM method for the
+   finish commands.  */
+
+enum async_reply_reason
+finish_command_fsm::do_async_reply_reason ()
 {
-  xfree (arg);
+  if (execution_direction == EXEC_REVERSE)
+    return EXEC_ASYNC_END_STEPPING_RANGE;
+  else
+    return EXEC_ASYNC_FUNCTION_FINISHED;
 }
 
 /* finish_backward -- helper function for finish_command.  */
 
 static void
-finish_backward (struct symbol *function)
+finish_backward (struct finish_command_fsm *sm)
 {
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
@@ -1622,8 +1801,7 @@ finish_backward (struct symbol *function)
   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."));
+    error (_("Cannot find bounds of current function"));
 
   sal = find_pc_line (func_addr, 0);
 
@@ -1641,82 +1819,89 @@ finish_backward (struct symbol *function)
     {
       struct frame_info *frame = get_selected_frame (NULL);
       struct gdbarch *gdbarch = get_frame_arch (frame);
-      struct symtab_and_line sr_sal;
 
       /* Set a step-resume at the function's entry point.  Once that's
         hit, we'll do one more step backwards.  */
-      init_sal (&sr_sal);
+      symtab_and_line sr_sal;
       sr_sal.pc = sal.pc;
       sr_sal.pspace = get_frame_program_space (frame);
       insert_step_resume_breakpoint_at_sal (gdbarch,
                                            sr_sal, null_frame_id);
 
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
   else
     {
       /* 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, GDB_SIGNAL_DEFAULT, 1);
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
 }
 
-/* finish_forward -- helper function for finish_command.  */
+/* finish_forward -- helper function for finish_command.  FRAME is the
+   frame that called the function we're about to step out of.  */
 
 static void
-finish_forward (struct symbol *function, struct frame_info *frame)
+finish_forward (struct finish_command_fsm *sm, struct frame_info *frame)
 {
   struct frame_id frame_id = get_frame_id (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);
+  sm->breakpoint = set_momentary_breakpoint (gdbarch, sal,
+                                            get_stack_frame_id (frame),
+                                            bp_finish);
 
   /* set_momentary_breakpoint invalidates FRAME.  */
   frame = NULL;
 
-  old_chain = make_cleanup_delete_breakpoint (breakpoint);
-
   set_longjmp_breakpoint (tp, frame_id);
-  make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
 
-  /* We want stop_registers, please...  */
+  /* We want to print return value, please...  */
   tp->control.proceed_to_finish = 1;
-  cargs = xmalloc (sizeof (*cargs));
 
-  cargs->thread = thread;
-  cargs->breakpoint = breakpoint;
-  cargs->function = function;
-  add_continuation (tp, finish_command_continuation, cargs,
-                    finish_command_continuation_free_arg);
-  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
+}
+
+/* Skip frames for "finish".  */
+
+static struct frame_info *
+skip_finish_frames (struct frame_info *frame)
+{
+  struct frame_info *start;
+
+  do
+    {
+      start = frame;
+
+      frame = skip_tailcall_frames (frame);
+      if (frame == NULL)
+       break;
+
+      frame = skip_unwritable_frames (frame);
+      if (frame == NULL)
+       break;
+    }
+  while (start != frame);
 
-  discard_cleanups (old_chain);
-  if (!target_can_async_p ())
-    do_all_continuations (0);
+  return frame;
 }
 
 /* "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)
+finish_command (const char *arg, int from_tty)
 {
   struct frame_info *frame;
-  struct symbol *function;
-
-  int async_exec = 0;
+  int async_exec;
+  struct finish_command_fsm *sm;
+  struct thread_info *tp;
 
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
@@ -1724,21 +1909,10 @@ finish_command (char *arg, int from_tty)
   ensure_not_running ();
 
   /* 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.  */
-  if (async_exec && !target_can_async_p ())
-    error (_("Asynchronous execution not supported on this target."));
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
+  arg = stripped.get ();
 
-  /* 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 ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-    }
+  prepare_execution_command (current_top_target (), async_exec);
 
   if (arg)
     error (_("The \"finish\" command does not take any arguments."));
@@ -1747,11 +1921,16 @@ finish_command (char *arg, int from_tty)
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
 
-  clear_proceed_status ();
+  clear_proceed_status (0);
+
+  tp = inferior_thread ();
+
+  sm = new finish_command_fsm (command_interp ());
+
+  tp->thread_fsm = sm;
 
   /* 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.  */
+     try to show the "return value" - no way to locate it.  */
   if (get_frame_type (get_selected_frame (_("No selected frame.")))
       == INLINE_FRAME)
     {
@@ -1760,11 +1939,7 @@ finish_command (char *arg, int from_tty)
         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;
-
-      init_sal (&empty_sal);
-      set_step_info (frame, empty_sal);
+      set_step_info (frame, {});
       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;
@@ -1774,21 +1949,16 @@ finish_command (char *arg, int from_tty)
       if (from_tty)
        {
          printf_filtered (_("Run till exit from "));
-         print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+         print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
        }
 
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
       return;
     }
 
-  /* Ignore TAILCALL_FRAME type frames, they were executed already before
-     entering THISFRAME.  */
-  while (get_frame_type (frame) == TAILCALL_FRAME)
-    frame = get_prev_frame (frame);
-
   /* Find the function we will return from.  */
 
-  function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
+  sm->function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
 
   /* Print info on the selected frame, including level number but not
      source.  */
@@ -1797,25 +1967,39 @@ finish_command (char *arg, int from_tty)
       if (execution_direction == EXEC_REVERSE)
        printf_filtered (_("Run back to call of "));
       else
-       printf_filtered (_("Run till exit from "));
+       {
+         if (sm->function != NULL && TYPE_NO_RETURN (sm->function->type)
+             && !query (_("warning: Function %s does not return normally.\n"
+                          "Try to finish anyway? "),
+                        sm->function->print_name ()))
+           error (_("Not confirmed."));
+         printf_filtered (_("Run till exit from "));
+       }
 
-      print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+      print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
     }
 
   if (execution_direction == EXEC_REVERSE)
-    finish_backward (function);
+    finish_backward (sm);
   else
-    finish_forward (function, frame);
+    {
+      frame = skip_finish_frames (frame);
+
+      if (frame == NULL)
+       error (_("Cannot find the caller frame."));
+
+      finish_forward (sm, frame);
+    }
 }
 \f
 
 static void
-program_info (char *args, int from_tty)
+info_program_command (const char *args, int from_tty)
 {
   bpstat bs;
   int num, stat;
-  struct thread_info *tp;
   ptid_t ptid;
+  process_stratum_target *proc_target;
 
   if (!target_has_execution)
     {
@@ -1824,26 +2008,29 @@ program_info (char *args, int from_tty)
     }
 
   if (non_stop)
-    ptid = inferior_ptid;
-  else
     {
-      struct target_waitstatus ws;
-
-      get_last_target_status (&ptid, &ws);
+      ptid = inferior_ptid;
+      proc_target = current_inferior ()->process_target ();
     }
+  else
+    get_last_target_status (&proc_target, &ptid, nullptr);
+
+  if (ptid == null_ptid || ptid == minus_one_ptid)
+    error (_("No selected thread."));
 
-  if (ptid_equal (ptid, null_ptid) || is_exited (ptid))
+  thread_info *tp = find_thread_ptid (proc_target, ptid);
+
+  if (tp->state == THREAD_EXITED)
     error (_("Invalid selected thread."));
-  else if (is_running (ptid))
+  else if (tp->state == THREAD_RUNNING)
     error (_("Selected thread is running."));
 
-  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"),
-                  paddress (target_gdbarch (), stop_pc));
+                  paddress (target_gdbarch (), tp->suspend.stop_pc));
   if (tp->control.stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
@@ -1869,7 +2056,7 @@ program_info (char *args, int from_tty)
                       gdb_signal_to_string (tp->suspend.stop_signal));
     }
 
-  if (!from_tty)
+  if (from_tty)
     {
       printf_filtered (_("Type \"info stack\" or \"info "
                         "registers\" for more information.\n"));
@@ -1877,11 +2064,11 @@ program_info (char *args, int from_tty)
 }
 \f
 static void
-environment_info (char *var, int from_tty)
+environment_info (const char *var, int from_tty)
 {
   if (var)
     {
-      char *val = get_in_environ (current_inferior ()->environment, var);
+      const char *val = current_inferior ()->environment.get (var);
 
       if (val)
        {
@@ -1899,26 +2086,26 @@ environment_info (char *var, int from_tty)
     }
   else
     {
-      char **vector = environ_vector (current_inferior ()->environment);
+      char **envp = current_inferior ()->environment.envp ();
 
-      while (*vector)
+      for (int idx = 0; envp[idx] != NULL; ++idx)
        {
-         puts_filtered (*vector++);
+         puts_filtered (envp[idx]);
          puts_filtered ("\n");
        }
     }
 }
 
 static void
-set_environment_command (char *arg, int from_tty)
+set_environment_command (const char *arg, int from_tty)
 {
-  char *p, *val, *var;
+  const char *p, *val;
   int nullset = 0;
 
   if (arg == 0)
     error_no_arg (_("environment variable and value"));
 
-  /* Find seperation between variable name and value.  */
+  /* Find separation between variable name and value.  */
   p = (char *) strchr (arg, '=');
   val = (char *) strchr (arg, ' ');
 
@@ -1959,34 +2146,30 @@ set_environment_command (char *arg, int from_tty)
   while (p != arg && (p[-1] == ' ' || p[-1] == '\t'))
     p--;
 
-  var = savestring (arg, p - arg);
+  std::string var (arg, p - arg);
   if (nullset)
     {
       printf_filtered (_("Setting environment variable "
                         "\"%s\" to null value.\n"),
-                      var);
-      set_in_environ (current_inferior ()->environment, var, "");
+                      var.c_str ());
+      current_inferior ()->environment.set (var.c_str (), "");
     }
   else
-    set_in_environ (current_inferior ()->environment, var, val);
-  xfree (var);
+    current_inferior ()->environment.set (var.c_str (), val);
 }
 
 static void
-unset_environment_command (char *var, int from_tty)
+unset_environment_command (const char *var, int from_tty)
 {
   if (var == 0)
     {
       /* If there is no argument, delete all environment variables.
          Ask for confirmation if reading from the terminal.  */
       if (!from_tty || query (_("Delete all environment variables? ")))
-       {
-         free_environ (current_inferior ()->environment);
-         current_inferior ()->environment = make_environ ();
-       }
+       current_inferior ()->environment.clear ();
     }
   else
-    unset_in_environ (current_inferior ()->environment, var);
+    current_inferior ()->environment.unset (var);
 }
 
 /* Handle the execution path (PATH variable).  */
@@ -1994,36 +2177,45 @@ unset_environment_command (char *var, int from_tty)
 static const char path_var_name[] = "PATH";
 
 static void
-path_info (char *args, int from_tty)
+path_info (const char *args, int from_tty)
 {
   puts_filtered ("Executable and object file path: ");
-  puts_filtered (get_in_environ (current_inferior ()->environment,
-                                path_var_name));
+  puts_filtered (current_inferior ()->environment.get (path_var_name));
   puts_filtered ("\n");
 }
 
 /* Add zero or more directories to the front of the execution path.  */
 
 static void
-path_command (char *dirname, int from_tty)
+path_command (const char *dirname, int from_tty)
 {
   char *exec_path;
-  char *env;
+  const char *env;
 
   dont_repeat ();
-  env = get_in_environ (current_inferior ()->environment, path_var_name);
+  env = current_inferior ()->environment.get (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 (current_inferior ()->environment, path_var_name, exec_path);
+  current_inferior ()->environment.set (path_var_name, exec_path);
   xfree (exec_path);
   if (from_tty)
-    path_info ((char *) NULL, from_tty);
+    path_info (NULL, from_tty);
 }
 \f
 
+static void
+pad_to_column (string_file &stream, int col)
+{
+  /* At least one space must be printed to separate columns.  */
+  stream.putc (' ');
+  const int size = stream.size ();
+  if (size < col)
+    stream.puts (n_spaces (col - size));
+}
+
 /* Print out the register NAME with value VAL, to FILE, in the default
    fashion.  */
 
@@ -2033,46 +2225,46 @@ default_print_one_register_info (struct ui_file *file,
                                 struct value *val)
 {
   struct type *regtype = value_type (val);
+  int print_raw_format;
+  string_file format_stream;
+  enum tab_stops
+    {
+      value_column_1 = 15,
+      /* Give enough room for "0x", 16 hex digits and two spaces in
+         preceding column.  */
+      value_column_2 = value_column_1 + 2 + 16 + 2,
+    };
 
-  fputs_filtered (name, file);
-  print_spaces_filtered (15 - strlen (name), file);
+  format_stream.puts (name);
+  pad_to_column (format_stream, value_column_1);
 
-  if (!value_entirely_available (val))
-    {
-      fprintf_filtered (file, "*value not available*\n");
-      return;
-    }
+  print_raw_format = (value_entirely_available (val)
+                     && !value_optimized_out (val));
 
   /* If virtual format is floating, print it that way, and in raw
      hex.  */
   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);
-      enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype));
+      enum bfd_endian byte_order = type_byte_order (regtype);
 
       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);
+                &format_stream, 0, val, &opts, current_language);
 
-      fprintf_filtered (file, "\t(raw 0x");
-      for (j = 0; j < TYPE_LENGTH (regtype); j++)
+      if (print_raw_format)
        {
-         int idx;
-
-         if (byte_order == BFD_ENDIAN_BIG)
-           idx = j;
-         else
-           idx = TYPE_LENGTH (regtype) - 1 - j;
-         fprintf_filtered (file, "%02x", (unsigned char) valaddr[idx]);
+         pad_to_column (format_stream, value_column_2);
+         format_stream.puts ("(raw ");
+         print_hex_chars (&format_stream, valaddr, TYPE_LENGTH (regtype),
+                          byte_order, true);
+         format_stream.putc (')');
        }
-      fprintf_filtered (file, ")");
     }
   else
     {
@@ -2082,23 +2274,22 @@ default_print_one_register_info (struct ui_file *file,
       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);
+                &format_stream, 0, val, &opts, current_language);
       /* If not a vector register, print it also according to its
         natural format.  */
-      if (TYPE_VECTOR (regtype) == 0)
+      if (print_raw_format && TYPE_VECTOR (regtype) == 0)
        {
+         pad_to_column (format_stream, value_column_2);
          get_user_print_options (&opts);
          opts.deref_ref = 1;
-         fprintf_filtered (file, "\t");
          val_print (regtype,
-                    value_contents_for_printing (val),
                     value_embedded_offset (val), 0,
-                    file, 0, val, &opts, current_language);
+                    &format_stream, 0, val, &opts, current_language);
        }
     }
 
+  fputs_filtered (format_stream.c_str (), file);
   fprintf_filtered (file, "\n");
 }
 
@@ -2120,14 +2311,10 @@ default_print_registers_info (struct gdbarch *gdbarch,
                              int regnum, int print_all)
 {
   int i;
-  const int numregs = gdbarch_num_regs (gdbarch)
-                     + gdbarch_num_pseudo_regs (gdbarch);
+  const int numregs = gdbarch_num_cooked_regs (gdbarch);
 
   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)
@@ -2155,21 +2342,14 @@ default_print_registers_info (struct gdbarch *gdbarch,
          || *(gdbarch_register_name (gdbarch, i)) == '\0')
        continue;
 
-      regtype = register_type (gdbarch, i);
-      val = allocate_value (regtype);
-
-      /* Get the data in raw format.  */
-      if (! deprecated_frame_register_read (frame, i, value_contents_raw (val)))
-       mark_value_bytes_unavailable (val, 0, TYPE_LENGTH (value_type (val)));
-
       default_print_one_register_info (file,
                                       gdbarch_register_name (gdbarch, i),
-                                      val);
+                                      value_of_register (i, frame));
     }
 }
 
 void
-registers_info (char *addr_exp, int fpregs)
+registers_info (const char *addr_exp, int fpregs)
 {
   struct frame_info *frame;
   struct gdbarch *gdbarch;
@@ -2188,15 +2368,11 @@ registers_info (char *addr_exp, int fpregs)
 
   while (*addr_exp != '\0')
     {
-      char *start;
+      const char *start;
       const char *end;
 
-      /* Keep skipping leading white space.  */
-      if (isspace ((*addr_exp)))
-       {
-         addr_exp++;
-         continue;
-       }
+      /* Skip leading white space.  */
+      addr_exp = skip_spaces (addr_exp);
 
       /* Discard any leading ``$''.  Check that there is something
          resembling a register following it.  */
@@ -2222,8 +2398,7 @@ registers_info (char *addr_exp, int fpregs)
            /* User registers lie completely outside of the range of
               normal registers.  Catch them early so that the target
               never sees them.  */
-           if (regnum >= gdbarch_num_regs (gdbarch)
-                         + gdbarch_num_pseudo_regs (gdbarch))
+           if (regnum >= gdbarch_num_cooked_regs (gdbarch))
              {
                struct value *regval = value_of_user_reg (regnum, frame);
                const char *regname = user_reg_map_regnum_to_name (gdbarch,
@@ -2262,8 +2437,7 @@ registers_info (char *addr_exp, int fpregs)
            int regnum;
 
            for (regnum = 0;
-                regnum < gdbarch_num_regs (gdbarch)
-                         + gdbarch_num_pseudo_regs (gdbarch);
+                regnum < gdbarch_num_cooked_regs (gdbarch);
                 regnum++)
              {
                if (gdbarch_register_reggroup_p (gdbarch, regnum, group))
@@ -2281,13 +2455,13 @@ registers_info (char *addr_exp, int fpregs)
 }
 
 static void
-all_registers_info (char *addr_exp, int from_tty)
+info_all_registers_command (const char *addr_exp, int from_tty)
 {
   registers_info (addr_exp, 1);
 }
 
 static void
-nofp_registers_info (char *addr_exp, int from_tty)
+info_registers_command (const char *addr_exp, int from_tty)
 {
   registers_info (addr_exp, 0);
 }
@@ -2305,10 +2479,7 @@ print_vector_info (struct ui_file *file,
       int regnum;
       int printed_something = 0;
 
-      for (regnum = 0;
-          regnum < gdbarch_num_regs (gdbarch)
-                   + gdbarch_num_pseudo_regs (gdbarch);
-          regnum++)
+      for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
        {
          if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup))
            {
@@ -2322,7 +2493,7 @@ print_vector_info (struct ui_file *file,
 }
 
 static void
-vector_info (char *args, int from_tty)
+info_vector_command (const char *args, int from_tty)
 {
   if (!target_has_registers)
     error (_("The program has no registers now."));
@@ -2333,125 +2504,71 @@ vector_info (char *args, int from_tty)
 /* Kill the inferior process.  Make us have no inferior.  */
 
 static void
-kill_command (char *arg, int from_tty)
+kill_command (const 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))
+  if (inferior_ptid == null_ptid)
     error (_("The program is not being run."));
   if (!query (_("Kill the program being debugged? ")))
     error (_("Not confirmed."));
+
+  int pid = current_inferior ()->pid;
+  /* Save the pid as a string before killing the inferior, since that
+     may unpush the current target, and we need the string after.  */
+  std::string pid_str = target_pid_to_str (ptid_t (pid));
+  int infnum = current_inferior ()->num;
+
   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.  */
+  if (print_inferior_events)
+    printf_unfiltered (_("[Inferior %d (%s) killed]\n"),
+                      infnum, pid_str.c_str ());
 
-      /* 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
+/* Used in `attach&' command.  Proceed threads of inferior INF iff
    they stopped due to debugger request, and when they did, they
-   reported a clean stop (GDB_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 == GDB_SIGNAL_0)
-    {
-      switch_to_thread (thread->ptid);
-      clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
-    }
-
-  return 0;
-}
+   reported a clean stop (GDB_SIGNAL_0).  Do not proceed threads that
+   have been explicitly been told to stop.  */
 
 static void
-proceed_after_attach (int pid)
+proceed_after_attach (inferior *inf)
 {
   /* 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 ();
+  scoped_restore_current_thread restore_thread;
 
-  iterate_over_threads (proceed_after_attach_callback, &pid);
-
-  /* Restore selected ptid.  */
-  do_cleanups (old_chain);
+  for (thread_info *thread : inf->non_exited_threads ())
+    if (!thread->executing
+       && !thread->stop_requested
+       && thread->suspend.stop_signal == GDB_SIGNAL_0)
+      {
+       switch_to_thread (thread);
+       clear_proceed_status (0);
+       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
+      }
 }
 
-/*
- * TODO:
- * Should save/restore the tty state since it might be that the
- * program to be debugged was started on this tty and it wants
- * the tty in some state other than what we want.  If it's running
- * on another terminal or without a terminal, then saving and
- * restoring the tty state is a harmless no-op.
- * This only needs to be done if we are attaching to a process.
- */
-
-/* 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.  */
+/* See inferior.h.  */
 
-static void
-attach_command_post_wait (char *args, int from_tty, int async_exec)
+void
+setup_inferior (int from_tty)
 {
-  char *exec_file;
-  char *full_exec_path = NULL;
   struct inferior *inferior;
 
   inferior = current_inferior ();
-  inferior->control.stop_soon = NO_STOP_QUIETLY;
+  inferior->needs_setup = 0;
 
   /* If no exec file is yet known, try to determine it from the
      process itself.  */
-  exec_file = (char *) get_exec_file (0);
-  if (!exec_file)
-    {
-      exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid));
-      if (exec_file)
-       {
-         /* It's possible we don't have a full path, but rather just a
-            filename.  Some targets, such as HP-UX, don't provide the
-            full path, sigh.
-
-            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...)  */
-
-         if (!source_full_path_of (exec_file, &full_exec_path))
-           full_exec_path = xstrdup (exec_file);
-
-         exec_file_attach (full_exec_path, from_tty);
-         symbol_file_add_main (full_exec_path, from_tty);
-       }
-    }
+  if (get_exec_file (0) == NULL)
+    exec_file_locate_attach (inferior_ptid.pid (), 1, from_tty);
   else
     {
       reopen_exec_file ();
@@ -2459,14 +2576,40 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
     }
 
   /* Take any necessary post-attaching actions for this platform.  */
-  target_post_attach (PIDGET (inferior_ptid));
+  target_post_attach (inferior_ptid.pid ());
+
+  post_create_inferior (current_top_target (), from_tty);
+}
+
+/* What to do after the first program stops after attaching.  */
+enum attach_post_wait_mode
+{
+  /* Do nothing.  Leaves threads as they are.  */
+  ATTACH_POST_WAIT_NOTHING,
+
+  /* Re-resume threads that are marked running.  */
+  ATTACH_POST_WAIT_RESUME,
+
+  /* Stop all threads.  */
+  ATTACH_POST_WAIT_STOP,
+};
+
+/* Called after we've attached to a process and we've seen it stop for
+   the first time.  If ASYNC_EXEC is true, re-resume threads that
+   should be running.  Else if ATTACH, */
+
+static void
+attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mode)
+{
+  struct inferior *inferior;
 
-  post_create_inferior (&current_target, from_tty);
+  inferior = current_inferior ();
+  inferior->control.stop_soon = NO_STOP_QUIETLY;
 
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
+  if (inferior->needs_setup)
+    setup_inferior (from_tty);
 
-  if (async_exec)
+  if (mode == ATTACH_POST_WAIT_RESUME)
     {
       /* The user requested an `attach&', so be sure to leave threads
         that didn't get a signal running.  */
@@ -2476,24 +2619,21 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
         already running threads.  If a thread has been stopped with a
         signal, leave it be.  */
       if (non_stop)
-       proceed_after_attach (inferior->pid);
+       proceed_after_attach (inferior);
       else
        {
          if (inferior_thread ()->suspend.stop_signal == GDB_SIGNAL_0)
            {
-             clear_proceed_status ();
-             proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+             clear_proceed_status (0);
+             proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
            }
        }
     }
-  else
+  else if (mode == ATTACH_POST_WAIT_STOP)
     {
       /* 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
@@ -2502,7 +2642,24 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
         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));
+       target_stop (ptid_t (inferior->pid));
+      else if (target_is_non_stop_p ())
+       {
+         struct thread_info *lowest = inferior_thread ();
+
+         stop_all_threads ();
+
+         /* It's not defined which thread will report the attach
+            stop.  For consistency, always select the thread with
+            lowest GDB number, which should be the main thread, if it
+            still exists.  */
+         for (thread_info *thread : current_inferior ()->non_exited_threads ())
+           if (thread->inf->num < lowest->inf->num
+               || thread->per_inf_num < lowest->per_inf_num)
+             lowest = thread;
+
+         switch_to_thread (lowest);
+       }
 
       /* Tell the user/frontend where we're stopped.  */
       normal_stop ();
@@ -2515,34 +2672,42 @@ struct attach_command_continuation_args
 {
   char *args;
   int from_tty;
-  int async_exec;
+  enum attach_post_wait_mode mode;
 };
 
 static void
 attach_command_continuation (void *args, int err)
 {
-  struct attach_command_continuation_args *a = args;
+  struct attach_command_continuation_args *a
+    = (struct attach_command_continuation_args *) args;
 
   if (err)
     return;
 
-  attach_command_post_wait (a->args, a->from_tty, a->async_exec);
+  attach_post_wait (a->args, a->from_tty, a->mode);
 }
 
 static void
 attach_command_continuation_free_args (void *args)
 {
-  struct attach_command_continuation_args *a = args;
+  struct attach_command_continuation_args *a
+    = (struct attach_command_continuation_args *) args;
 
   xfree (a->args);
   xfree (a);
 }
 
+/* "attach" command entry point.  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.  */
+
 void
-attach_command (char *args, int from_tty)
+attach_command (const char *args, int from_tty)
 {
-  int async_exec = 0;
-  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+  int async_exec;
+  struct target_ops *attach_target;
+  struct inferior *inferior = current_inferior ();
+  enum attach_post_wait_mode mode;
 
   dont_repeat ();              /* Not for the faint of heart */
 
@@ -2562,40 +2727,49 @@ attach_command (char *args, int from_tty)
      this function should probably be moved into target_pre_inferior.  */
   target_pre_inferior (from_tty);
 
-  if (non_stop && !target_supports_non_stop ())
-    error (_("Cannot attach to this target in non-stop mode"));
+  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
+  args = stripped.get ();
 
-  if (args)
-    {
-      async_exec = strip_bg_char (&args);
+  attach_target = find_attach_target ();
 
-      /* If we get a request for running in the bg but the target
-         doesn't support it, error out.  */
-      if (async_exec && !target_can_async_p ())
-       error (_("Asynchronous execution not supported on this target."));
-    }
+  prepare_execution_command (attach_target, async_exec);
 
-  /* If we don't get a request of running in the bg, then we need
-     to simulate synchronous (fg) execution.  */
-  if (!async_exec && target_can_async_p ())
-    {
-      /* Simulate synchronous execution.  */
-      async_disable_stdin ();
-      make_cleanup ((make_cleanup_ftype *)async_enable_stdin, NULL);
-    }
+  if (non_stop && !attach_target->supports_non_stop ())
+    error (_("Cannot attach to this target in non-stop mode"));
 
-  target_attach (args, from_tty);
+  attach_target->attach (args, from_tty);
+  /* to_attach should push the target, so after this point we
+     shouldn't refer to attach_target again.  */
+  attach_target = NULL;
 
   /* Set up the "saved terminal modes" of the inferior
      based on what modes we are starting it with.  */
-  target_terminal_init ();
+  target_terminal::init ();
+
+  /* Install inferior's terminal modes.  This may look like a no-op,
+     as we've just saved them above, however, this does more than
+     restore terminal settings:
+
+     - installs a SIGINT handler that forwards SIGINT to the inferior.
+       Otherwise a Ctrl-C pressed just while waiting for the initial
+       stop would end up as a spurious Quit.
+
+     - removes stdin from the event loop, which we need if attaching
+       in the foreground, otherwise on targets that report an initial
+       stop on attach (which are most) we'd process input/commands
+       while we're in the event loop waiting for that stop.  That is,
+       before the attach continuation runs and the command is really
+       finished.  */
+  target_terminal::inferior ();
 
   /* Set up execution context to know that we should return from
      wait_for_inferior as soon as the target reports a stop.  */
   init_wait_for_inferior ();
-  clear_proceed_status ();
+  clear_proceed_status (0);
 
-  if (non_stop)
+  inferior->needs_setup = 1;
+
+  if (target_is_non_stop_p ())
     {
       /* If we find that the current thread isn't stopped, explicitly
         do so now, because we're going to install breakpoints and
@@ -2607,14 +2781,16 @@ attach_command (char *args, int from_tty)
       else
        /* The user requested an `attach', so stop all threads of this
           inferior.  */
-       target_stop (pid_to_ptid (ptid_get_pid (inferior_ptid)));
+       target_stop (ptid_t (inferior_ptid.pid ()));
     }
 
+  mode = async_exec ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_STOP;
+
   /* Some system don't generate traps when attaching to inferior.
      E.g. Mach 3 or GNU hurd.  */
-  if (!target_attach_no_wait)
+  if (!target_attach_no_wait ())
     {
-      struct inferior *inferior = current_inferior ();
+      struct attach_command_continuation_args *a;
 
       /* Careful here.  See comments in inferior.h.  Basically some
         OSes don't ignore SIGSTOPs on continue requests anymore.  We
@@ -2623,26 +2799,24 @@ attach_command (char *args, int from_tty)
         STOP_QUIETLY_NO_SIGSTOP is for.  */
       inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
 
-      if (target_can_async_p ())
-       {
-         /* sync_execution mode.  Wait for stop.  */
-         struct attach_command_continuation_args *a;
-
-         a = xmalloc (sizeof (*a));
-         a->args = xstrdup (args);
-         a->from_tty = from_tty;
-         a->async_exec = async_exec;
-         add_inferior_continuation (attach_command_continuation, a,
-                                    attach_command_continuation_free_args);
-         discard_cleanups (back_to);
-         return;
-       }
+      /* Wait for stop.  */
+      a = XNEW (struct attach_command_continuation_args);
+      a->args = xstrdup (args);
+      a->from_tty = from_tty;
+      a->mode = mode;
+      add_inferior_continuation (attach_command_continuation, a,
+                                attach_command_continuation_free_args);
 
-      wait_for_inferior ();
-    }
+      /* Let infrun consider waiting for events out of this
+        target.  */
+      inferior->process_target ()->threads_executing = true;
 
-  attach_command_post_wait (args, from_tty, async_exec);
-  discard_cleanups (back_to);
+      if (!target_is_async_p ())
+       mark_infrun_async_event_handler ();
+      return;
+    }
+  else
+    attach_post_wait (args, from_tty, mode);
 }
 
 /* We had just found out that the target was already attached to an
@@ -2654,29 +2828,26 @@ attach_command (char *args, int from_tty)
    as stopped.  */
 
 void
-notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
+notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
 {
-  struct cleanup* old_chain;
-  int async_exec;
-
-  old_chain = make_cleanup (null_cleanup, NULL);
+  enum attach_post_wait_mode mode
+    = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
 
-  /* 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 != GDB_SIGNAL_0.  We don't try to
-     resume threads with such a stop signal.  */
-  async_exec = non_stop;
+  gdb::optional<scoped_restore_current_thread> restore_thread;
 
-  if (!ptid_equal (inferior_ptid, null_ptid))
-    make_cleanup_restore_current_thread ();
+  if (inferior_ptid != null_ptid)
+    restore_thread.emplace ();
 
-  switch_to_thread (ptid);
+  /* Avoid reading registers -- we haven't fetched the target
+     description yet.  */
+  switch_to_thread_no_regs (thr);
 
   /* 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))
+  if (thr->executing)
     {
+      struct attach_command_continuation_args *a;
       struct inferior *inferior = current_inferior ();
 
       /* We're going to install breakpoints, and poke at memory,
@@ -2687,28 +2858,17 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
       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);
+      a = XNEW (struct attach_command_continuation_args);
+      a->args = xstrdup ("");
+      a->from_tty = from_tty;
+      a->mode = mode;
+      add_inferior_continuation (attach_command_continuation, a,
+                                attach_command_continuation_free_args);
 
-         do_cleanups (old_chain);
-         return;
-       }
-      else
-       wait_for_inferior ();
+      return;
     }
 
-  async_exec = leave_running;
-  attach_command_post_wait ("" /* args */, from_tty, async_exec);
-
-  do_cleanups (old_chain);
+  attach_post_wait ("" /* args */, from_tty, mode);
 }
 
 /*
@@ -2723,27 +2883,31 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
  */
 
 void
-detach_command (char *args, int from_tty)
+detach_command (const char *args, int from_tty)
 {
   dont_repeat ();              /* Not for the faint of heart.  */
 
-  if (ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid == null_ptid)
     error (_("The program is not being run."));
 
-  disconnect_tracing (from_tty);
+  query_if_trace_running (from_tty);
+
+  disconnect_tracing ();
+
+  target_detach (current_inferior (), from_tty);
 
-  target_detach (args, from_tty);
+  /* The current inferior process was just detached successfully.  Get
+     rid of breakpoints that no longer make sense.  Note we don't do
+     this within target_detach because that is also used when
+     following child forks, and in that case we will want to transfer
+     breakpoints to the child, not delete them.  */
+  breakpoint_init_inferior (inf_exited);
 
   /* 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 ();
 }
@@ -2757,10 +2921,11 @@ detach_command (char *args, int from_tty)
    stopped processes on some native platforms (e.g. GNU/Linux).  */
 
 static void
-disconnect_command (char *args, int from_tty)
+disconnect_command (const char *args, int from_tty)
 {
   dont_repeat ();              /* Not for the faint of heart.  */
-  disconnect_tracing (from_tty);
+  query_if_trace_running (from_tty);
+  disconnect_tracing ();
   target_disconnect (args, from_tty);
   no_shared_libraries (NULL, from_tty);
   init_thread_list ();
@@ -2768,15 +2933,14 @@ disconnect_command (char *args, int from_tty)
     deprecated_detach_hook ();
 }
 
-void 
-interrupt_target_1 (int all_threads)
-{
-  ptid_t ptid;
+/* Stop PTID in the current target, and tag the PTID threads as having
+   been explicitly requested to stop.  PTID can be a thread, a
+   process, or minus_one_ptid, meaning all threads of all inferiors of
+   the current target.  */
 
-  if (all_threads)
-    ptid = minus_one_ptid;
-  else
-    ptid = inferior_ptid;
+static void
+stop_current_target_threads_ns (ptid_t ptid)
+{
   target_stop (ptid);
 
   /* Tag the thread as having been explicitly requested to stop, so
@@ -2785,18 +2949,42 @@ interrupt_target_1 (int all_threads)
      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.  */
+  set_stop_requested (current_inferior ()->process_target (),
+                     ptid, 1);
+}
+
+/* See inferior.h.  */
+
+void
+interrupt_target_1 (bool all_threads)
+{
   if (non_stop)
-    set_stop_requested (ptid, 1);
+    {
+      if (all_threads)
+       {
+         scoped_restore_current_thread restore_thread;
+
+         for (inferior *inf : all_inferiors ())
+           {
+             switch_to_inferior_no_thread (inf);
+             stop_current_target_threads_ns (minus_one_ptid);
+           }
+       }
+      else
+       stop_current_target_threads_ns (inferior_ptid);
+    }
+  else
+    target_interrupt ();
 }
 
-/* Stop the execution of the target while running in async mode, in
-   the backgound.  In all-stop, stop the whole process.  In non-stop
+/* interrupt [-a]
+   Stop the execution of the target while running in async mode, in
+   the background.  In all-stop, stop the whole process.  In non-stop
    mode, stop the current thread only by default, or stop all threads
    if the `-a' switch is used.  */
 
-/* interrupt [-a]  */
 static void
-interrupt_target_command (char *args, int from_tty)
+interrupt_command (const char *args, int from_tty)
 {
   if (target_can_async_p ())
     {
@@ -2805,7 +2993,7 @@ interrupt_target_command (char *args, int from_tty)
       dont_repeat ();          /* Not for the faint of heart.  */
 
       if (args != NULL
-         && strncmp (args, "-a", sizeof ("-a") - 1) == 0)
+         && startswith (args, "-a"))
        all_threads = 1;
 
       if (!non_stop && all_threads)
@@ -2815,57 +3003,52 @@ interrupt_target_command (char *args, int from_tty)
     }
 }
 
-static void
-print_float_info (struct ui_file *file,
-                 struct frame_info *frame, const char *args)
+/* See inferior.h.  */
+
+void
+default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
+                         struct frame_info *frame, const char *args)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  int regnum;
+  int printed_something = 0;
 
-  if (gdbarch_print_float_info_p (gdbarch))
-    gdbarch_print_float_info (gdbarch, file, frame, args);
-  else
+  for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
     {
-      int regnum;
-      int printed_something = 0;
-
-      for (regnum = 0;
-          regnum < gdbarch_num_regs (gdbarch)
-                   + gdbarch_num_pseudo_regs (gdbarch);
-          regnum++)
+      if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup))
        {
-         if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup))
-           {
-             printed_something = 1;
-             gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
-           }
+         printed_something = 1;
+         gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
        }
-      if (!printed_something)
-       fprintf_filtered (file, "No floating-point info "
-                         "available for this processor.\n");
     }
+  if (!printed_something)
+    fprintf_filtered (file, "No floating-point info "
+                     "available for this processor.\n");
 }
 
 static void
-float_info (char *args, int from_tty)
+info_float_command (const char *args, int from_tty)
 {
+  struct frame_info *frame;
+
   if (!target_has_registers)
     error (_("The program has no registers now."));
 
-  print_float_info (gdb_stdout, get_selected_frame (NULL), args);
+  frame = get_selected_frame (NULL);
+  gdbarch_print_float_info (get_frame_arch (frame), gdb_stdout, frame, args);
 }
 \f
 static void
-unset_command (char *args, int from_tty)
+unset_command (const char *args, int from_tty)
 {
   printf_filtered (_("\"unset\" must be followed by the "
                     "name of an unset subcommand.\n"));
-  help_list (unsetlist, "unset ", -1, gdb_stdout);
+  help_list (unsetlist, "unset ", all_commands, gdb_stdout);
 }
 
 /* Implement `info proc' family of commands.  */
 
 static void
-info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
+info_proc_cmd_1 (const char *args, enum info_proc_what what, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
 
@@ -2878,10 +3061,10 @@ info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
     }
 }
 
-/* Implement `info proc' when given without any futher parameters.  */
+/* Implement `info proc' when given without any further parameters.  */
 
 static void
-info_proc_cmd (char *args, int from_tty)
+info_proc_cmd (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_MINIMAL, from_tty);
 }
@@ -2889,7 +3072,7 @@ info_proc_cmd (char *args, int from_tty)
 /* Implement `info proc mappings'.  */
 
 static void
-info_proc_cmd_mappings (char *args, int from_tty)
+info_proc_cmd_mappings (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_MAPPINGS, from_tty);
 }
@@ -2897,7 +3080,7 @@ info_proc_cmd_mappings (char *args, int from_tty)
 /* Implement `info proc stat'.  */
 
 static void
-info_proc_cmd_stat (char *args, int from_tty)
+info_proc_cmd_stat (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_STAT, from_tty);
 }
@@ -2905,7 +3088,7 @@ info_proc_cmd_stat (char *args, int from_tty)
 /* Implement `info proc status'.  */
 
 static void
-info_proc_cmd_status (char *args, int from_tty)
+info_proc_cmd_status (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_STATUS, from_tty);
 }
@@ -2913,7 +3096,7 @@ info_proc_cmd_status (char *args, int from_tty)
 /* Implement `info proc cwd'.  */
 
 static void
-info_proc_cmd_cwd (char *args, int from_tty)
+info_proc_cmd_cwd (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_CWD, from_tty);
 }
@@ -2921,7 +3104,7 @@ info_proc_cmd_cwd (char *args, int from_tty)
 /* Implement `info proc cmdline'.  */
 
 static void
-info_proc_cmd_cmdline (char *args, int from_tty)
+info_proc_cmd_cmdline (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_CMDLINE, from_tty);
 }
@@ -2929,36 +3112,78 @@ info_proc_cmd_cmdline (char *args, int from_tty)
 /* Implement `info proc exe'.  */
 
 static void
-info_proc_cmd_exe (char *args, int from_tty)
+info_proc_cmd_exe (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_EXE, from_tty);
 }
 
+/* Implement `info proc files'.  */
+
+static void
+info_proc_cmd_files (const char *args, int from_tty)
+{
+  info_proc_cmd_1 (args, IP_FILES, from_tty);
+}
+
 /* Implement `info proc all'.  */
 
 static void
-info_proc_cmd_all (char *args, int from_tty)
+info_proc_cmd_all (const char *args, int from_tty)
 {
   info_proc_cmd_1 (args, IP_ALL, from_tty);
 }
 
+/* Implement `show print finish'.  */
+
+static void
+show_print_finish (struct ui_file *file, int from_tty,
+                  struct cmd_list_element *c,
+                  const char *value)
+{
+  fprintf_filtered (file, _("\
+Printing of return value after `finish' is %s.\n"),
+                   value);
+}
+
+
+/* This help string is used for the run, start, and starti commands.
+   It is defined as a macro to prevent duplication.  */
+
+#define RUN_ARGS_HELP \
+"You may specify arguments to give it.\n\
+Args may include \"*\", or \"[...]\"; they are expanded using the\n\
+shell that will start the program (specified by the \"$SHELL\" environment\n\
+variable).  Input and output redirection with \">\", \"<\", or \">>\"\n\
+are also allowed.\n\
+\n\
+With no arguments, uses arguments last specified (with \"run\" or \n\
+\"set args\").  To cancel previous arguments and run with no arguments,\n\
+use \"set args\" without arguments.\n\
+\n\
+To start the inferior without using a shell, use \"set startup-with-shell off\"."
+
 void
 _initialize_infcmd (void)
 {
   static struct cmd_list_element *info_proc_cmdlist;
   struct cmd_list_element *c = NULL;
-  char *cmd_name;
+  const char *cmd_name;
 
   /* Add the filename of the terminal connected to inferior I/O.  */
-  add_setshow_filename_cmd ("inferior-tty", class_run,
-                           &inferior_io_terminal_scratch, _("\
+  add_setshow_optional_filename_cmd ("inferior-tty", class_run,
+                                    &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"),
-                           set_inferior_tty_command,
-                           show_inferior_tty_command,
-                           &setlist, &showlist);
-  add_com_alias ("tty", "set inferior-tty", class_alias, 0);
+Usage: set inferior-tty [TTY]\n\n\
+If TTY is omitted, the default behavior of using the same terminal as GDB\n\
+is restored."),
+                                    set_inferior_tty_command,
+                                    show_inferior_tty_command,
+                                    &setlist, &showlist);
+  cmd_name = "inferior-tty";
+  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  gdb_assert (c != NULL);
+  add_alias_cmd ("tty", c, class_alias, 0, &cmdlist);
 
   cmd_name = "args";
   add_setshow_string_noescape_cmd (cmd_name, class_run,
@@ -2973,6 +3198,25 @@ Follow this command with any number of args, to be passed to the program."),
   gdb_assert (c != NULL);
   set_cmd_completer (c, filename_completer);
 
+  cmd_name = "cwd";
+  add_setshow_string_noescape_cmd (cmd_name, class_run,
+                                  &inferior_cwd_scratch, _("\
+Set the current working directory to be used when the inferior is started.\n\
+Changing this setting does not have any effect on inferiors that are\n\
+already running."),
+                                  _("\
+Show the current working directory that is used when the inferior is started."),
+                                  _("\
+Use this command to change the current working directory that will be used\n\
+when the inferior is started.  This setting does not affect GDB's current\n\
+working directory."),
+                                  set_cwd_command,
+                                  show_cwd_command,
+                                  &setlist, &showlist);
+  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  gdb_assert (c != NULL);
+  set_cmd_completer (c, filename_completer);
+
   c = add_cmd ("environment", no_class, environment_info, _("\
 The environment to give the program, or one variable's value.\n\
 With an argument VAR, prints the value of environment variable VAR to\n\
@@ -3052,7 +3296,24 @@ The SIGNAL argument is processed the same as the handle command.\n\
 \n\
 An argument of \"0\" means continue the program without sending it a signal.\n\
 This is useful in cases where the program stopped because of a signal,\n\
-and you want to resume the program while discarding the signal."));
+and you want to resume the program while discarding the signal.\n\
+\n\
+In a multi-threaded program the signal is delivered to, or discarded from,\n\
+the current thread only."));
+  set_cmd_completer (c, signal_completer);
+
+  c = add_com ("queue-signal", class_run, queue_signal_command, _("\
+Queue a signal to be delivered to the current thread when it is resumed.\n\
+Usage: queue-signal SIGNAL\n\
+The SIGNAL argument is processed the same as the handle command.\n\
+It is an error if the handling state of SIGNAL is \"nopass\".\n\
+\n\
+An argument of \"0\" means remove any currently queued signal from\n\
+the current thread.  This is useful in cases where the program stopped\n\
+because of a signal, and you want to resume it while discarding the signal.\n\
+\n\
+In a multi-threaded program the signal is queued with, or discarded from,\n\
+the current thread only."));
   set_cmd_completer (c, signal_completer);
 
   add_com ("stepi", class_run, stepi_command, _("\
@@ -3082,8 +3343,6 @@ Unlike \"step\", if the current source line calls a subroutine,\n\
 this command does not enter the subroutine, but instead steps over\n\
 the call, in effect treating it as a single source line."));
   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\
@@ -3093,6 +3352,7 @@ reason)."));
   add_com_alias ("s", "step", class_run, 1);
 
   c = add_com ("until", class_run, until_command, _("\
+Execute until past the current line or past a LOCATION.\n\
 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."));
@@ -3107,27 +3367,12 @@ Execution will also stop upon exit from the current stack frame."));
 
   c = add_com ("jump", class_run, jump_command, _("\
 Continue program being debugged at specified line or address.\n\
-Usage: jump <location>\n\
+Usage: jump LOCATION\n\
 Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
 for an address to start at."));
   set_cmd_completer (c, location_completer);
   add_com_alias ("j", "jump", class_run, 1);
 
-  if (xdb_commands)
-    {
-      c = add_com ("go", class_run, go_command, _("\
-Usage: go <location>\n\
-Continue program being debugged, stopping at specified line or \n\
-address.\n\
-Give as argument either LINENUM or *ADDR, where ADDR is an \n\
-expression for an address to start at.\n\
-This command is a combination of tbreak and jump."));
-      set_cmd_completer (c, location_completer);
-    }
-
-  if (xdb_commands)
-    add_com_alias ("g", "go", class_run, 1);
-
   add_com ("continue", class_run, continue_command, _("\
 Continue program being debugged, after signal or breakpoint.\n\
 Usage: continue [N]\n\
@@ -3143,63 +3388,60 @@ Specifying -a and an ignore count simultaneously is an error."));
   add_com_alias ("fg", "cont", class_run, 1);
 
   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\
-To cancel previous arguments and run with no arguments,\n\
-use \"set args\" without arguments."));
+Start debugged program.\n"
+RUN_ARGS_HELP));
   set_cmd_completer (c, filename_completer);
   add_com_alias ("r", "run", class_run, 1);
-  if (xdb_commands)
-    add_com ("R", class_run, run_no_args_command,
-            _("Start debugged program with no arguments."));
 
   c = add_com ("start", class_run, start_command, _("\
-Run the debugged program until the beginning of the main procedure.\n\
-You may specify arguments to give to your program, just as with the\n\
-\"run\" command."));
+Start the debugged program stopping at the beginning of the main procedure.\n"
+RUN_ARGS_HELP));
+  set_cmd_completer (c, filename_completer);
+
+  c = add_com ("starti", class_run, starti_command, _("\
+Start the debugged program stopping at the first instruction.\n"
+RUN_ARGS_HELP));
   set_cmd_completer (c, filename_completer);
 
-  add_com ("interrupt", class_run, interrupt_target_command,
+  add_com ("interrupt", class_run, interrupt_command,
           _("Interrupt the execution of the debugged program.\n\
 If non-stop mode is enabled, interrupt only the current thread,\n\
 otherwise all the threads in the program are stopped.  To \n\
 interrupt all running threads in non-stop mode, use the -a option."));
 
-  add_info ("registers", nofp_registers_info, _("\
+  c = add_info ("registers", info_registers_command, _("\
 List of integer registers and their contents, for selected stack frame.\n\
-Register name as argument means describe only that register."));
+One or more register names as argument means describe the given registers.\n\
+One or more register group names as argument means describe the registers\n\
+in the named register groups."));
   add_info_alias ("r", "registers", 1);
+  set_cmd_completer (c, reg_or_group_completer);
 
-  if (xdb_commands)
-    add_com ("lr", class_info, nofp_registers_info, _("\
-List of integer registers and their contents, for selected stack frame.\n\
-Register name as argument means describe only that register."));
-  add_info ("all-registers", all_registers_info, _("\
+  c = add_info ("all-registers", info_all_registers_command, _("\
 List of all registers and their contents, for selected stack frame.\n\
-Register name as argument means describe only that register."));
+One or more register names as argument means describe the given registers.\n\
+One or more register group names as argument means describe the registers\n\
+in the named register groups."));
+  set_cmd_completer (c, reg_or_group_completer);
 
-  add_info ("program", program_info,
+  add_info ("program", info_program_command,
            _("Execution status of the program."));
 
-  add_info ("float", float_info,
-           _("Print the status of the floating point unit\n"));
+  add_info ("float", info_float_command,
+           _("Print the status of the floating point unit."));
 
-  add_info ("vector", vector_info,
-           _("Print the status of the vector unit\n"));
+  add_info ("vector", info_vector_command,
+           _("Print the status of the vector unit."));
 
   add_prefix_cmd ("proc", class_info, info_proc_cmd,
                  _("\
-Show /proc process information about any running process.\n\
+Show additional information about a process.\n\
 Specify any process id, or use the program being debugged by default."),
                  &info_proc_cmdlist, "info proc ",
                  1/*allow-unknown*/, &infolist);
 
   add_cmd ("mappings", class_info, info_proc_cmd_mappings, _("\
-List of mapped memory regions."),
+List memory regions mapped by the specified process."),
           &info_proc_cmdlist);
 
   add_cmd ("stat", class_info, info_proc_cmd_stat, _("\
@@ -3211,18 +3453,30 @@ List process info from /proc/PID/status."),
           &info_proc_cmdlist);
 
   add_cmd ("cwd", class_info, info_proc_cmd_cwd, _("\
-List current working directory of the process."),
+List current working directory of the specified process."),
           &info_proc_cmdlist);
 
   add_cmd ("cmdline", class_info, info_proc_cmd_cmdline, _("\
-List command line arguments of the process."),
+List command line arguments of the specified process."),
           &info_proc_cmdlist);
 
   add_cmd ("exe", class_info, info_proc_cmd_exe, _("\
-List absolute filename for executable of the process."),
+List absolute filename for executable of the specified process."),
+          &info_proc_cmdlist);
+
+  add_cmd ("files", class_info, info_proc_cmd_files, _("\
+List files opened by the specified process."),
           &info_proc_cmdlist);
 
   add_cmd ("all", class_info, info_proc_cmd_all, _("\
-List all available /proc info."),
+List all available info about the specified process."),
           &info_proc_cmdlist);
+
+  add_setshow_boolean_cmd ("finish", class_support,
+                          &user_print_options.finish_print, _("\
+Set whether `finish' prints the return value."), _("\
+Show whether `finish' prints the return value."), NULL,
+                          NULL,
+                          show_print_finish,
+                          &setprintlist, &showprintlist);
 }
This page took 0.066571 seconds and 4 git commands to generate.