gdb/amd64: clean up unused variable
[binutils-gdb.git] / gdb / infrun.c
index 8870f82b9cc3f53db689085270f37d15eb646801..033699bc3f73c7684ada386a981a614fafb2779d 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2021 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -72,6 +72,7 @@
 #include "scoped-mock-context.h"
 #include "test-target.h"
 #include "gdbsupport/common-debug.h"
+#include "gdbsupport/buildargv.h"
 
 /* Prototypes for local functions */
 
@@ -95,6 +96,13 @@ static void resume (gdb_signal sig);
 
 static void wait_for_inferior (inferior *inf);
 
+static void restart_threads (struct thread_info *event_thread,
+                            inferior *inf = nullptr);
+
+static bool start_step_over (void);
+
+static bool step_over_info_valid_p (void);
+
 /* Asynchronous signal handler registered as event loop source for
    when we have pending events ready to be passed to the core.  */
 static struct async_event_handler *infrun_async_inferior_event_token;
@@ -137,7 +145,7 @@ static void
 show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Mode of the step operation is %s.\n"), value);
+  gdb_printf (file, _("Mode of the step operation is %s.\n"), value);
 }
 
 /* proceed and normal_stop use this to notify the user when the
@@ -158,7 +166,7 @@ static void
 show_debug_infrun (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Inferior debugging is %s.\n"), value);
+  gdb_printf (file, _("Inferior debugging is %s.\n"), value);
 }
 
 /* Support for disabling address space randomization.  */
@@ -170,14 +178,14 @@ show_disable_randomization (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
   if (target_supports_disable_randomization ())
-    fprintf_filtered (file,
-                     _("Disabling randomization of debuggee's "
-                       "virtual address space is %s.\n"),
-                     value);
+    gdb_printf (file,
+               _("Disabling randomization of debuggee's "
+                 "virtual address space is %s.\n"),
+               value);
   else
-    fputs_filtered (_("Disabling randomization of debuggee's "
-                     "virtual address space is unsupported on\n"
-                     "this platform.\n"), file);
+    gdb_puts (_("Disabling randomization of debuggee's "
+               "virtual address space is unsupported on\n"
+               "this platform.\n"), file);
 }
 
 static void
@@ -212,9 +220,9 @@ static void
 show_non_stop (struct ui_file *file, int from_tty,
               struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Controlling the inferior in non-stop mode is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Controlling the inferior in non-stop mode is %s.\n"),
+             value);
 }
 
 /* "Observer mode" is somewhat like a more extreme version of
@@ -256,15 +264,15 @@ set_observer_mode (const char *args, int from_tty,
     }
 
   if (from_tty)
-    printf_filtered (_("Observer mode is now %s.\n"),
-                    (observer_mode ? "on" : "off"));
+    gdb_printf (_("Observer mode is now %s.\n"),
+               (observer_mode ? "on" : "off"));
 }
 
 static void
 show_observer_mode (struct ui_file *file, int from_tty,
                    struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Observer mode is %s.\n"), value);
+  gdb_printf (file, _("Observer mode is %s.\n"), value);
 }
 
 /* This updates the value of observer mode based on changes in
@@ -284,8 +292,8 @@ update_observer_mode (void)
 
   /* Let the user know if things change.  */
   if (newval != observer_mode)
-    printf_filtered (_("Observer mode is now %s.\n"),
-                    (newval ? "on" : "off"));
+    gdb_printf (_("Observer mode is now %s.\n"),
+               (newval ? "on" : "off"));
 
   observer_mode = observer_mode_1 = newval;
 }
@@ -357,8 +365,8 @@ static void
 show_stop_on_solib_events (struct ui_file *file, int from_tty,
                           struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Stopping for shared library events is %s.\n"),
-                   value);
+  gdb_printf (file, _("Stopping for shared library events is %s.\n"),
+             value);
 }
 
 /* True after stop if current stack frame should be printed.  */
@@ -366,7 +374,7 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty,
 static bool stop_print_frame;
 
 /* This is a cached copy of the target/ptid/waitstatus of the last
-   event returned by target_wait()/deprecated_target_wait_hook().
+   event returned by target_wait().
    This information is returned by get_last_target_status().  */
 static process_stratum_target *target_last_proc_target;
 static ptid_t target_last_wait_ptid;
@@ -388,10 +396,10 @@ static void
 show_follow_fork_mode_string (struct ui_file *file, int from_tty,
                              struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Debugger response to a program "
-                     "call of fork or vfork is \"%s\".\n"),
-                   value);
+  gdb_printf (file,
+             _("Debugger response to a program "
+               "call of fork or vfork is \"%s\".\n"),
+             value);
 }
 \f
 
@@ -404,12 +412,12 @@ show_follow_fork_mode_string (struct ui_file *file, int from_tty,
 static bool
 follow_fork_inferior (bool follow_child, bool detach_fork)
 {
-  target_waitkind fork_kind = inferior_thread ()->pending_follow.kind;
+  target_waitkind fork_kind = inferior_thread ()->pending_follow.kind ();
   gdb_assert (fork_kind == TARGET_WAITKIND_FORKED
              || fork_kind == TARGET_WAITKIND_VFORKED);
   bool has_vforked = fork_kind == TARGET_WAITKIND_VFORKED;
   ptid_t parent_ptid = inferior_ptid;
-  ptid_t child_ptid = inferior_thread ()->pending_follow.value.related_pid;
+  ptid_t child_ptid = inferior_thread ()->pending_follow.child_ptid ();
 
   if (has_vforked
       && !non_stop /* Non-stop always resumes both branches.  */
@@ -421,7 +429,7 @@ follow_fork_inferior (bool follow_child, bool detach_fork)
         the parent stays blocked.  If we're telling the parent to run
         in the foreground, the user will not be able to ctrl-c to get
         back the terminal, effectively hanging the debug session.  */
-      fprintf_filtered (gdb_stderr, _("\
+      gdb_printf (gdb_stderr, _("\
 Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
@@ -431,6 +439,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
   inferior *parent_inf = current_inferior ();
   inferior *child_inf = nullptr;
 
+  gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr);
+
   if (!follow_child)
     {
       /* Detach new forked process?  */
@@ -455,10 +465,9 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              ptid_t process_ptid = ptid_t (child_ptid.pid ());
 
              target_terminal::ours_for_output ();
-             fprintf_filtered (gdb_stdlog,
-                               _("[Detaching after %s from child %s]\n"),
-                               has_vforked ? "vfork" : "fork",
-                               target_pid_to_str (process_ptid).c_str ());
+             gdb_printf (_("[Detaching after %s from child %s]\n"),
+                         has_vforked ? "vfork" : "fork",
+                         target_pid_to_str (process_ptid).c_str ());
            }
        }
       else
@@ -492,7 +501,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
            }
          else
            {
-             child_inf->aspace = new_address_space ();
+             child_inf->aspace = new address_space ();
              child_inf->pspace = new program_space (child_inf->aspace);
              child_inf->removable = 1;
              clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -508,7 +517,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
             insert breakpoints, so that we can debug it.  A
             subsequent child exec or exit is enough to know when does
             the child stops using the parent's address space.  */
-         parent_inf->waiting_for_vfork_done = detach_fork;
+         parent_inf->thread_waiting_for_vfork_done
+           = detach_fork ? inferior_thread () : nullptr;
          parent_inf->pspace->breakpoints_not_allowed = detach_fork;
        }
     }
@@ -522,11 +532,10 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          std::string child_pid = target_pid_to_str (child_ptid);
 
          target_terminal::ours_for_output ();
-         fprintf_filtered (gdb_stdlog,
-                           _("[Attaching after %s %s to child %s]\n"),
-                           parent_pid.c_str (),
-                           has_vforked ? "vfork" : "fork",
-                           child_pid.c_str ());
+         gdb_printf (_("[Attaching after %s %s to child %s]\n"),
+                     parent_pid.c_str (),
+                     has_vforked ? "vfork" : "fork",
+                     child_pid.c_str ());
        }
 
       /* Add the new inferior first, so that the target_detach below
@@ -539,25 +548,46 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
       child_inf->gdbarch = parent_inf->gdbarch;
       copy_inferior_target_desc_info (child_inf, parent_inf);
 
-      program_space *parent_pspace = parent_inf->pspace;
-
-      /* If this is a vfork child, then the address-space is shared
-        with the parent.  If we detached from the parent, then we can
-        reuse the parent's program/address spaces.  */
-      if (has_vforked || detach_fork)
+      if (has_vforked)
        {
-         child_inf->pspace = parent_pspace;
-         child_inf->aspace = child_inf->pspace->aspace;
+         /* If this is a vfork child, then the address-space is shared
+            with the parent.  */
+         child_inf->aspace = parent_inf->aspace;
+         child_inf->pspace = parent_inf->pspace;
 
          exec_on_vfork (child_inf);
        }
+      else if (detach_fork)
+       {
+         /* We follow the child and detach from the parent: move the parent's
+            program space to the child.  This simplifies some things, like
+            doing "next" over fork() and landing on the expected line in the
+            child (note, that is broken with "set detach-on-fork off").
+
+            Before assigning brand new spaces for the parent, remove
+            breakpoints from it: because the new pspace won't match
+            currently inserted locations, the normal detach procedure
+            wouldn't remove them, and we would leave them inserted when
+            detaching.  */
+         remove_breakpoints_inf (parent_inf);
+
+         child_inf->aspace = parent_inf->aspace;
+         child_inf->pspace = parent_inf->pspace;
+         parent_inf->aspace = new address_space ();
+         parent_inf->pspace = new program_space (parent_inf->aspace);
+         clone_program_space (parent_inf->pspace, child_inf->pspace);
+
+         /* The parent inferior is still the current one, so keep things
+            in sync.  */
+         set_current_program_space (parent_inf->pspace);
+       }
       else
        {
-         child_inf->aspace = new_address_space ();
+         child_inf->aspace = new address_space ();
          child_inf->pspace = new program_space (child_inf->aspace);
          child_inf->removable = 1;
          child_inf->symfile_flags = SYMFILE_NO_READ;
-         clone_program_space (child_inf->pspace, parent_pspace);
+         clone_program_space (child_inf->pspace, parent_inf->pspace);
        }
     }
 
@@ -582,6 +612,23 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
   if (child_inf != nullptr)
     gdb_assert (!child_inf->thread_list.empty ());
 
+  /* Clear the parent thread's pending follow field.  Do this before calling
+     target_detach, so that the target can differentiate the two following
+     cases:
+
+      - We continue past a fork with "follow-fork-mode == child" &&
+       "detach-on-fork on", and therefore detach the parent.  In that
+       case the target should not detach the fork child.
+      - We run to a fork catchpoint and the user types "detach".  In that
+       case, the target should detach the fork child in addition to the
+       parent.
+
+     The former case will have pending_follow cleared, the later will have
+     pending_follow set.  */
+  thread_info *parent_thread = find_thread_ptid (parent_inf, parent_ptid);
+  gdb_assert (parent_thread != nullptr);
+  parent_thread->pending_follow.set_spurious ();
+
   /* Detach the parent if needed.  */
   if (follow_child)
     {
@@ -603,7 +650,6 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          child_inf->pending_detach = 0;
          parent_inf->vfork_child = child_inf;
          parent_inf->pending_detach = detach_fork;
-         parent_inf->waiting_for_vfork_done = 0;
        }
       else if (detach_fork)
        {
@@ -613,10 +659,9 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              ptid_t process_ptid = ptid_t (parent_ptid.pid ());
 
              target_terminal::ours_for_output ();
-             fprintf_filtered (gdb_stdlog,
-                               _("[Detaching after fork from "
-                                 "parent %s]\n"),
-                               target_pid_to_str (process_ptid).c_str ());
+             gdb_printf (_("[Detaching after fork from "
+                           "parent %s]\n"),
+                         target_pid_to_str (process_ptid).c_str ());
            }
 
          target_detach (parent_inf, 0);
@@ -650,7 +695,6 @@ follow_fork ()
 {
   bool follow_child = (follow_fork_mode_string == follow_fork_mode_child);
   bool should_resume = true;
-  struct thread_info *tp;
 
   /* Copy user stepping state to the new inferior thread.  FIXME: the
      followed fork child thread should have a copy of most of the
@@ -663,7 +707,6 @@ follow_fork ()
   int current_line = 0;
   symtab *current_symtab = NULL;
   struct frame_id step_frame_id = { 0 };
-  struct thread_fsm *thread_fsm = NULL;
 
   if (!non_stop)
     {
@@ -676,8 +719,8 @@ follow_fork ()
 
       /* If not stopped at a fork event, then there's nothing else to
         do.  */
-      if (wait_status.kind != TARGET_WAITKIND_FORKED
-         && wait_status.kind != TARGET_WAITKIND_VFORKED)
+      if (wait_status.kind () != TARGET_WAITKIND_FORKED
+         && wait_status.kind () != TARGET_WAITKIND_VFORKED)
        return 1;
 
       /* Check if we switched over from WAIT_PTID, since the event was
@@ -696,16 +739,17 @@ follow_fork ()
        }
     }
 
-  tp = inferior_thread ();
+  thread_info *tp = inferior_thread ();
 
   /* If there were any forks/vforks that were caught and are now to be
      followed, then do so now.  */
-  switch (tp->pending_follow.kind)
+  switch (tp->pending_follow.kind ())
     {
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
       {
        ptid_t parent, child;
+       std::unique_ptr<struct thread_fsm> thread_fsm;
 
        /* If the user did a next/step, etc, over a fork call,
           preserve the stepping state in the fork child.  */
@@ -720,7 +764,7 @@ follow_fork ()
            step_frame_id = tp->control.step_frame_id;
            exception_resume_breakpoint
              = clone_momentary_breakpoint (tp->control.exception_resume_breakpoint);
-           thread_fsm = tp->thread_fsm;
+           thread_fsm = tp->release_thread_fsm ();
 
            /* For now, delete the parent's sr breakpoint, otherwise,
               parent/child sr breakpoints are considered duplicates,
@@ -732,11 +776,16 @@ follow_fork ()
            tp->control.step_range_end = 0;
            tp->control.step_frame_id = null_frame_id;
            delete_exception_resume_breakpoint (tp);
-           tp->thread_fsm = NULL;
          }
 
        parent = inferior_ptid;
-       child = tp->pending_follow.value.related_pid;
+       child = tp->pending_follow.child_ptid ();
+
+       /* If handling a vfork, stop all the inferior's threads, they will be
+          restarted when the vfork shared region is complete.  */
+       if (tp->pending_follow.kind () == TARGET_WAITKIND_VFORKED
+           && target_is_non_stop_p ())
+         stop_all_threads ("handling vfork", tp->inf);
 
        process_stratum_target *parent_targ = tp->inf->process_target ();
        /* Set up inferior(s) as specified by the caller, and tell the
@@ -750,14 +799,6 @@ follow_fork ()
          }
        else
          {
-           /* This pending follow fork event is now handled, one way
-              or another.  The previous selected thread may be gone
-              from the lists by now, but if it is still around, need
-              to clear the pending follow request.  */
-           tp = find_thread_ptid (parent_targ, parent);
-           if (tp)
-             tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-
            /* This makes sure we don't try to apply the "Switched
               over from WAIT_PID" logic above.  */
            nullify_last_target_wait_ptid ();
@@ -782,7 +823,7 @@ follow_fork ()
                    tp->control.step_frame_id = step_frame_id;
                    tp->control.exception_resume_breakpoint
                      = exception_resume_breakpoint;
-                   tp->thread_fsm = thread_fsm;
+                   tp->set_thread_fsm (std::move (thread_fsm));
                  }
                else
                  {
@@ -808,7 +849,7 @@ follow_fork ()
     default:
       internal_error (__FILE__, __LINE__,
                      "Unexpected pending_follow.kind %d\n",
-                     tp->pending_follow.kind);
+                     tp->pending_follow.kind ());
       break;
     }
 
@@ -855,30 +896,24 @@ follow_inferior_reset_breakpoints (void)
   insert_breakpoints ();
 }
 
-/* The child has exited or execed: resume threads of the parent the
-   user wanted to be executing.  */
+/* The child has exited or execed: resume THREAD, a thread of the parent,
+   if it was meant to be executing.  */
 
-static int
-proceed_after_vfork_done (struct thread_info *thread,
-                         void *arg)
+static void
+proceed_after_vfork_done (thread_info *thread)
 {
-  int pid = * (int *) arg;
-
-  if (thread->ptid.pid () == pid
-      && thread->state == THREAD_RUNNING
-      && !thread->executing
+  if (thread->state == THREAD_RUNNING
+      && !thread->executing ()
       && !thread->stop_requested
       && thread->stop_signal () == GDB_SIGNAL_0)
     {
       infrun_debug_printf ("resuming vfork parent thread %s",
-                          target_pid_to_str (thread->ptid).c_str ());
+                          thread->ptid.to_string ().c_str ());
 
       switch_to_thread (thread);
       clear_proceed_status (0);
       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
-
-  return 0;
 }
 
 /* Called whenever we notice an exec or exit event, to handle
@@ -891,7 +926,7 @@ handle_vfork_child_exec_or_exit (int exec)
 
   if (inf->vfork_parent)
     {
-      int resume_parent = -1;
+      inferior *resume_parent = nullptr;
 
       /* This exec or exit marks the end of the shared memory region
         between the parent and the child.  Break the bonds.  */
@@ -942,15 +977,13 @@ handle_vfork_child_exec_or_exit (int exec)
 
              if (exec)
                {
-                 fprintf_filtered (gdb_stdlog,
-                                   _("[Detaching vfork parent %s "
-                                     "after child exec]\n"), pidstr.c_str ());
+                 gdb_printf (_("[Detaching vfork parent %s "
+                               "after child exec]\n"), pidstr.c_str ());
                }
              else
                {
-                 fprintf_filtered (gdb_stdlog,
-                                   _("[Detaching vfork parent %s "
-                                     "after child exit]\n"), pidstr.c_str ());
+                 gdb_printf (_("[Detaching vfork parent %s "
+                               "after child exit]\n"), pidstr.c_str ());
                }
            }
 
@@ -969,7 +1002,7 @@ handle_vfork_child_exec_or_exit (int exec)
          inf->removable = 1;
          set_current_program_space (inf->pspace);
 
-         resume_parent = vfork_parent->pid;
+         resume_parent = vfork_parent;
        }
       else
        {
@@ -995,25 +1028,75 @@ handle_vfork_child_exec_or_exit (int exec)
          inf->symfile_flags = SYMFILE_NO_READ;
          clone_program_space (inf->pspace, vfork_parent->pspace);
 
-         resume_parent = vfork_parent->pid;
+         resume_parent = vfork_parent;
        }
 
       gdb_assert (current_program_space == inf->pspace);
 
-      if (non_stop && resume_parent != -1)
+      if (non_stop && resume_parent != nullptr)
        {
          /* If the user wanted the parent to be running, let it go
             free now.  */
          scoped_restore_current_thread restore_thread;
 
          infrun_debug_printf ("resuming vfork parent process %d",
-                              resume_parent);
+                              resume_parent->pid);
 
-         iterate_over_threads (proceed_after_vfork_done, &resume_parent);
+         for (thread_info *thread : resume_parent->threads ())
+           proceed_after_vfork_done (thread);
        }
     }
 }
 
+/* Handle TARGET_WAITKIND_VFORK_DONE.  */
+
+static void
+handle_vfork_done (thread_info *event_thread)
+{
+  /* We only care about this event if inferior::thread_waiting_for_vfork_done is
+     set, that is if we are waiting for a vfork child not under our control
+     (because we detached it) to exec or exit.
+
+     If an inferior has vforked and we are debugging the child, we don't use
+     the vfork-done event to get notified about the end of the shared address
+     space window.  We rely instead on the child's exec or exit event, and the
+     inferior::vfork_{parent,child} fields are used instead.  See
+     handle_vfork_child_exec_or_exit for that.  */
+  if (event_thread->inf->thread_waiting_for_vfork_done == nullptr)
+    {
+      infrun_debug_printf ("not waiting for a vfork-done event");
+      return;
+    }
+
+  INFRUN_SCOPED_DEBUG_ENTER_EXIT;
+
+  /* We stopped all threads (other than the vforking thread) of the inferior in
+     follow_fork and kept them stopped until now.  It should therefore not be
+     possible for another thread to have reported a vfork during that window.
+     If THREAD_WAITING_FOR_VFORK_DONE is set, it has to be the same thread whose
+     vfork-done we are handling right now.  */
+  gdb_assert (event_thread->inf->thread_waiting_for_vfork_done == event_thread);
+
+  event_thread->inf->thread_waiting_for_vfork_done = nullptr;
+  event_thread->inf->pspace->breakpoints_not_allowed = 0;
+
+  /* On non-stop targets, we stopped all the inferior's threads in follow_fork,
+     resume them now.  On all-stop targets, everything that needs to be resumed
+     will be when we resume the event thread.  */
+  if (target_is_non_stop_p ())
+    {
+      /* restart_threads and start_step_over may change the current thread, make
+        sure we leave the event thread as the current thread.  */
+      scoped_restore_current_thread restore_thread;
+
+      insert_breakpoints ();
+      start_step_over ();
+
+      if (!step_over_info_valid_p ())
+       restart_threads (event_thread, event_thread->inf);
+    }
+}
+
 /* Enum strings for "set|show follow-exec-mode".  */
 
 static const char follow_exec_mode_new[] = "new";
@@ -1030,7 +1113,7 @@ static void
 show_follow_exec_mode_string (struct ui_file *file, int from_tty,
                              struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Follow exec mode is \"%s\".\n"),  value);
+  gdb_printf (file, _("Follow exec mode is \"%s\".\n"),  value);
 }
 
 /* EXEC_FILE_TARGET is assumed to be non-NULL.  */
@@ -1111,9 +1194,9 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
 
   /* What is this a.out's name?  */
   process_ptid = ptid_t (pid);
-  printf_unfiltered (_("%s is executing new program: %s\n"),
-                    target_pid_to_str (process_ptid).c_str (),
-                    exec_file_target);
+  gdb_printf (_("%s is executing new program: %s\n"),
+             target_pid_to_str (process_ptid).c_str (),
+             exec_file_target);
 
   /* We've followed the inferior through an exec.  Therefore, the
      inferior has essentially been killed & reborn.  */
@@ -1465,6 +1548,7 @@ static void
 infrun_inferior_exit (struct inferior *inf)
 {
   inf->displaced_step_state.reset ();
+  inf->thread_waiting_for_vfork_done = nullptr;
 }
 
 static void
@@ -1483,6 +1567,8 @@ infrun_inferior_execd (inferior *inf)
      one in progress at the time of the exec, it must have been the exec'ing
      thread.  */
   clear_step_over_info ();
+
+  inf->thread_waiting_for_vfork_done = nullptr;
 }
 
 /* If ON, and the architecture supports it, GDB will use displaced
@@ -1500,14 +1586,14 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
                                 const char *value)
 {
   if (can_use_displaced_stepping == AUTO_BOOLEAN_AUTO)
-    fprintf_filtered (file,
-                     _("Debugger's willingness to use displaced stepping "
-                       "to step over breakpoints is %s (currently %s).\n"),
-                     value, target_is_non_stop_p () ? "on" : "off");
+    gdb_printf (file,
+               _("Debugger's willingness to use displaced stepping "
+                 "to step over breakpoints is %s (currently %s).\n"),
+               value, target_is_non_stop_p () ? "on" : "off");
   else
-    fprintf_filtered (file,
-                     _("Debugger's willingness to use displaced stepping "
-                       "to step over breakpoints is %s.\n"), value);
+    gdb_printf (file,
+               _("Debugger's willingness to use displaced stepping "
+                 "to step over breakpoints is %s.\n"), value);
 }
 
 /* Return true if the gdbarch implements the required methods to use
@@ -1636,14 +1722,14 @@ displaced_step_prepare_throw (thread_info *tp)
         it is likely that it will return unavailable, so don't bother asking.  */
 
       displaced_debug_printf ("deferring step of %s",
-                             target_pid_to_str (tp->ptid).c_str ());
+                             tp->ptid.to_string ().c_str ());
 
       global_thread_step_over_chain_enqueue (tp);
       return DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE;
     }
 
   displaced_debug_printf ("displaced-stepping %s now",
-                         target_pid_to_str (tp->ptid).c_str ());
+                         tp->ptid.to_string ().c_str ());
 
   scoped_restore_current_thread restore_thread;
 
@@ -1658,7 +1744,7 @@ displaced_step_prepare_throw (thread_info *tp)
   if (status == DISPLACED_STEP_PREPARE_STATUS_CANT)
     {
       displaced_debug_printf ("failed to prepare (%s)",
-                             target_pid_to_str (tp->ptid).c_str ());
+                             tp->ptid.to_string ().c_str ());
 
       return DISPLACED_STEP_PREPARE_STATUS_CANT;
     }
@@ -1669,7 +1755,7 @@ displaced_step_prepare_throw (thread_info *tp)
 
       displaced_debug_printf ("not enough resources available, "
                              "deferring step of %s",
-                             target_pid_to_str (tp->ptid).c_str ());
+                             tp->ptid.to_string ().c_str ());
 
       global_thread_step_over_chain_enqueue (tp);
 
@@ -1686,7 +1772,7 @@ displaced_step_prepare_throw (thread_info *tp)
 
   displaced_debug_printf ("prepared successfully thread=%s, "
                          "original_pc=%s, displaced_pc=%s",
-                         target_pid_to_str (tp->ptid).c_str (),
+                         tp->ptid.to_string ().c_str (),
                          paddress (gdbarch, original_pc),
                          paddress (gdbarch, displaced_pc));
 
@@ -1769,6 +1855,25 @@ displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
    discarded between events.  */
 struct execution_control_state
 {
+  execution_control_state ()
+  {
+    this->reset ();
+  }
+
+  void reset ()
+  {
+    this->target = nullptr;
+    this->ptid = null_ptid;
+    this->event_thread = nullptr;
+    ws = target_waitstatus ();
+    stop_func_filled_in = 0;
+    stop_func_start = 0;
+    stop_func_end = 0;
+    stop_func_name = nullptr;
+    wait_some_more = 0;
+    hit_singlestep_breakpoint = 0;
+  }
+
   process_stratum_target *target;
   ptid_t ptid;
   /* The thread that got the event, if this was a thread event; NULL
@@ -1794,7 +1899,7 @@ struct execution_control_state
 static void
 reset_ecs (struct execution_control_state *ecs, struct thread_info *tp)
 {
-  memset (ecs, 0, sizeof (*ecs));
+  ecs->reset ();
   ecs->event_thread = tp;
   ecs->ptid = tp->ptid;
 }
@@ -1866,6 +1971,16 @@ start_step_over (void)
          continue;
        }
 
+      if (tp->inf->thread_waiting_for_vfork_done != nullptr)
+       {
+         /* When we stop all threads, handling a vfork, any thread in the step
+            over chain remains there.  A user could also try to continue a
+            thread stopped at a breakpoint while another thread is waiting for
+            a vfork-done event.  In any case, we don't want to start a step
+            over right now.  */
+         continue;
+       }
+
       /* Remove thread from the THREADS_TO_STEP chain.  If anything goes wrong
         while we try to prepare the displaced step, we don't add it back to
         the global step over chain.  This is to avoid a thread staying in the
@@ -1890,19 +2005,19 @@ start_step_over (void)
 
       if (tp->control.trap_expected
          || tp->resumed ()
-         || tp->executing)
+         || tp->executing ())
        {
          internal_error (__FILE__, __LINE__,
                          "[%s] has inconsistent state: "
                          "trap_expected=%d, resumed=%d, executing=%d\n",
-                         target_pid_to_str (tp->ptid).c_str (),
+                         tp->ptid.to_string ().c_str (),
                          tp->control.trap_expected,
                          tp->resumed (),
-                         tp->executing);
+                         tp->executing ());
        }
 
       infrun_debug_printf ("resuming [%s] for step-over",
-                          target_pid_to_str (tp->ptid).c_str ());
+                          tp->ptid.to_string ().c_str ());
 
       /* keep_going_pass_signal skips the step-over if the breakpoint
         is no longer inserted.  In all-stop, we want to keep looking
@@ -1925,13 +2040,13 @@ start_step_over (void)
       if (tp->resumed  ())
        {
          infrun_debug_printf ("[%s] was resumed.",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          gdb_assert (!thread_is_in_step_over_chain (tp));
        }
       else
        {
          infrun_debug_printf ("[%s] was NOT resumed.",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          gdb_assert (thread_is_in_step_over_chain (tp));
        }
 
@@ -1995,10 +2110,10 @@ static void
 show_scheduler_mode (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Mode for locking scheduler "
-                     "during execution is \"%s\".\n"),
-                   value);
+  gdb_printf (file,
+             _("Mode for locking scheduler "
+               "during execution is \"%s\".\n"),
+             value);
 }
 
 static void
@@ -2101,8 +2216,41 @@ internal_resume_ptid (int user_step)
      return a wildcard ptid.  */
   if (target_is_non_stop_p ())
     return inferior_ptid;
-  else
-    return user_visible_resume_ptid (user_step);
+
+  /* The rest of the function assumes non-stop==off and
+     target-non-stop==off.
+
+     If a thread is waiting for a vfork-done event, it means breakpoints are out
+     for this inferior (well, program space in fact).  We don't want to resume
+     any thread other than the one waiting for vfork done, otherwise these other
+     threads could miss breakpoints.  So if a thread in the resumption set is
+     waiting for a vfork-done event, resume only that thread.
+
+     The resumption set width depends on whether schedule-multiple is on or off.
+
+     Note that if the target_resume interface was more flexible, we could be
+     smarter here when schedule-multiple is on.  For example, imagine 3
+     inferiors with 2 threads each (1.1, 1.2, 2.1, 2.2, 3.1 and 3.2).  Threads
+     2.1 and 3.2 are both waiting for a vfork-done event.  Then we could ask the
+     target(s) to resume:
+
+      - All threads of inferior 1
+      - Thread 2.1
+      - Thread 3.2
+
+     Since we don't have that flexibility (we can only pass one ptid), just
+     resume the first thread waiting for a vfork-done event we find (e.g. thread
+     2.1).  */
+  if (sched_multi)
+    {
+      for (inferior *inf : all_non_exited_inferiors ())
+       if (inf->thread_waiting_for_vfork_done != nullptr)
+         return inf->thread_waiting_for_vfork_done->ptid;
+    }
+  else if (current_inferior ()->thread_waiting_for_vfork_done != nullptr)
+    return current_inferior ()->thread_waiting_for_vfork_done->ptid;
+
+  return user_visible_resume_ptid (user_step);
 }
 
 /* Wrapper for target_resume, that handles infrun-specific
@@ -2147,10 +2295,11 @@ do_target_resume (ptid_t resume_ptid, bool step, enum gdb_signal sig)
   else
     target_pass_signals (signal_pass);
 
-  target_resume (resume_ptid, step, sig);
+  infrun_debug_printf ("resume_ptid=%s, step=%d, sig=%s",
+                      resume_ptid.to_string ().c_str (),
+                      step, gdb_signal_to_symbol_string (sig));
 
-  if (target_can_async_p ())
-    target_async (1);
+  target_resume (resume_ptid, step, sig);
 }
 
 /* Resume the inferior.  SIG is the signal to give the inferior
@@ -2183,8 +2332,8 @@ resume_1 (enum gdb_signal sig)
       infrun_debug_printf
        ("thread %s has pending wait "
         "status %s (currently_stepping=%d).",
-        target_pid_to_str (tp->ptid).c_str (),
-        target_waitstatus_to_string (&tp->pending_waitstatus ()).c_str (),
+        tp->ptid.to_string ().c_str (),
+        tp->pending_waitstatus ().to_string ().c_str (),
         currently_stepping (tp));
 
       tp->inf->process_target ()->threads_executing = true;
@@ -2197,14 +2346,14 @@ resume_1 (enum gdb_signal sig)
        {
          warning (_("Couldn't deliver signal %s to %s."),
                   gdb_signal_to_name (sig),
-                  target_pid_to_str (tp->ptid).c_str ());
+                  tp->ptid.to_string ().c_str ());
        }
 
       tp->set_stop_signal (GDB_SIGNAL_0);
 
       if (target_can_async_p ())
        {
-         target_async (1);
+         target_async (true);
          /* Tell the event loop we have an event to process. */
          mark_async_event_handler (infrun_async_inferior_event_token);
        }
@@ -2216,7 +2365,7 @@ resume_1 (enum gdb_signal sig)
   /* Depends on stepped_breakpoint.  */
   step = currently_stepping (tp);
 
-  if (current_inferior ()->waiting_for_vfork_done)
+  if (current_inferior ()->thread_waiting_for_vfork_done != nullptr)
     {
       /* Don't try to single-step a vfork parent that is waiting for
         the child to get out of the shared memory region (by exec'ing
@@ -2239,7 +2388,7 @@ resume_1 (enum gdb_signal sig)
                       "current thread [%s] at %s",
                       step, gdb_signal_to_symbol_string (sig),
                       tp->control.trap_expected,
-                      target_pid_to_str (inferior_ptid).c_str (),
+                      inferior_ptid.to_string ().c_str (),
                       paddress (gdbarch, pc));
 
   /* Normally, by the time we reach `resume', the breakpoints are either
@@ -2336,7 +2485,7 @@ resume_1 (enum gdb_signal sig)
       && use_displaced_stepping (tp)
       && !step_over_info_valid_p ()
       && sig == GDB_SIGNAL_0
-      && !current_inferior ()->waiting_for_vfork_done)
+      && current_inferior ()->thread_waiting_for_vfork_done == nullptr)
     {
       displaced_step_prepare_status prepare_status
        = displaced_step_prepare (tp);
@@ -2353,7 +2502,7 @@ resume_1 (enum gdb_signal sig)
          /* Fallback to stepping over the breakpoint in-line.  */
 
          if (target_is_non_stop_p ())
-           stop_all_threads ();
+           stop_all_threads ("displaced stepping falling back on inline stepping");
 
          set_step_over_info (regcache->aspace (),
                              regcache_read_pc (regcache), 0, tp->global_num);
@@ -2371,8 +2520,8 @@ resume_1 (enum gdb_signal sig)
          step = gdbarch_displaced_step_hw_singlestep (gdbarch);
        }
       else
-       gdb_assert_not_reached (_("Invalid displaced_step_prepare_status "
-                                 "value."));
+       gdb_assert_not_reached ("Invalid displaced_step_prepare_status "
+                               "value.");
     }
 
   /* Do we need to do it the hard way, w/temp breakpoints?  */
@@ -2480,7 +2629,7 @@ resume_1 (enum gdb_signal sig)
         do displaced stepping.  */
 
       infrun_debug_printf ("resume: [%s] stepped breakpoint",
-                          target_pid_to_str (tp->ptid).c_str ());
+                          tp->ptid.to_string ().c_str ());
 
       tp->stepped_breakpoint = 1;
 
@@ -2582,7 +2731,7 @@ new_stop_id (void)
 static void
 clear_proceed_status_thread (struct thread_info *tp)
 {
-  infrun_debug_printf ("%s", target_pid_to_str (tp->ptid).c_str ());
+  infrun_debug_printf ("%s", tp->ptid.to_string ().c_str ());
 
   /* If we're starting a new sequence, then the previous finished
      single-step is no longer relevant.  */
@@ -2592,7 +2741,7 @@ clear_proceed_status_thread (struct thread_info *tp)
        {
          infrun_debug_printf ("pending event of %s was a finished step. "
                               "Discarding.",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
 
          tp->clear_pending_waitstatus ();
          tp->set_stop_reason (TARGET_STOPPED_BY_NO_REASON);
@@ -2601,8 +2750,8 @@ clear_proceed_status_thread (struct thread_info *tp)
        {
          infrun_debug_printf
            ("thread %s has pending wait status %s (currently_stepping=%d).",
-            target_pid_to_str (tp->ptid).c_str (),
-            target_waitstatus_to_string (&tp->pending_waitstatus ()).c_str (),
+            tp->ptid.to_string ().c_str (),
+            tp->pending_waitstatus ().to_string ().c_str (),
             currently_stepping (tp));
        }
     }
@@ -2612,8 +2761,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (!signal_pass_state (tp->stop_signal ()))
     tp->set_stop_signal (GDB_SIGNAL_0);
 
-  delete tp->thread_fsm;
-  tp->thread_fsm = NULL;
+  tp->release_thread_fsm ();
 
   tp->control.trap_expected = 0;
   tp->control.step_range_start = 0;
@@ -3017,7 +3165,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   CORE_ADDR pc;
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
-  bool started;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
      "set follow-fork-mode" command; otherwise, we'll just proceed
@@ -3056,7 +3203,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
   if (addr == (CORE_ADDR) -1)
     {
-      if (pc == cur_thr->stop_pc ()
+      if (cur_thr->stop_pc_p ()
+         && pc == cur_thr->stop_pc ()
          && breakpoint_here_p (aspace, pc) == ordinary_breakpoint_here
          && execution_direction != EXEC_REVERSE)
        /* There is a breakpoint at the address we will resume at,
@@ -3143,7 +3291,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
          gdb_assert (!thread_is_in_step_over_chain (tp));
 
          infrun_debug_printf ("need to step-over [%s] first",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
 
          global_thread_step_over_chain_enqueue (tp);
        }
@@ -3165,8 +3313,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
   {
     scoped_disable_commit_resumed disable_commit_resumed ("proceeding");
-
-    started = start_step_over ();
+    bool step_over_started = start_step_over ();
 
     if (step_over_info_valid_p ())
       {
@@ -3174,7 +3321,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
           other thread was already doing one.  In either case, don't
           resume anything else until the step-over is finished.  */
       }
-    else if (started && !target_is_non_stop_p ())
+    else if (step_over_started && !target_is_non_stop_p ())
       {
        /* A new displaced stepping sequence was started.  In all-stop,
           we can't talk to the target anymore until it next stops.  */
@@ -3194,27 +3341,40 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
            if (!tp->inf->has_execution ())
              {
                infrun_debug_printf ("[%s] target has no execution",
-                                    target_pid_to_str (tp->ptid).c_str ());
+                                    tp->ptid.to_string ().c_str ());
                continue;
              }
 
            if (tp->resumed ())
              {
                infrun_debug_printf ("[%s] resumed",
-                                    target_pid_to_str (tp->ptid).c_str ());
-               gdb_assert (tp->executing || tp->has_pending_waitstatus ());
+                                    tp->ptid.to_string ().c_str ());
+               gdb_assert (tp->executing () || tp->has_pending_waitstatus ());
                continue;
              }
 
            if (thread_is_in_step_over_chain (tp))
              {
                infrun_debug_printf ("[%s] needs step-over",
-                                    target_pid_to_str (tp->ptid).c_str ());
+                                    tp->ptid.to_string ().c_str ());
+               continue;
+             }
+
+           /* If a thread of that inferior is waiting for a vfork-done
+              (for a detached vfork child to exec or exit), breakpoints are
+              removed.  We must not resume any thread of that inferior, other
+              than the one waiting for the vfork-done.  */
+           if (tp->inf->thread_waiting_for_vfork_done != nullptr
+               && tp != tp->inf->thread_waiting_for_vfork_done)
+             {
+               infrun_debug_printf ("[%s] another thread of this inferior is "
+                                    "waiting for vfork-done",
+                                    tp->ptid.to_string ().c_str ());
                continue;
              }
 
            infrun_debug_printf ("resuming %s",
-                                target_pid_to_str (tp->ptid).c_str ());
+                                tp->ptid.to_string ().c_str ());
 
            reset_ecs (ecs, tp);
            switch_to_thread (tp);
@@ -3223,7 +3383,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
              error (_("Command aborted."));
          }
       }
-    else if (!cur_thr->resumed () && !thread_is_in_step_over_chain (cur_thr))
+    else if (!cur_thr->resumed ()
+            && !thread_is_in_step_over_chain (cur_thr)
+            /* In non-stop, forbid resuming a thread if some other thread of
+               that inferior is waiting for a vfork-done event (this means
+               breakpoints are out for this inferior).  */
+            && !(non_stop
+                 && cur_thr->inf->thread_waiting_for_vfork_done != nullptr))
       {
        /* The thread wasn't started, and isn't queued, run it now.  */
        reset_ecs (ecs, cur_thr);
@@ -3334,7 +3500,7 @@ infrun_thread_stop_requested (ptid_t ptid)
     {
       if (tp->state != THREAD_RUNNING)
        continue;
-      if (tp->executing)
+      if (tp->executing ())
        continue;
 
       /* Remove matching threads from the step-over queue, so
@@ -3350,8 +3516,7 @@ infrun_thread_stop_requested (ptid_t ptid)
       if (!tp->has_pending_waitstatus ())
        {
          target_waitstatus ws;
-         ws.kind = TARGET_WAITKIND_STOPPED;
-         ws.value.sig = GDB_SIGNAL_0;
+         ws.set_stopped (GDB_SIGNAL_0);
          tp->set_pending_waitstatus (ws);
        }
 
@@ -3440,7 +3605,7 @@ delete_just_stopped_threads_single_step_breakpoints (void)
 
 void
 print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
-                          const struct target_waitstatus *ws)
+                          const struct target_waitstatus &ws)
 {
   infrun_debug_printf ("target_wait (%s [%s], status) =",
                       waiton_ptid.to_string ().c_str (),
@@ -3448,7 +3613,7 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
   infrun_debug_printf ("  %s [%s],",
                       result_ptid.to_string ().c_str (),
                       target_pid_to_str (result_ptid).c_str ());
-  infrun_debug_printf ("  %s", target_waitstatus_to_string (ws).c_str ());
+  infrun_debug_printf ("  %s", ws.to_string ().c_str ());
 }
 
 /* Select a thread at random, out of those which are resumed and have
@@ -3467,7 +3632,7 @@ random_pending_event_thread (inferior *inf, ptid_t waiton_ptid)
       return nullptr;
     }
 
-  infrun_debug_printf ("Found %s.", target_pid_to_str (thread->ptid).c_str ());
+  infrun_debug_printf ("Found %s.", thread->ptid.to_string ().c_str ());
   gdb_assert (thread->resumed ());
   gdb_assert (thread->has_pending_waitstatus ());
 
@@ -3483,7 +3648,6 @@ static ptid_t
 do_target_wait_1 (inferior *inf, ptid_t ptid,
                  target_waitstatus *status, target_wait_flags options)
 {
-  ptid_t event_ptid;
   struct thread_info *tp;
 
   /* We know that we are looking for an event in the target of inferior
@@ -3501,7 +3665,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
   else
     {
       infrun_debug_printf ("Waiting for specific thread %s.",
-                          target_pid_to_str (ptid).c_str ());
+                          ptid.to_string ().c_str ());
 
       /* We have a specific thread to check.  */
       tp = find_thread_ptid (inf, ptid);
@@ -3524,7 +3688,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
       if (pc != tp->stop_pc ())
        {
          infrun_debug_printf ("PC of %s changed.  was=%s, now=%s",
-                              target_pid_to_str (tp->ptid).c_str (),
+                              tp->ptid.to_string ().c_str (),
                               paddress (gdbarch, tp->stop_pc ()),
                               paddress (gdbarch, pc));
          discard = 1;
@@ -3532,7 +3696,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
       else if (!breakpoint_inserted_here_p (regcache->aspace (), pc))
        {
          infrun_debug_printf ("previous breakpoint of %s, at %s gone",
-                              target_pid_to_str (tp->ptid).c_str (),
+                              tp->ptid.to_string ().c_str (),
                               paddress (gdbarch, pc));
 
          discard = 1;
@@ -3541,11 +3705,11 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
       if (discard)
        {
          infrun_debug_printf ("pending event of %s cancelled.",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
 
          tp->clear_pending_waitstatus ();
          target_waitstatus ws;
-         ws.kind = TARGET_WAITKIND_SPURIOUS;
+         ws.set_spurious ();
          tp->set_pending_waitstatus (ws);
          tp->set_stop_reason (TARGET_STOPPED_BY_NO_REASON);
        }
@@ -3554,9 +3718,8 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
   if (tp != NULL)
     {
       infrun_debug_printf ("Using pending wait status %s for %s.",
-                          target_waitstatus_to_string
-                            (&tp->pending_waitstatus ()).c_str (),
-                          target_pid_to_str (tp->ptid).c_str ());
+                          tp->pending_waitstatus ().to_string ().c_str (),
+                          tp->ptid.to_string ().c_str ());
 
       /* Now that we've selected our final event LWP, un-adjust its PC
         if it was a software breakpoint (and the target doesn't
@@ -3599,12 +3762,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid,
   if (!target_can_async_p ())
     options &= ~TARGET_WNOHANG;
 
-  if (deprecated_target_wait_hook)
-    event_ptid = deprecated_target_wait_hook (ptid, status, options);
-  else
-    event_ptid = target_wait (ptid, status, options);
-
-  return event_ptid;
+  return target_wait (ptid, status, options);
 }
 
 /* Wrapper for target_wait that first checks whether threads have
@@ -3634,7 +3792,7 @@ do_target_wait (execution_control_state *ecs, target_wait_flags options)
 
   if (num_inferiors == 0)
     {
-      ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+      ecs->ws.set_ignore ();
       return false;
     }
 
@@ -3665,7 +3823,7 @@ do_target_wait (execution_control_state *ecs, target_wait_flags options)
   {
     ecs->ptid = do_target_wait_1 (inf, minus_one_ptid, &ecs->ws, options);
     ecs->target = inf->process_target ();
-    return (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+    return (ecs->ws.kind () != TARGET_WAITKIND_IGNORE);
   };
 
   /* Needed in 'all-stop + target-non-stop' mode, because we end up
@@ -3696,7 +3854,7 @@ do_target_wait (execution_control_state *ecs, target_wait_flags options)
        return true;
     }
 
-  ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+  ecs->ws.set_ignore ();
   return false;
 }
 
@@ -3715,7 +3873,6 @@ struct wait_one_event
 };
 
 static bool handle_one (const wait_one_event &event);
-static void restart_threads (struct thread_info *event_thread);
 
 /* Prepare and stabilize the inferior for detaching it.  E.g.,
    detaching while a thread is displaced stepping is a recipe for
@@ -3740,7 +3897,7 @@ prepare_for_detach (void)
     if (tp->inf == inf)
       {
        infrun_debug_printf ("removing thread %s from global step over chain",
-                            target_pid_to_str (tp->ptid).c_str ());
+                            tp->ptid.to_string ().c_str ());
        global_thread_step_over_chain_remove (tp);
       }
 
@@ -3783,7 +3940,7 @@ prepare_for_detach (void)
        {
          if (thr->displaced_step_state.in_progress ())
            {
-             if (thr->executing)
+             if (thr->executing ())
                {
                  if (!thr->stop_requested)
                    {
@@ -3804,7 +3961,7 @@ prepare_for_detach (void)
          event.ptid = do_target_wait_1 (inf, pid_ptid, &event.ws, 0);
 
          if (debug_infrun)
-           print_target_wait_results (pid_ptid, event.ptid, &event.ws);
+           print_target_wait_results (pid_ptid, event.ptid, event.ws);
 
          handle_one (event);
        }
@@ -3814,6 +3971,16 @@ prepare_for_detach (void)
     }
 }
 
+/* If all-stop, but there exists a non-stop target, stop all threads
+   now that we're presenting the stop to the user.  */
+
+static void
+stop_all_threads_if_all_stop_mode ()
+{
+  if (!non_stop && exists_non_stop_target ())
+    stop_all_threads ("presenting stop to user in all-stop");
+}
+
 /* Wait for control to return from inferior to debugger.
 
    If inferior gets a signal, we may decide to start it up again
@@ -3839,8 +4006,6 @@ wait_for_inferior (inferior *inf)
       struct execution_control_state ecss;
       struct execution_control_state *ecs = &ecss;
 
-      memset (ecs, 0, sizeof (*ecs));
-
       overlay_cache_invalid = 1;
 
       /* Flush target cache before starting to handle each event.
@@ -3853,7 +4018,7 @@ wait_for_inferior (inferior *inf)
       ecs->target = inf->process_target ();
 
       if (debug_infrun)
-       print_target_wait_results (minus_one_ptid, ecs->ptid, &ecs->ws);
+       print_target_wait_results (minus_one_ptid, ecs->ptid, ecs->ws);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
@@ -3862,6 +4027,8 @@ wait_for_inferior (inferior *inf)
        break;
     }
 
+  stop_all_threads_if_all_stop_mode ();
+
   /* No error, don't finish the state yet.  */
   finish_state.release ();
 }
@@ -3901,25 +4068,29 @@ reinstall_readline_callback_handler_cleanup ()
 static void
 clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
 {
-  if (ecs->event_thread != NULL
-      && ecs->event_thread->thread_fsm != NULL)
-    ecs->event_thread->thread_fsm->clean_up (ecs->event_thread);
+  /* The first clean_up call below assumes the event thread is the current
+     one.  */
+  if (ecs->event_thread != nullptr)
+    gdb_assert (ecs->event_thread == inferior_thread ());
+
+  if (ecs->event_thread != nullptr
+      && ecs->event_thread->thread_fsm () != nullptr)
+    ecs->event_thread->thread_fsm ()->clean_up (ecs->event_thread);
 
   if (!non_stop)
     {
+      scoped_restore_current_thread restore_thread;
+
       for (thread_info *thr : all_non_exited_threads ())
        {
-         if (thr->thread_fsm == NULL)
+         if (thr->thread_fsm () == nullptr)
            continue;
          if (thr == ecs->event_thread)
            continue;
 
          switch_to_thread (thr);
-         thr->thread_fsm->clean_up (thr);
+         thr->thread_fsm ()->clean_up (thr);
        }
-
-      if (ecs->event_thread != NULL)
-       switch_to_thread (ecs->event_thread);
     }
 }
 
@@ -3937,7 +4108,7 @@ check_curr_ui_sync_execution_done (void)
     {
       target_terminal::ours ();
       gdb::observers::sync_execution_done.notify ();
-      ui_register_input_event_handler (ui);
+      ui->register_file_handler ();
     }
 }
 
@@ -3982,8 +4153,6 @@ fetch_inferior_event ()
   struct execution_control_state *ecs = &ecss;
   int cmd_done = 0;
 
-  memset (ecs, 0, sizeof (*ecs));
-
   /* Events are always processed with the main UI as current UI.  This
      way, warnings, debug output, etc. are always consistently sent to
      the main console.  */
@@ -4038,14 +4207,14 @@ fetch_inferior_event ()
        return;
       }
 
-    gdb_assert (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+    gdb_assert (ecs->ws.kind () != TARGET_WAITKIND_IGNORE);
 
     /* Switch to the target that generated the event, so we can do
        target calls.  */
     switch_to_target_no_thread (ecs->target);
 
     if (debug_infrun)
-      print_target_wait_results (minus_one_ptid, ecs->ptid, &ecs->ws);
+      print_target_wait_results (minus_one_ptid, ecs->ptid, ecs->ws);
 
     /* If an error happens while handling the event, propagate GDB's
        knowledge of the executing state to the frontend/user running
@@ -4071,13 +4240,8 @@ fetch_inferior_event ()
 
        delete_just_stopped_threads_infrun_breakpoints ();
 
-       if (thr != NULL)
-         {
-           struct thread_fsm *thread_fsm = thr->thread_fsm;
-
-           if (thread_fsm != NULL)
-             should_stop = thread_fsm->should_stop (thr);
-         }
+       if (thr != nullptr && thr->thread_fsm () != nullptr)
+         should_stop = thr->thread_fsm ()->should_stop (thr);
 
        if (!should_stop)
          {
@@ -4088,10 +4252,13 @@ fetch_inferior_event ()
            bool should_notify_stop = true;
            int proceeded = 0;
 
+           stop_all_threads_if_all_stop_mode ();
+
            clean_up_just_stopped_threads_fsms (ecs);
 
-           if (thr != NULL && thr->thread_fsm != NULL)
-             should_notify_stop = thr->thread_fsm->should_notify_stop ();
+           if (thr != nullptr && thr->thread_fsm () != nullptr)
+             should_notify_stop
+              = thr->thread_fsm ()->should_notify_stop ();
 
            if (should_notify_stop)
              {
@@ -4116,7 +4283,7 @@ fetch_inferior_event ()
               selected.".  */
            if (!non_stop
                && cmd_done
-               && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
+               && ecs->ws.kind () != TARGET_WAITKIND_NO_RESUMED)
              restore_thread.dont_restore ();
          }
       }
@@ -4133,6 +4300,18 @@ fetch_inferior_event ()
        reinstalled here.  */
   }
 
+  /* Handling this event might have caused some inferiors to become prunable.
+     For example, the exit of an inferior that was automatically added.  Try
+     to get rid of them.  Keeping those around slows down things linearly.
+
+     Note that this never removes the current inferior.  Therefore, call this
+     after RESTORE_THREAD went out of scope, in case the event inferior (which was
+     temporarily made the current inferior) is meant to be deleted.
+
+     Call this before all_uis_check_sync_execution_done, so that notifications about
+     removed inferiors appear before the prompt.  */
+  prune_inferiors ();
+
   /* If a UI was in sync execution mode, and now isn't, restore its
      prompt (a synchronous execution command has finished, and we're
      ready for input).  */
@@ -4142,7 +4321,7 @@ fetch_inferior_event ()
       && exec_done_display_p
       && (inferior_ptid == null_ptid
          || inferior_thread ()->state != THREAD_RUNNING))
-    printf_unfiltered (_("completed.\n"));
+    gdb_printf (_("completed.\n"));
 }
 
 /* See infrun.h.  */
@@ -4160,6 +4339,13 @@ set_step_info (thread_info *tp, struct frame_info *frame,
 
   tp->current_symtab = sal.symtab;
   tp->current_line = sal.line;
+
+  infrun_debug_printf
+    ("symtab = %s, line = %d, step_frame_id = %s, step_stack_frame_id = %s",
+     tp->current_symtab != nullptr ? tp->current_symtab->filename : "<null>",
+     tp->current_line,
+     tp->control.step_frame_id.to_string ().c_str (),
+     tp->control.step_stack_frame_id.to_string ().c_str ());
 }
 
 /* Clear context switchable stepping state.  */
@@ -4177,7 +4363,7 @@ init_thread_stepping_state (struct thread_info *tss)
 
 void
 set_last_target_status (process_stratum_target *target, ptid_t ptid,
-                       target_waitstatus status)
+                       const target_waitstatus &status)
 {
   target_last_proc_target = target;
   target_last_wait_ptid = ptid;
@@ -4218,8 +4404,8 @@ context_switch (execution_control_state *ecs)
          || ecs->event_thread != inferior_thread ()))
     {
       infrun_debug_printf ("Switching context from %s to %s",
-                          target_pid_to_str (inferior_ptid).c_str (),
-                          target_pid_to_str (ecs->ptid).c_str ());
+                          inferior_ptid.to_string ().c_str (),
+                          ecs->ptid.to_string ().c_str ());
     }
 
   switch_to_thread (ecs->event_thread);
@@ -4232,7 +4418,7 @@ context_switch (execution_control_state *ecs)
 
 static void
 adjust_pc_after_break (struct thread_info *thread,
-                      const target_waitstatus *ws)
+                      const target_waitstatus &ws)
 {
   struct regcache *regcache;
   struct gdbarch *gdbarch;
@@ -4259,10 +4445,10 @@ adjust_pc_after_break (struct thread_info *thread,
      target with both of these set in GDB history, and it seems unlikely to be
      correct, so gdbarch_have_nonsteppable_watchpoint is not checked here.  */
 
-  if (ws->kind != TARGET_WAITKIND_STOPPED)
+  if (ws.kind () != TARGET_WAITKIND_STOPPED)
     return;
 
-  if (ws->value.sig != GDB_SIGNAL_TRAP)
+  if (ws.sig () != GDB_SIGNAL_TRAP)
     return;
 
   /* In reverse execution, when a breakpoint is hit, the instruction
@@ -4437,8 +4623,7 @@ handle_stop_requested (struct execution_control_state *ecs)
 {
   if (ecs->event_thread->stop_requested)
     {
-      ecs->ws.kind = TARGET_WAITKIND_STOPPED;
-      ecs->ws.value.sig = GDB_SIGNAL_0;
+      ecs->ws.set_stopped (GDB_SIGNAL_0);
       handle_signal_stop (ecs);
       return true;
     }
@@ -4459,18 +4644,18 @@ handle_syscall_event (struct execution_control_state *ecs)
   context_switch (ecs);
 
   regcache = get_thread_regcache (ecs->event_thread);
-  syscall_number = ecs->ws.value.syscall_number;
+  syscall_number = ecs->ws.syscall_number ();
   ecs->event_thread->set_stop_pc (regcache_read_pc (regcache));
 
   if (catch_syscall_enabled () > 0
-      && catching_syscall_number (syscall_number) > 0)
+      && catching_syscall_number (syscall_number))
     {
       infrun_debug_printf ("syscall number=%d", syscall_number);
 
       ecs->event_thread->control.stop_bpstat
-       = bpstat_stop_status (regcache->aspace (),
-                             ecs->event_thread->stop_pc (),
-                             ecs->event_thread, &ecs->ws);
+       = bpstat_stop_status_nowatch (regcache->aspace (),
+                                     ecs->event_thread->stop_pc (),
+                                     ecs->event_thread, ecs->ws);
 
       if (handle_stop_requested (ecs))
        return false;
@@ -4520,8 +4705,8 @@ fill_in_stop_func (struct gdbarch *gdbarch,
         stop_func_start is NOT advanced when in a range of a
         non-contiguous block that does not contain the entry pc.  */
       if (block != nullptr
-         && ecs->stop_func_start <= BLOCK_ENTRY_PC (block)
-         && BLOCK_ENTRY_PC (block) < ecs->stop_func_end)
+         && ecs->stop_func_start <= block->entry_pc ()
+         && block->entry_pc () < ecs->stop_func_end)
        {
          ecs->stop_func_start
            += gdbarch_deprecated_function_start_offset (gdbarch);
@@ -4563,13 +4748,10 @@ poll_one_curr_target (struct target_waitstatus *ws)
      don't get any event.  */
   target_dcache_invalidate ();
 
-  if (deprecated_target_wait_hook)
-    event_ptid = deprecated_target_wait_hook (minus_one_ptid, ws, TARGET_WNOHANG);
-  else
-    event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG);
+  event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG);
 
   if (debug_infrun)
-    print_target_wait_results (minus_one_ptid, event_ptid, ws);
+    print_target_wait_results (minus_one_ptid, event_ptid, *ws);
 
   return event_ptid;
 }
@@ -4595,13 +4777,13 @@ wait_one ()
          event.target = target;
          event.ptid = poll_one_curr_target (&event.ws);
 
-         if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+         if (event.ws.kind () == TARGET_WAITKIND_NO_RESUMED)
            {
              /* If nothing is resumed, remove the target from the
                 event loop.  */
-             target_async (0);
+             target_async (false);
            }
-         else if (event.ws.kind != TARGET_WAITKIND_IGNORE)
+         else if (event.ws.kind () != TARGET_WAITKIND_IGNORE)
            return event;
        }
 
@@ -4629,7 +4811,9 @@ wait_one ()
       if (nfds == 0)
        {
          /* No waitable targets left.  All must be stopped.  */
-         return {NULL, minus_one_ptid, {TARGET_WAITKIND_NO_RESUMED}};
+         target_waitstatus ws;
+         ws.set_no_resumed ();
+         return {NULL, minus_one_ptid, std::move (ws)};
        }
 
       QUIT;
@@ -4648,25 +4832,23 @@ wait_one ()
 /* Save the thread's event and stop reason to process it later.  */
 
 static void
-save_waitstatus (struct thread_info *tp, const target_waitstatus *ws)
+save_waitstatus (struct thread_info *tp, const target_waitstatus &ws)
 {
-  infrun_debug_printf ("saving status %s for %d.%ld.%ld",
-                      target_waitstatus_to_string (ws).c_str (),
-                      tp->ptid.pid (),
-                      tp->ptid.lwp (),
-                      tp->ptid.tid ());
+  infrun_debug_printf ("saving status %s for %s",
+                      ws.to_string ().c_str (),
+                      tp->ptid.to_string ().c_str ());
 
   /* Record for later.  */
-  tp->set_pending_waitstatus (*ws);
+  tp->set_pending_waitstatus (ws);
 
-  if (ws->kind == TARGET_WAITKIND_STOPPED
-      && ws->value.sig == GDB_SIGNAL_TRAP)
+  if (ws.kind () == TARGET_WAITKIND_STOPPED
+      && ws.sig () == GDB_SIGNAL_TRAP)
     {
       struct regcache *regcache = get_thread_regcache (tp);
       const address_space *aspace = regcache->aspace ();
       CORE_ADDR pc = regcache_read_pc (regcache);
 
-      adjust_pc_after_break (tp, &tp->pending_waitstatus ());
+      adjust_pc_after_break (tp, tp->pending_waitstatus ());
 
       scoped_restore_current_thread restore_thread;
       switch_to_thread (tp);
@@ -4698,14 +4880,14 @@ save_waitstatus (struct thread_info *tp, const target_waitstatus *ws)
 static void
 mark_non_executing_threads (process_stratum_target *target,
                            ptid_t event_ptid,
-                           struct target_waitstatus ws)
+                           const target_waitstatus &ws)
 {
   ptid_t mark_ptid;
 
   if (!target_is_non_stop_p ())
     mark_ptid = minus_one_ptid;
-  else if (ws.kind == TARGET_WAITKIND_SIGNALLED
-          || ws.kind == TARGET_WAITKIND_EXITED)
+  else if (ws.kind () == TARGET_WAITKIND_SIGNALLED
+          || ws.kind () == TARGET_WAITKIND_EXITED)
     {
       /* If we're handling a process exit in non-stop mode, even
         though threads haven't been deleted yet, one would think
@@ -4744,17 +4926,17 @@ static bool
 handle_one (const wait_one_event &event)
 {
   infrun_debug_printf
-    ("%s %s", target_waitstatus_to_string (&event.ws).c_str (),
-     target_pid_to_str (event.ptid).c_str ());
+    ("%s %s", event.ws.to_string ().c_str (),
+     event.ptid.to_string ().c_str ());
 
-  if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (event.ws.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       /* All resumed threads exited.  */
       return true;
     }
-  else if (event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
-          || event.ws.kind == TARGET_WAITKIND_EXITED
-          || event.ws.kind == TARGET_WAITKIND_SIGNALLED)
+  else if (event.ws.kind () == TARGET_WAITKIND_THREAD_EXITED
+          || event.ws.kind () == TARGET_WAITKIND_EXITED
+          || event.ws.kind () == TARGET_WAITKIND_SIGNALLED)
     {
       /* One thread/process exited/signalled.  */
 
@@ -4781,7 +4963,7 @@ handle_one (const wait_one_event &event)
          gdb_assert (t != nullptr);
 
          infrun_debug_printf
-           ("using %s", target_pid_to_str (t->ptid).c_str ());
+           ("using %s", t->ptid.to_string ().c_str ());
        }
       else
        {
@@ -4789,7 +4971,7 @@ handle_one (const wait_one_event &event)
          /* Check if this is the first time we see this thread.
             Don't bother adding if it individually exited.  */
          if (t == nullptr
-             && event.ws.kind != TARGET_WAITKIND_THREAD_EXITED)
+             && event.ws.kind () != TARGET_WAITKIND_THREAD_EXITED)
            t = add_thread (event.target, event.ptid);
        }
 
@@ -4800,7 +4982,7 @@ handle_one (const wait_one_event &event)
          switch_to_thread_no_regs (t);
          mark_non_executing_threads (event.target, event.ptid,
                                      event.ws);
-         save_waitstatus (t, &event.ws);
+         save_waitstatus (t, event.ws);
          t->stop_requested = false;
        }
     }
@@ -4811,21 +4993,20 @@ handle_one (const wait_one_event &event)
        t = add_thread (event.target, event.ptid);
 
       t->stop_requested = 0;
-      t->executing = 0;
+      t->set_executing (false);
       t->set_resumed (false);
       t->control.may_range_step = 0;
 
       /* This may be the first time we see the inferior report
         a stop.  */
-      inferior *inf = find_inferior_ptid (event.target, event.ptid);
-      if (inf->needs_setup)
+      if (t->inf->needs_setup)
        {
          switch_to_thread_no_regs (t);
          setup_inferior (0);
        }
 
-      if (event.ws.kind == TARGET_WAITKIND_STOPPED
-         && event.ws.value.sig == GDB_SIGNAL_0)
+      if (event.ws.kind () == TARGET_WAITKIND_STOPPED
+         && event.ws.sig () == GDB_SIGNAL_0)
        {
          /* We caught the event that we intended to catch, so
             there's no event to save as pending.  */
@@ -4836,7 +5017,7 @@ handle_one (const wait_one_event &event)
              /* Add it back to the step-over queue.  */
              infrun_debug_printf
                ("displaced-step of %s canceled",
-                target_pid_to_str (t->ptid).c_str ());
+                t->ptid.to_string ().c_str ());
 
              t->control.trap_expected = 0;
              if (!t->inf->detaching)
@@ -4849,15 +5030,15 @@ handle_one (const wait_one_event &event)
          struct regcache *regcache;
 
          infrun_debug_printf
-           ("target_wait %s, saving status for %d.%ld.%ld",
-            target_waitstatus_to_string (&event.ws).c_str (),
-            t->ptid.pid (), t->ptid.lwp (), t->ptid.tid ());
+           ("target_wait %s, saving status for %s",
+            event.ws.to_string ().c_str (),
+            t->ptid.to_string ().c_str ());
 
          /* Record for later.  */
-         save_waitstatus (t, &event.ws);
+         save_waitstatus (t, event.ws);
 
-         sig = (event.ws.kind == TARGET_WAITKIND_STOPPED
-                ? event.ws.value.sig : GDB_SIGNAL_0);
+         sig = (event.ws.kind () == TARGET_WAITKIND_STOPPED
+                ? event.ws.sig () : GDB_SIGNAL_0);
 
          if (displaced_step_finish (t, sig)
              == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
@@ -4874,7 +5055,7 @@ handle_one (const wait_one_event &event)
          infrun_debug_printf ("saved stop_pc=%s for %s "
                               "(currently_stepping=%d)",
                               paddress (target_gdbarch (), t->stop_pc ()),
-                              target_pid_to_str (t->ptid).c_str (),
+                              t->ptid.to_string ().c_str (),
                               currently_stepping (t));
        }
     }
@@ -4885,7 +5066,7 @@ handle_one (const wait_one_event &event)
 /* See infrun.h.  */
 
 void
-stop_all_threads (void)
+stop_all_threads (const char *reason, inferior *inf)
 {
   /* We may need multiple passes to discover all threads.  */
   int pass;
@@ -4893,22 +5074,32 @@ stop_all_threads (void)
 
   gdb_assert (exists_non_stop_target ());
 
-  infrun_debug_printf ("starting");
+  INFRUN_SCOPED_DEBUG_START_END ("reason=%s, inf=%d", reason,
+                                inf != nullptr ? inf->num : -1);
+
+  infrun_debug_show_threads ("non-exited threads",
+                            all_non_exited_threads ());
 
   scoped_restore_current_thread restore_thread;
 
-  /* Enable thread events of all targets.  */
+  /* Enable thread events on relevant targets.  */
   for (auto *target : all_non_exited_process_targets ())
     {
+      if (inf != nullptr && inf->process_target () != target)
+       continue;
+
       switch_to_target_no_thread (target);
       target_thread_events (true);
     }
 
   SCOPE_EXIT
     {
-      /* Disable thread events of all targets.  */
+      /* Disable thread events on relevant targets.  */
       for (auto *target : all_non_exited_process_targets ())
        {
+         if (inf != nullptr && inf->process_target () != target)
+           continue;
+
          switch_to_target_no_thread (target);
          target_thread_events (false);
        }
@@ -4933,6 +5124,9 @@ stop_all_threads (void)
 
          for (auto *target : all_non_exited_process_targets ())
            {
+             if (inf != nullptr && inf->process_target () != target)
+               continue;
+
              switch_to_target_no_thread (target);
              update_thread_list ();
            }
@@ -4941,6 +5135,9 @@ stop_all_threads (void)
             to tell the target to stop.  */
          for (thread_info *t : all_non_exited_threads ())
            {
+             if (inf != nullptr && t->inf != inf)
+               continue;
+
              /* For a single-target setting with an all-stop target,
                 we would not even arrive here.  For a multi-target
                 setting, until GDB is able to handle a mixture of
@@ -4952,21 +5149,21 @@ stop_all_threads (void)
              if (!target_is_non_stop_p ())
                continue;
 
-             if (t->executing)
+             if (t->executing ())
                {
                  /* If already stopping, don't request a stop again.
                     We just haven't seen the notification yet.  */
                  if (!t->stop_requested)
                    {
                      infrun_debug_printf ("  %s executing, need stop",
-                                          target_pid_to_str (t->ptid).c_str ());
+                                          t->ptid.to_string ().c_str ());
                      target_stop (t->ptid);
                      t->stop_requested = 1;
                    }
                  else
                    {
                      infrun_debug_printf ("  %s executing, already stopping",
-                                          target_pid_to_str (t->ptid).c_str ());
+                                          t->ptid.to_string ().c_str ());
                    }
 
                  if (t->stop_requested)
@@ -4975,7 +5172,7 @@ stop_all_threads (void)
              else
                {
                  infrun_debug_printf ("  %s not executing",
-                                      target_pid_to_str (t->ptid).c_str ());
+                                      t->ptid.to_string ().c_str ());
 
                  /* The thread may be not executing, but still be
                     resumed with a pending status to process.  */
@@ -5068,12 +5265,7 @@ handle_no_resumed (struct execution_control_state *ecs)
   inferior *curr_inf = current_inferior ();
 
   scoped_restore_current_thread restore_thread;
-
-  for (auto *target : all_non_exited_process_targets ())
-    {
-      switch_to_target_no_thread (target);
-      update_thread_list ();
-    }
+  update_thread_list ();
 
   /* If:
 
@@ -5096,7 +5288,7 @@ handle_no_resumed (struct execution_control_state *ecs)
 
   for (thread_info *thread : all_non_exited_threads ())
     {
-      if (swap_terminal && thread->executing)
+      if (swap_terminal && thread->executing ())
        {
          if (thread->inf != curr_inf)
            {
@@ -5108,8 +5300,7 @@ handle_no_resumed (struct execution_control_state *ecs)
          swap_terminal = false;
        }
 
-      if (!ignore_event
-         && (thread->executing || thread->has_pending_waitstatus ()))
+      if (!ignore_event && thread->resumed ())
        {
          /* Either there were no unwaited-for children left in the
             target at some point, but there are now, or some target
@@ -5157,9 +5348,9 @@ handle_inferior_event (struct execution_control_state *ecs)
      end.  */
   scoped_value_mark free_values;
 
-  infrun_debug_printf ("%s", target_waitstatus_to_string (&ecs->ws).c_str ());
+  infrun_debug_printf ("%s", ecs->ws.to_string ().c_str ());
 
-  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
+  if (ecs->ws.kind () == TARGET_WAITKIND_IGNORE)
     {
       /* We had an event in the inferior, but we are not interested in
         handling it at this level.  The lower layers have already
@@ -5174,13 +5365,13 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+  if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
     {
       prepare_to_wait (ecs);
       return;
     }
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED
+  if (ecs->ws.kind () == TARGET_WAITKIND_NO_RESUMED
       && handle_no_resumed (ecs))
     return;
 
@@ -5190,7 +5381,7 @@ handle_inferior_event (struct execution_control_state *ecs)
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (ecs->ws.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       /* No unwaited-for children left.  IOW, all resumed children
         have exited.  */
@@ -5199,8 +5390,8 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+  if (ecs->ws.kind () != TARGET_WAITKIND_EXITED
+      && ecs->ws.kind () != TARGET_WAITKIND_SIGNALLED)
     {
       ecs->event_thread = find_thread_ptid (ecs->target, ecs->ptid);
       /* If it's a new thread, add it to the thread database.  */
@@ -5213,7 +5404,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     }
 
   /* Dependent on valid ECS->EVENT_THREAD.  */
-  adjust_pc_after_break (ecs->event_thread, &ecs->ws);
+  adjust_pc_after_break (ecs->event_thread, ecs->ws);
 
   /* Dependent on the current PC value modified by adjust_pc_after_break.  */
   reinit_frame_cache ();
@@ -5230,10 +5421,10 @@ handle_inferior_event (struct execution_control_state *ecs)
      non-executable stack.  This happens for call dummy breakpoints
      for architectures like SPARC that place call dummies on the
      stack.  */
-  if (ecs->ws.kind == TARGET_WAITKIND_STOPPED
-      && (ecs->ws.value.sig == GDB_SIGNAL_ILL
-         || ecs->ws.value.sig == GDB_SIGNAL_SEGV
-         || ecs->ws.value.sig == GDB_SIGNAL_EMT))
+  if (ecs->ws.kind () == TARGET_WAITKIND_STOPPED
+      && (ecs->ws.sig () == GDB_SIGNAL_ILL
+         || ecs->ws.sig () == GDB_SIGNAL_SEGV
+         || ecs->ws.sig () == GDB_SIGNAL_EMT))
     {
       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
 
@@ -5241,13 +5432,13 @@ handle_inferior_event (struct execution_control_state *ecs)
                                      regcache_read_pc (regcache)))
        {
          infrun_debug_printf ("Treating signal as SIGTRAP");
-         ecs->ws.value.sig = GDB_SIGNAL_TRAP;
+         ecs->ws.set_stopped (GDB_SIGNAL_TRAP);
        }
     }
 
   mark_non_executing_threads (ecs->target, ecs->ptid, ecs->ws);
 
-  switch (ecs->ws.kind)
+  switch (ecs->ws.kind ())
     {
     case TARGET_WAITKIND_LOADED:
       {
@@ -5268,10 +5459,11 @@ handle_inferior_event (struct execution_control_state *ecs)
 
            handle_solib_event ();
 
+           ecs->event_thread->set_stop_pc (regcache_read_pc (regcache));
            ecs->event_thread->control.stop_bpstat
-             = bpstat_stop_status (regcache->aspace (),
-                                   ecs->event_thread->stop_pc (),
-                                   ecs->event_thread, &ecs->ws);
+             = bpstat_stop_status_nowatch (regcache->aspace (),
+                                           ecs->event_thread->stop_pc (),
+                                           ecs->event_thread, ecs->ws);
 
            if (handle_stop_requested (ecs))
              return;
@@ -5366,21 +5558,21 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* Clearing any previous state of convenience variables.  */
       clear_exit_convenience_vars ();
 
-      if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
+      if (ecs->ws.kind () == TARGET_WAITKIND_EXITED)
        {
          /* Record the exit code in the convenience variable $_exitcode, so
             that the user can inspect this again later.  */
          set_internalvar_integer (lookup_internalvar ("_exitcode"),
-                                  (LONGEST) ecs->ws.value.integer);
+                                  (LONGEST) ecs->ws.exit_status ());
 
          /* Also record this in the inferior itself.  */
          current_inferior ()->has_exit_code = 1;
-         current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+         current_inferior ()->exit_code = (LONGEST) ecs->ws.exit_status ();
 
          /* Support the --return-child-result option.  */
-         return_child_result_value = ecs->ws.value.integer;
+         return_child_result_value = ecs->ws.exit_status ();
 
-         gdb::observers::exited.notify (ecs->ws.value.integer);
+         gdb::observers::exited.notify (ecs->ws.exit_status ());
        }
       else
        {
@@ -5392,7 +5584,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                 which holds the signal uncaught by the inferior.  */
              set_internalvar_integer (lookup_internalvar ("_exitsignal"),
                                       gdbarch_gdb_signal_to_target (gdbarch,
-                                                         ecs->ws.value.sig));
+                                                         ecs->ws.sig ()));
            }
          else
            {
@@ -5407,7 +5599,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                                   "signal number.");
            }
 
-         gdb::observers::signal_exited.notify (ecs->ws.value.sig);
+         gdb::observers::signal_exited.notify (ecs->ws.sig ());
        }
 
       gdb_flush (gdb_stdout);
@@ -5434,10 +5626,10 @@ handle_inferior_event (struct execution_control_state *ecs)
           gdbarch_displaced_step_restore_all_in_ptid.  This is not
           enforced during gdbarch validation to support architectures
           which support displaced stepping but not forks.  */
-       if (ecs->ws.kind == TARGET_WAITKIND_FORKED
+       if (ecs->ws.kind () == TARGET_WAITKIND_FORKED
            && gdbarch_supports_displaced_stepping (gdbarch))
          gdbarch_displaced_step_restore_all_in_ptid
-           (gdbarch, parent_inf, ecs->ws.value.related_pid);
+           (gdbarch, parent_inf, ecs->ws.child_ptid ());
 
        /* If displaced stepping is supported, and thread ecs->ptid is
           displaced stepping.  */
@@ -5465,7 +5657,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
            child_regcache
              = get_thread_arch_aspace_regcache (parent_inf->process_target (),
-                                                ecs->ws.value.related_pid,
+                                                ecs->ws.child_ptid (),
                                                 gdbarch,
                                                 parent_inf->aspace);
            /* Read PC value of parent process.  */
@@ -5494,11 +5686,11 @@ handle_inferior_event (struct execution_control_state *ecs)
         need to unpatch at follow/detach time instead to be certain
         that new breakpoints added between catchpoint hit time and
         vfork follow are detached.  */
-      if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
+      if (ecs->ws.kind () != TARGET_WAITKIND_VFORKED)
        {
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (ecs->ws.value.related_pid);
+         detach_breakpoints (ecs->ws.child_ptid ());
        }
 
       delete_just_stopped_threads_single_step_breakpoints ();
@@ -5512,9 +5704,9 @@ handle_inferior_event (struct execution_control_state *ecs)
        (regcache_read_pc (get_thread_regcache (ecs->event_thread)));
 
       ecs->event_thread->control.stop_bpstat
-       = bpstat_stop_status (get_current_regcache ()->aspace (),
-                             ecs->event_thread->stop_pc (),
-                             ecs->event_thread, &ecs->ws);
+       = bpstat_stop_status_nowatch (get_current_regcache ()->aspace (),
+                                     ecs->event_thread->stop_pc (),
+                                     ecs->event_thread, ecs->ws);
 
       if (handle_stop_requested (ecs))
        return;
@@ -5538,8 +5730,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          /* Note that one of these may be an invalid pointer,
             depending on detach_fork.  */
          thread_info *parent = ecs->event_thread;
-         thread_info *child
-           = find_thread_ptid (targ, ecs->ws.value.related_pid);
+         thread_info *child = find_thread_ptid (targ, ecs->ws.child_ptid ());
 
          /* At this point, the parent is marked running, and the
             child is marked stopped.  */
@@ -5575,7 +5766,18 @@ handle_inferior_event (struct execution_control_state *ecs)
          ecs->ptid = inferior_ptid;
 
          if (should_resume)
-           keep_going (ecs);
+           {
+             /* Never call switch_back_to_stepped_thread if we are waiting for
+                vfork-done (waiting for an external vfork child to exec or
+                exit).  We will resume only the vforking thread for the purpose
+                of collecting the vfork-done event, and we will restart any
+                step once the critical shared address space window is done.  */
+             if ((!follow_child
+                  && detach_fork
+                  && parent->inf->thread_waiting_for_vfork_done != nullptr)
+                 || !switch_back_to_stepped_thread (ecs))
+               keep_going (ecs);
+           }
          else
            stop_waiting (ecs);
          return;
@@ -5589,15 +5791,19 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       context_switch (ecs);
 
-      current_inferior ()->waiting_for_vfork_done = 0;
-      current_inferior ()->pspace->breakpoints_not_allowed = 0;
+      handle_vfork_done (ecs->event_thread);
+      gdb_assert (inferior_thread () == ecs->event_thread);
 
       if (handle_stop_requested (ecs))
        return;
 
-      /* This also takes care of reinserting breakpoints in the
-        previously locked inferior.  */
-      keep_going (ecs);
+      if (!switch_back_to_stepped_thread (ecs))
+       {
+         gdb_assert (inferior_thread () == ecs->event_thread);
+         /* This also takes care of reinserting breakpoints in the
+            previously locked inferior.  */
+         keep_going (ecs);
+       }
       return;
 
     case TARGET_WAITKIND_EXECD:
@@ -5613,7 +5819,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* This causes the eventpoints and symbol table to be reset.
         Must do this now, before trying to determine whether to
         stop.  */
-      follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
+      follow_exec (inferior_ptid, ecs->ws.execd_pathname ());
 
       /* In follow_exec we may have deleted the original thread and
         created a new one.  Make sure that the event thread is the
@@ -5624,14 +5830,9 @@ handle_inferior_event (struct execution_control_state *ecs)
        (regcache_read_pc (get_thread_regcache (ecs->event_thread)));
 
       ecs->event_thread->control.stop_bpstat
-       = bpstat_stop_status (get_current_regcache ()->aspace (),
-                             ecs->event_thread->stop_pc (),
-                             ecs->event_thread, &ecs->ws);
-
-      /* Note that this may be referenced from inside
-        bpstat_stop_status above, through inferior_has_execd.  */
-      xfree (ecs->ws.value.execd_pathname);
-      ecs->ws.value.execd_pathname = NULL;
+       = bpstat_stop_status_nowatch (get_current_regcache ()->aspace (),
+                                     ecs->event_thread->stop_pc (),
+                                     ecs->event_thread, ecs->ws);
 
       if (handle_stop_requested (ecs))
        return;
@@ -5689,21 +5890,32 @@ handle_inferior_event (struct execution_control_state *ecs)
 }
 
 /* Restart threads back to what they were trying to do back when we
-   paused them for an in-line step-over.  The EVENT_THREAD thread is
-   ignored.  */
+   paused them (because of an in-line step-over or vfork, for example).
+   The EVENT_THREAD thread is ignored (not restarted).
+
+   If INF is non-nullptr, only resume threads from INF.  */
 
 static void
-restart_threads (struct thread_info *event_thread)
+restart_threads (struct thread_info *event_thread, inferior *inf)
 {
+  INFRUN_SCOPED_DEBUG_START_END ("event_thread=%s, inf=%d",
+                                event_thread->ptid.to_string ().c_str (),
+                                inf != nullptr ? inf->num : -1);
+
+  gdb_assert (!step_over_info_valid_p ());
+
   /* In case the instruction just stepped spawned a new thread.  */
   update_thread_list ();
 
   for (thread_info *tp : all_non_exited_threads ())
     {
+      if (inf != nullptr && tp->inf != inf)
+       continue;
+
       if (tp->inf->detaching)
        {
          infrun_debug_printf ("restart threads: [%s] inferior detaching",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          continue;
        }
 
@@ -5712,29 +5924,29 @@ restart_threads (struct thread_info *event_thread)
       if (tp == event_thread)
        {
          infrun_debug_printf ("restart threads: [%s] is event thread",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          continue;
        }
 
       if (!(tp->state == THREAD_RUNNING || tp->control.in_infcall))
        {
          infrun_debug_printf ("restart threads: [%s] not meant to be running",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          continue;
        }
 
       if (tp->resumed ())
        {
          infrun_debug_printf ("restart threads: [%s] resumed",
-                             target_pid_to_str (tp->ptid).c_str ());
-         gdb_assert (tp->executing || tp->has_pending_waitstatus ());
+                             tp->ptid.to_string ().c_str ());
+         gdb_assert (tp->executing () || tp->has_pending_waitstatus ());
          continue;
        }
 
       if (thread_is_in_step_over_chain (tp))
        {
          infrun_debug_printf ("restart threads: [%s] needs step-over",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          gdb_assert (!tp->resumed ());
          continue;
        }
@@ -5743,7 +5955,7 @@ restart_threads (struct thread_info *event_thread)
       if (tp->has_pending_waitstatus ())
        {
          infrun_debug_printf ("restart threads: [%s] has pending status",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          tp->set_resumed (true);
          continue;
        }
@@ -5758,13 +5970,13 @@ restart_threads (struct thread_info *event_thread)
          internal_error (__FILE__, __LINE__,
                          "thread [%s] needs a step-over, but not in "
                          "step-over queue\n",
-                         target_pid_to_str (tp->ptid).c_str ());
+                         tp->ptid.to_string ().c_str ());
        }
 
       if (currently_stepping (tp))
        {
          infrun_debug_printf ("restart threads: [%s] was stepping",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          keep_going_stepped_thread (tp);
        }
       else
@@ -5773,7 +5985,7 @@ restart_threads (struct thread_info *event_thread)
          struct execution_control_state *ecs = &ecss;
 
          infrun_debug_printf ("restart threads: [%s] continuing",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          reset_ecs (ecs, tp);
          switch_to_thread (tp);
          keep_going_pass_signal (ecs);
@@ -5868,13 +6080,13 @@ finish_step_over (struct execution_control_state *ecs)
          gdb_assert (pending != tp);
 
          /* Record the event thread's event for later.  */
-         save_waitstatus (tp, &ecs->ws);
+         save_waitstatus (tp, ecs->ws);
          /* This was cleared early, by handle_inferior_event.  Set it
             so this pending event is considered by
             do_target_wait.  */
          tp->set_resumed (true);
 
-         gdb_assert (!tp->executing);
+         gdb_assert (!tp->executing ());
 
          regcache = get_thread_regcache (tp);
          tp->set_stop_pc (regcache_read_pc (regcache));
@@ -5882,7 +6094,7 @@ finish_step_over (struct execution_control_state *ecs)
          infrun_debug_printf ("saved stop_pc=%s for %s "
                               "(currently_stepping=%d)",
                               paddress (target_gdbarch (), tp->stop_pc ()),
-                              target_pid_to_str (tp->ptid).c_str (),
+                              tp->ptid.to_string ().c_str (),
                               currently_stepping (tp));
 
          /* This in-line step-over finished; clear this so we won't
@@ -5912,9 +6124,9 @@ handle_signal_stop (struct execution_control_state *ecs)
   enum stop_kind stop_soon;
   int random_signal;
 
-  gdb_assert (ecs->ws.kind == TARGET_WAITKIND_STOPPED);
+  gdb_assert (ecs->ws.kind () == TARGET_WAITKIND_STOPPED);
 
-  ecs->event_thread->set_stop_signal (ecs->ws.value.sig);
+  ecs->event_thread->set_stop_signal (ecs->ws.sig ());
 
   /* Do we need to clean up the state of a thread that has
      completed a displaced single-step?  (Doing so usually affects
@@ -6026,14 +6238,14 @@ handle_signal_stop (struct execution_control_state *ecs)
            {
              infrun_debug_printf ("[%s] hit another thread's single-step "
                                   "breakpoint",
-                                  target_pid_to_str (ecs->ptid).c_str ());
+                                  ecs->ptid.to_string ().c_str ());
              ecs->hit_singlestep_breakpoint = 1;
            }
        }
       else
        {
          infrun_debug_printf ("[%s] hit its single-step breakpoint",
-                              target_pid_to_str (ecs->ptid).c_str ());
+                              ecs->ptid.to_string ().c_str ());
        }
     }
   delete_just_stopped_threads_single_step_breakpoints ();
@@ -6043,7 +6255,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       && ecs->event_thread->stepping_over_watchpoint)
     stopped_by_watchpoint = 0;
   else
-    stopped_by_watchpoint = watchpoints_triggered (&ecs->ws);
+    stopped_by_watchpoint = watchpoints_triggered (ecs->ws);
 
   /* If necessary, step over this watchpoint.  We'll be back to display
      it in a moment.  */
@@ -6089,7 +6301,7 @@ handle_signal_stop (struct execution_control_state *ecs)
   ecs->event_thread->control.stop_step = 0;
   stop_print_frame = true;
   stopped_by_random_signal = 0;
-  bpstat stop_chain = NULL;
+  bpstat *stop_chain = nullptr;
 
   /* Hide inlined functions starting here, unless we just performed stepi or
      nexti.  After stepi and nexti, always show the innermost frame (not any
@@ -6116,16 +6328,16 @@ handle_signal_stop (struct execution_control_state *ecs)
         that's an extremely unlikely scenario.  */
       if (!pc_at_non_inline_function (aspace,
                                      ecs->event_thread->stop_pc (),
-                                     &ecs->ws)
+                                     ecs->ws)
          && !(ecs->event_thread->stop_signal () == GDB_SIGNAL_TRAP
               && ecs->event_thread->control.trap_expected
               && pc_at_non_inline_function (aspace,
                                             ecs->event_thread->prev_pc,
-                                            &ecs->ws)))
+                                            ecs->ws)))
        {
          stop_chain = build_bpstat_chain (aspace,
                                           ecs->event_thread->stop_pc (),
-                                          &ecs->ws);
+                                          ecs->ws);
          skip_inline_frames (ecs->event_thread, stop_chain);
 
          /* Re-fetch current thread's frame in case that invalidated
@@ -6177,7 +6389,7 @@ handle_signal_stop (struct execution_control_state *ecs)
   ecs->event_thread->control.stop_bpstat
     = bpstat_stop_status (get_current_regcache ()->aspace (),
                          ecs->event_thread->stop_pc (),
-                         ecs->event_thread, &ecs->ws, stop_chain);
+                         ecs->event_thread, ecs->ws, stop_chain);
 
   /* Following in case break condition called a
      function.  */
@@ -7241,6 +7453,11 @@ process_event_stop_test (struct execution_control_state *ecs)
   ecs->event_thread->control.step_range_start = stop_pc_sal.pc;
   ecs->event_thread->control.step_range_end = stop_pc_sal.end;
   ecs->event_thread->control.may_range_step = 1;
+  infrun_debug_printf
+    ("updated step range, start = %s, end = %s, may_range_step = %d",
+     paddress (gdbarch, ecs->event_thread->control.step_range_start),
+     paddress (gdbarch, ecs->event_thread->control.step_range_end),
+     ecs->event_thread->control.may_range_step);
   if (refresh_step_info)
     set_step_info (ecs->event_thread, frame, stop_pc_sal);
 
@@ -7279,7 +7496,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
        {
          infrun_debug_printf
            ("need to finish step-over of [%s]",
-            target_pid_to_str (ecs->event_thread->ptid).c_str ());
+            ecs->event_thread->ptid.to_string ().c_str ());
          keep_going (ecs);
          return true;
        }
@@ -7289,7 +7506,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
       if (ecs->hit_singlestep_breakpoint)
        {
         infrun_debug_printf ("need to step [%s] over single-step breakpoint",
-                             target_pid_to_str (ecs->ptid).c_str ());
+                             ecs->ptid.to_string ().c_str ());
         keep_going (ecs);
         return true;
        }
@@ -7301,7 +7518,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
        {
          infrun_debug_printf
            ("thread [%s] still needs step-over",
-            target_pid_to_str (ecs->event_thread->ptid).c_str ());
+            ecs->event_thread->ptid.to_string ().c_str ());
          keep_going (ecs);
          return true;
        }
@@ -7424,7 +7641,7 @@ restart_after_all_stop_detach (process_stratum_target *proc_target)
       /* If we have any thread that is already executing, then we
         don't need to resume the target -- it is already been
         resumed.  */
-      if (thr->executing)
+      if (thr->executing ())
        return;
 
       /* If we have a pending event to process, skip resuming the
@@ -7907,10 +8124,10 @@ check_exception_resume (struct execution_control_state *ecs,
         cases such as throwing an exception from inside a signal
         handler.  */
 
-      b = SYMBOL_BLOCK_VALUE (func);
+      b = func->value_block ();
       ALL_BLOCK_SYMBOLS (b, iter, sym)
        {
-         if (!SYMBOL_IS_ARGUMENT (sym))
+         if (!sym->is_argument ())
            continue;
 
          if (argno == 0)
@@ -7935,11 +8152,6 @@ stop_waiting (struct execution_control_state *ecs)
 
   /* Let callers know we don't want to wait for the inferior anymore.  */
   ecs->wait_some_more = 0;
-
-  /* If all-stop, but there exists a non-stop target, stop all
-     threads now that we're presenting the stop to the user.  */
-  if (!non_stop && exists_non_stop_target ())
-    stop_all_threads ();
 }
 
 /* Like keep_going, but passes the signal to the inferior, even if the
@@ -7961,7 +8173,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
 
       infrun_debug_printf ("%s has trap_expected set, "
                           "resuming to collect trap",
-                          target_pid_to_str (tp->ptid).c_str ());
+                          tp->ptid.to_string ().c_str ());
 
       /* We haven't yet gotten our trap, and either: intercepted a
         non-signal event (e.g., a fork); or took a signal which we
@@ -7981,14 +8193,12 @@ keep_going_pass_signal (struct execution_control_state *ecs)
        {
          infrun_debug_printf ("step-over already in progress: "
                               "step-over for %s deferred",
-                              target_pid_to_str (tp->ptid).c_str ());
+                              tp->ptid.to_string ().c_str ());
          global_thread_step_over_chain_enqueue (tp);
        }
       else
-       {
-         infrun_debug_printf ("step-over in progress: resume of %s deferred",
-                              target_pid_to_str (tp->ptid).c_str ());
-       }
+       infrun_debug_printf ("step-over in progress: resume of %s deferred",
+                            tp->ptid.to_string ().c_str ());
     }
   else
     {
@@ -8041,7 +8251,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
         we're about to step over, otherwise other threads could miss
         it.  */
       if (step_over_info_valid_p () && target_is_non_stop_p ())
-       stop_all_threads ();
+       stop_all_threads ("starting in-line step-over");
 
       /* Stop stepping if inserting breakpoints fails.  */
       try
@@ -8191,12 +8401,10 @@ print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
     ;
   else if (show_thread_that_caused_stop ())
     {
-      const char *name;
-
       uiout->text ("\nThread ");
       uiout->field_string ("thread-id", print_thread_id (thr));
 
-      name = thr->name != NULL ? thr->name : target_thread_name (thr);
+      const char *name = thread_name (thr);
       if (name != NULL)
        {
          uiout->text (" \"");
@@ -8244,14 +8452,14 @@ print_no_history_reason (struct ui_out *uiout)
    based on the event(s) that just occurred.  */
 
 static void
-print_stop_location (struct target_waitstatus *ws)
+print_stop_location (const target_waitstatus &ws)
 {
   int bpstat_ret;
   enum print_what source_flag;
   int do_frame_printing = 1;
   struct thread_info *tp = inferior_thread ();
 
-  bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind);
+  bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws.kind ());
   switch (bpstat_ret)
     {
     case PRINT_UNKNOWN:
@@ -8311,7 +8519,7 @@ print_stop_event (struct ui_out *uiout, bool displays)
   {
     scoped_restore save_uiout = make_scoped_restore (&current_uiout, uiout);
 
-    print_stop_location (&last);
+    print_stop_location (last);
 
     /* Display the auto-display expressions.  */
     if (displays)
@@ -8319,13 +8527,13 @@ print_stop_event (struct ui_out *uiout, bool displays)
   }
 
   tp = inferior_thread ();
-  if (tp->thread_fsm != NULL
-      && tp->thread_fsm->finished_p ())
+  if (tp->thread_fsm () != nullptr
+      && tp->thread_fsm ()->finished_p ())
     {
       struct return_value_info *rv;
 
-      rv = tp->thread_fsm->return_value ();
-      if (rv != NULL)
+      rv = tp->thread_fsm ()->return_value ();
+      if (rv != nullptr)
        print_return_value (uiout, rv);
     }
 }
@@ -8340,9 +8548,9 @@ maybe_remove_breakpoints (void)
       if (remove_breakpoints ())
        {
          target_terminal::ours_for_output ();
-         printf_filtered (_("Cannot remove breakpoints because "
-                            "program is no longer writable.\nFurther "
-                            "execution is probably impossible.\n"));
+         gdb_printf (_("Cannot remove breakpoints because "
+                       "program is no longer writable.\nFurther "
+                       "execution is probably impossible.\n"));
        }
     }
 }
@@ -8426,8 +8634,8 @@ normal_stop (void)
 
   if (!non_stop)
     finish_ptid = minus_one_ptid;
-  else if (last.kind == TARGET_WAITKIND_SIGNALLED
-          || last.kind == TARGET_WAITKIND_EXITED)
+  else if (last.kind () == TARGET_WAITKIND_SIGNALLED
+          || last.kind () == TARGET_WAITKIND_EXITED)
     {
       /* On some targets, we may still have live threads in the
         inferior when we get a process exit event.  E.g., for
@@ -8437,7 +8645,7 @@ normal_stop (void)
       if (inferior_ptid != null_ptid)
        finish_ptid = ptid_t (inferior_ptid.pid ());
     }
-  else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
+  else if (last.kind () != TARGET_WAITKIND_NO_RESUMED)
     finish_ptid = inferior_ptid;
 
   gdb::optional<scoped_finish_thread_state> maybe_finish_thread_state;
@@ -8457,7 +8665,7 @@ normal_stop (void)
      instead of after.  */
   update_thread_list ();
 
-  if (last.kind == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
+  if (last.kind () == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
     gdb::observers::signal_received.notify (inferior_thread ()->stop_signal ());
 
   /* As with the notification of thread events, we want to delay
@@ -8479,27 +8687,27 @@ normal_stop (void)
   if (!non_stop
       && previous_inferior_ptid != inferior_ptid
       && target_has_execution ()
-      && last.kind != TARGET_WAITKIND_SIGNALLED
-      && last.kind != TARGET_WAITKIND_EXITED
-      && last.kind != TARGET_WAITKIND_NO_RESUMED)
+      && last.kind () != TARGET_WAITKIND_SIGNALLED
+      && last.kind () != TARGET_WAITKIND_EXITED
+      && last.kind () != TARGET_WAITKIND_NO_RESUMED)
     {
       SWITCH_THRU_ALL_UIS ()
        {
          target_terminal::ours_for_output ();
-         printf_filtered (_("[Switching to %s]\n"),
-                          target_pid_to_str (inferior_ptid).c_str ());
+         gdb_printf (_("[Switching to %s]\n"),
+                     target_pid_to_str (inferior_ptid).c_str ());
          annotate_thread_changed ();
        }
       previous_inferior_ptid = inferior_ptid;
     }
 
-  if (last.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (last.kind () == TARGET_WAITKIND_NO_RESUMED)
     {
       SWITCH_THRU_ALL_UIS ()
        if (current_ui->prompt_state == PROMPT_BLOCKED)
          {
            target_terminal::ours_for_output ();
-           printf_filtered (_("No unwaited-for children left.\n"));
+           gdb_printf (_("No unwaited-for children left.\n"));
          }
     }
 
@@ -8550,29 +8758,26 @@ normal_stop (void)
 
   /* Look up the hook_stop and run it (CLI internally handles problem
      of stop_command's pre-hook not existing).  */
-  if (stop_command != NULL)
-    {
-      stop_context saved_context;
-
-      try
-       {
-         execute_cmd_pre_hook (stop_command);
-       }
-      catch (const gdb_exception &ex)
-       {
-         exception_fprintf (gdb_stderr, ex,
-                            "Error while running hook_stop:\n");
-       }
+  stop_context saved_context;
 
-      /* If the stop hook resumes the target, then there's no point in
-        trying to notify about the previous stop; its context is
-        gone.  Likewise if the command switches thread or inferior --
-        the observers would print a stop for the wrong
-        thread/inferior.  */
-      if (saved_context.changed ())
-       return 1;
+  try
+    {
+      execute_cmd_pre_hook (stop_command);
+    }
+  catch (const gdb_exception &ex)
+    {
+      exception_fprintf (gdb_stderr, ex,
+                        "Error while running hook_stop:\n");
     }
 
+  /* If the stop hook resumes the target, then there's no point in
+     trying to notify about the previous stop; its context is
+     gone.  Likewise if the command switches thread or inferior --
+     the observers would print a stop for the wrong
+     thread/inferior.  */
+  if (saved_context.changed ())
+    return 1;
+
   /* Notify observers about the stop.  This is where the interpreters
      print the stop event.  */
   if (inferior_ptid != null_ptid)
@@ -8585,19 +8790,14 @@ normal_stop (void)
 
   if (target_has_execution ())
     {
-      if (last.kind != TARGET_WAITKIND_SIGNALLED
-         && last.kind != TARGET_WAITKIND_EXITED
-         && last.kind != TARGET_WAITKIND_NO_RESUMED)
+      if (last.kind () != TARGET_WAITKIND_SIGNALLED
+         && last.kind () != TARGET_WAITKIND_EXITED
+         && last.kind () != TARGET_WAITKIND_NO_RESUMED)
        /* Delete the breakpoint we stopped at, if it wants to be deleted.
           Delete any breakpoint that is to be deleted at the next stop.  */
        breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
     }
 
-  /* Try to get rid of automatically added inferiors that are no
-     longer needed.  Keeping those around slows down things linearly.
-     Note that this never removes the current inferior.  */
-  prune_inferiors ();
-
   return 0;
 }
 \f
@@ -8683,8 +8883,8 @@ signal_catch_update (const unsigned int *info)
 static void
 sig_print_header (void)
 {
-  printf_filtered (_("Signal        Stop\tPrint\tPass "
-                    "to program\tDescription\n"));
+  gdb_printf (_("Signal        Stop\tPrint\tPass "
+               "to program\tDescription\n"));
 }
 
 static void
@@ -8696,12 +8896,12 @@ sig_print_info (enum gdb_signal oursig)
   if (name_padding <= 0)
     name_padding = 0;
 
-  printf_filtered ("%s", name);
-  printf_filtered ("%*.*s ", name_padding, name_padding, "                 ");
-  printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
-  printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
-  printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
-  printf_filtered ("%s\n", gdb_signal_to_string (oursig));
+  gdb_printf ("%s", name);
+  gdb_printf ("%*.*s ", name_padding, name_padding, "                 ");
+  gdb_printf ("%s\t", signal_stop[oursig] ? "Yes" : "No");
+  gdb_printf ("%s\t", signal_print[oursig] ? "Yes" : "No");
+  gdb_printf ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
+  gdb_printf ("%s\n", gdb_signal_to_string (oursig));
 }
 
 /* Specify how various signals in the inferior should be handled.  */
@@ -8837,7 +9037,7 @@ Are you sure you want to change it? "),
                      sigs[signum] = 1;
                    }
                  else
-                   printf_unfiltered (_("Not confirmed, unchanged.\n"));
+                   gdb_printf (_("Not confirmed, unchanged.\n"));
                }
              break;
            case GDB_SIGNAL_0:
@@ -8932,7 +9132,7 @@ info_signals_command (const char *signum_exp, int from_tty)
       return;
     }
 
-  printf_filtered ("\n");
+  gdb_printf ("\n");
   /* These ugly casts brought to you by the native VAX compiler.  */
   for (oursig = GDB_SIGNAL_FIRST;
        (int) oursig < (int) GDB_SIGNAL_LAST;
@@ -8945,8 +9145,8 @@ info_signals_command (const char *signum_exp, int from_tty)
        sig_print_info (oursig);
     }
 
-  printf_filtered (_("\nUse the \"handle\" command "
-                    "to change these tables.\n"));
+  gdb_printf (_("\nUse the \"handle\" command "
+               "to change these tables.\n"));
 }
 
 /* The $_siginfo convenience variable is a bit special.  We don't know
@@ -8975,7 +9175,7 @@ siginfo_value_read (struct value *v)
     target_read (current_inferior ()->top_target (),
                 TARGET_OBJECT_SIGNAL_INFO,
                 NULL,
-                value_contents_all_raw (v),
+                value_contents_all_raw (v).data (),
                 value_offset (v),
                 TYPE_LENGTH (value_type (v)));
 
@@ -8998,7 +9198,7 @@ siginfo_value_write (struct value *v, struct value *fromval)
   transferred = target_write (current_inferior ()->top_target (),
                              TARGET_OBJECT_SIGNAL_INFO,
                              NULL,
-                             value_contents_all_raw (fromval),
+                             value_contents_all_raw (fromval).data (),
                              value_offset (v),
                              TYPE_LENGTH (value_type (fromval)));
 
@@ -9319,10 +9519,10 @@ show_exec_direction_func (struct ui_file *out, int from_tty,
 {
   switch (execution_direction) {
   case EXEC_FORWARD:
-    fprintf_filtered (out, _("Forward.\n"));
+    gdb_printf (out, _("Forward.\n"));
     break;
   case EXEC_REVERSE:
-    fprintf_filtered (out, _("Reverse.\n"));
+    gdb_printf (out, _("Reverse.\n"));
     break;
   default:
     internal_error (__FILE__, __LINE__,
@@ -9335,8 +9535,8 @@ static void
 show_schedule_multiple (struct ui_file *file, int from_tty,
                        struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Resuming the execution of threads "
-                           "of all processes is %s.\n"), value);
+  gdb_printf (file, _("Resuming the execution of threads "
+                     "of all processes is %s.\n"), value);
 }
 
 /* Implementation of `siginfo' variable.  */
@@ -9345,7 +9545,6 @@ static const struct internalvar_funcs siginfo_funcs =
 {
   siginfo_make_value,
   NULL,
-  NULL
 };
 
 /* Callback for infrun's target events source.  This is marked when a
@@ -9476,9 +9675,8 @@ may be interspersed with actions, with the actions being performed for\n\
 all signals cumulatively specified."));
   set_cmd_completer (c, handle_completer);
 
-  if (!dbx_commands)
-    stop_command = add_cmd ("stop", class_obscure,
-                           not_just_help_class_command, _("\
+  stop_command = add_cmd ("stop", class_obscure,
+                         not_just_help_class_command, _("\
 There is no `stop' command, but you can set a hook on `stop'.\n\
 This allows you to set a list of commands to be run each time execution\n\
 of the program stops."), &cmdlist);