Merge remote-tracking branch 'origin/master' into amd-common
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 33e5d434b3582cdf189887fb985331ab64f0b6a4..8209b08d0834acb1ecc169ff824188d8e2ba62db 100644 (file)
@@ -1,7 +1,8 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
+   Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #include "frame.h"
 #include "inferior.h"
 #include "breakpoint.h"
 #include "frame.h"
 #include "inferior.h"
 #include "breakpoint.h"
-#include "common/gdb_wait.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
-#include "cli/cli-script.h"
 #include "target.h"
 #include "target.h"
+#include "target-connection.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
 #include "top.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
 #include "top.h"
-#include <signal.h>
 #include "inf-loop.h"
 #include "regcache.h"
 #include "value.h"
 #include "inf-loop.h"
 #include "regcache.h"
 #include "value.h"
@@ -42,7 +41,6 @@
 #include "language.h"
 #include "solib.h"
 #include "main.h"
 #include "language.h"
 #include "solib.h"
 #include "main.h"
-#include "dictionary.h"
 #include "block.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
 #include "block.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
@@ -51,8 +49,6 @@
 #include "inline-frame.h"
 #include "jit.h"
 #include "tracepoint.h"
 #include "inline-frame.h"
 #include "jit.h"
 #include "tracepoint.h"
-#include "continuations.h"
-#include "interps.h"
 #include "skip.h"
 #include "probe.h"
 #include "objfiles.h"
 #include "skip.h"
 #include "probe.h"
 #include "objfiles.h"
 #include "solist.h"
 #include "event-loop.h"
 #include "thread-fsm.h"
 #include "solist.h"
 #include "event-loop.h"
 #include "thread-fsm.h"
-#include "common/enum-flags.h"
+#include "gdbsupport/enum-flags.h"
 #include "progspace-and-thread.h"
 #include "progspace-and-thread.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/gdb_optional.h"
 #include "arch-utils.h"
 #include "arch-utils.h"
-#include "common/scope-exit.h"
-#include "common/forward-scope-exit.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbsupport/forward-scope-exit.h"
+#include "gdb_select.h"
+#include <unordered_map>
 
 /* Prototypes for local functions */
 
 
 /* Prototypes for local functions */
 
@@ -84,8 +82,6 @@ static void follow_inferior_reset_breakpoints (void);
 
 static int currently_stepping (struct thread_info *tp);
 
 
 static int currently_stepping (struct thread_info *tp);
 
-void nullify_last_target_wait_ptid (void);
-
 static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
 
 static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
 static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
 
 static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
@@ -96,6 +92,8 @@ static int maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc);
 
 static void resume (gdb_signal sig);
 
 
 static void resume (gdb_signal sig);
 
+static void wait_for_inferior (inferior *inf);
+
 /* 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;
 /* 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;
@@ -136,7 +134,7 @@ mark_infrun_async_event_handler (void)
 /* When set, stop the 'step' command if we enter a function which has
    no line number information.  The normal behavior is that we step
    over such function.  */
 /* When set, stop the 'step' command if we enter a function which has
    no line number information.  The normal behavior is that we step
    over such function.  */
-int step_stop_if_no_debug = 0;
+bool step_stop_if_no_debug = false;
 static void
 show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 static void
 show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
@@ -155,9 +153,9 @@ static ptid_t previous_inferior_ptid;
    Exactly which branch is detached depends on 'set follow-fork-mode'
    setting.  */
 
    Exactly which branch is detached depends on 'set follow-fork-mode'
    setting.  */
 
-static int detach_fork = 1;
+static bool detach_fork = true;
 
 
-int debug_displaced = 0;
+bool debug_displaced = false;
 static void
 show_debug_displaced (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 static void
 show_debug_displaced (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
@@ -176,7 +174,7 @@ show_debug_infrun (struct ui_file *file, int from_tty,
 
 /* Support for disabling address space randomization.  */
 
 
 /* Support for disabling address space randomization.  */
 
-int disable_randomization = 1;
+bool disable_randomization = true;
 
 static void
 show_disable_randomization (struct ui_file *file, int from_tty,
 
 static void
 show_disable_randomization (struct ui_file *file, int from_tty,
@@ -205,8 +203,8 @@ set_disable_randomization (const char *args, int from_tty,
 
 /* User interface for non-stop mode.  */
 
 
 /* User interface for non-stop mode.  */
 
-int non_stop = 0;
-static int non_stop_1 = 0;
+bool non_stop = false;
+static bool non_stop_1 = false;
 
 static void
 set_non_stop (const char *args, int from_tty,
 
 static void
 set_non_stop (const char *args, int from_tty,
@@ -234,8 +232,8 @@ show_non_stop (struct ui_file *file, int from_tty,
    non-stop, in which all GDB operations that might affect the
    target's execution have been disabled.  */
 
    non-stop, in which all GDB operations that might affect the
    target's execution have been disabled.  */
 
-int observer_mode = 0;
-static int observer_mode_1 = 0;
+bool observer_mode = false;
+static bool observer_mode_1 = false;
 
 static void
 set_observer_mode (const char *args, int from_tty,
 
 static void
 set_observer_mode (const char *args, int from_tty,
@@ -256,7 +254,7 @@ set_observer_mode (const char *args, int from_tty,
   /* We can insert fast tracepoints in or out of observer mode,
      but enable them if we're going into this mode.  */
   if (observer_mode)
   /* We can insert fast tracepoints in or out of observer mode,
      but enable them if we're going into this mode.  */
   if (observer_mode)
-    may_insert_fast_tracepoints = 1;
+    may_insert_fast_tracepoints = true;
   may_stop = !observer_mode;
   update_target_permissions ();
 
   may_stop = !observer_mode;
   update_target_permissions ();
 
@@ -265,7 +263,7 @@ set_observer_mode (const char *args, int from_tty,
   if (observer_mode)
     {
       pagination_enabled = 0;
   if (observer_mode)
     {
       pagination_enabled = 0;
-      non_stop = non_stop_1 = 1;
+      non_stop = non_stop_1 = true;
     }
 
   if (from_tty)
     }
 
   if (from_tty)
@@ -289,13 +287,11 @@ show_observer_mode (struct ui_file *file, int from_tty,
 void
 update_observer_mode (void)
 {
 void
 update_observer_mode (void)
 {
-  int newval;
-
-  newval = (!may_insert_breakpoints
-           && !may_insert_tracepoints
-           && may_insert_fast_tracepoints
-           && !may_stop
-           && non_stop);
+  bool newval = (!may_insert_breakpoints
+                && !may_insert_tracepoints
+                && may_insert_fast_tracepoints
+                && !may_stop
+                && non_stop);
 
   /* Let the user know if things change.  */
   if (newval != observer_mode)
 
   /* Let the user know if things change.  */
   if (newval != observer_mode)
@@ -380,9 +376,10 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty,
 
 static int stop_print_frame;
 
 
 static int stop_print_frame;
 
-/* This is a cached copy of the pid/waitstatus of the last event
-   returned by target_wait()/deprecated_target_wait_hook().  This
-   information is returned by get_last_target_status().  */
+/* This is a cached copy of the target/ptid/waitstatus of the last
+   event returned by target_wait()/deprecated_target_wait_hook().
+   This information is returned by get_last_target_status().  */
+static process_stratum_target *target_last_proc_target;
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
@@ -440,7 +437,6 @@ follow_fork_inferior (int follow_child, int detach_fork)
 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"));
 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"));
-      /* FIXME output string > 80 columns.  */
       return 1;
     }
 
       return 1;
     }
 
@@ -471,7 +467,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              fprintf_filtered (gdb_stdlog,
                                _("[Detaching after %s from child %s]\n"),
                                has_vforked ? "vfork" : "fork",
              fprintf_filtered (gdb_stdlog,
                                _("[Detaching after %s from child %s]\n"),
                                has_vforked ? "vfork" : "fork",
-                               target_pid_to_str (process_ptid));
+                               target_pid_to_str (process_ptid).c_str ());
            }
        }
       else
            }
        }
       else
@@ -489,10 +485,12 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
          scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
 
          scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
-         inferior_ptid = child_ptid;
-         add_thread_silent (inferior_ptid);
          set_current_inferior (child_inf);
          set_current_inferior (child_inf);
+         switch_to_no_thread ();
          child_inf->symfile_flags = SYMFILE_NO_READ;
          child_inf->symfile_flags = SYMFILE_NO_READ;
+         push_target (parent_inf->process_target ());
+         add_thread_silent (child_inf->process_target (), child_ptid);
+         inferior_ptid = child_ptid;
 
          /* If this is a vfork child, then the address-space is
             shared with the parent.  */
 
          /* If this is a vfork child, then the address-space is
             shared with the parent.  */
@@ -501,6 +499,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
              child_inf->pspace = parent_inf->pspace;
              child_inf->aspace = parent_inf->aspace;
 
              child_inf->pspace = parent_inf->pspace;
              child_inf->aspace = parent_inf->aspace;
 
+             exec_on_vfork ();
+
              /* The parent will be frozen until the child is done
                 with the shared region.  Keep track of the
                 parent.  */
              /* The parent will be frozen until the child is done
                 with the shared region.  Keep track of the
                 parent.  */
@@ -576,52 +576,64 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
       parent_pspace = parent_inf->pspace;
 
 
       parent_pspace = parent_inf->pspace;
 
-      /* If we're vforking, we want to hold on to the parent until the
-        child exits or execs.  At child exec or exit time we can
-        remove the old breakpoints from the parent and detach or
-        resume debugging it.  Otherwise, detach the parent now; we'll
-        want to reuse it's program/address spaces, but we can't set
-        them to the child before removing breakpoints from the
-        parent, otherwise, the breakpoints module could decide to
-        remove breakpoints from the wrong process (since they'd be
-        assigned to the same address space).  */
+      process_stratum_target *target = parent_inf->process_target ();
 
 
-      if (has_vforked)
-       {
-         gdb_assert (child_inf->vfork_parent == NULL);
-         gdb_assert (parent_inf->vfork_child == NULL);
-         child_inf->vfork_parent = parent_inf;
-         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)
-       {
-         if (print_inferior_events)
-           {
-             /* Ensure that we have a process ptid.  */
-             ptid_t process_ptid = ptid_t (parent_ptid.pid ());
+      {
+       /* Hold a strong reference to the target while (maybe)
+          detaching the parent.  Otherwise detaching could close the
+          target.  */
+       auto target_ref = target_ops_ref::new_reference (target);
+
+       /* If we're vforking, we want to hold on to the parent until
+          the child exits or execs.  At child exec or exit time we
+          can remove the old breakpoints from the parent and detach
+          or resume debugging it.  Otherwise, detach the parent now;
+          we'll want to reuse it's program/address spaces, but we
+          can't set them to the child before removing breakpoints
+          from the parent, otherwise, the breakpoints module could
+          decide to remove breakpoints from the wrong process (since
+          they'd be assigned to the same address space).  */
+
+       if (has_vforked)
+         {
+           gdb_assert (child_inf->vfork_parent == NULL);
+           gdb_assert (parent_inf->vfork_child == NULL);
+           child_inf->vfork_parent = parent_inf;
+           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)
+         {
+           if (print_inferior_events)
+             {
+               /* Ensure that we have a process ptid.  */
+               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 ());
+             }
 
 
-             target_terminal::ours_for_output ();
-             fprintf_filtered (gdb_stdlog,
-                               _("[Detaching after fork from "
-                                 "parent %s]\n"),
-                               target_pid_to_str (process_ptid));
-           }
+           target_detach (parent_inf, 0);
+           parent_inf = NULL;
+         }
 
 
-         target_detach (parent_inf, 0);
-       }
+       /* Note that the detach above makes PARENT_INF dangling.  */
 
 
-      /* Note that the detach above makes PARENT_INF dangling.  */
+       /* Add the child thread to the appropriate lists, and switch
+          to this new thread, before cloning the program space, and
+          informing the solib layer about this new process.  */
 
 
-      /* Add the child thread to the appropriate lists, and switch to
-        this new thread, before cloning the program space, and
-        informing the solib layer about this new process.  */
+       set_current_inferior (child_inf);
+       push_target (target);
+      }
 
 
+      add_thread_silent (target, child_ptid);
       inferior_ptid = child_ptid;
       inferior_ptid = child_ptid;
-      add_thread_silent (inferior_ptid);
-      set_current_inferior (child_inf);
 
       /* If this is a vfork child, then the address-space is shared
         with the parent.  If we detached from the parent, then we can
 
       /* If this is a vfork child, then the address-space is shared
         with the parent.  If we detached from the parent, then we can
@@ -630,6 +642,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
        {
          child_inf->pspace = parent_pspace;
          child_inf->aspace = child_inf->pspace->aspace;
        {
          child_inf->pspace = parent_pspace;
          child_inf->aspace = child_inf->pspace->aspace;
+
+         exec_on_vfork ();
        }
       else
        {
        }
       else
        {
@@ -676,11 +690,12 @@ follow_fork (void)
 
   if (!non_stop)
     {
 
   if (!non_stop)
     {
+      process_stratum_target *wait_target;
       ptid_t wait_ptid;
       struct target_waitstatus wait_status;
 
       /* Get the last target status returned by target_wait().  */
       ptid_t wait_ptid;
       struct target_waitstatus wait_status;
 
       /* Get the last target status returned by target_wait().  */
-      get_last_target_status (&wait_ptid, &wait_status);
+      get_last_target_status (&wait_target, &wait_ptid, &wait_status);
 
       /* If not stopped at a fork event, then there's nothing else to
         do.  */
 
       /* If not stopped at a fork event, then there's nothing else to
         do.  */
@@ -691,14 +706,14 @@ follow_fork (void)
       /* Check if we switched over from WAIT_PTID, since the event was
         reported.  */
       if (wait_ptid != minus_one_ptid
       /* Check if we switched over from WAIT_PTID, since the event was
         reported.  */
       if (wait_ptid != minus_one_ptid
-         && inferior_ptid != wait_ptid)
+         && (current_inferior ()->process_target () != wait_target
+             || inferior_ptid != wait_ptid))
        {
          /* We did.  Switch back to WAIT_PTID thread, to tell the
             target to follow it (in either direction).  We'll
             afterwards refuse to resume, and inform the user what
             happened.  */
        {
          /* We did.  Switch back to WAIT_PTID thread, to tell the
             target to follow it (in either direction).  We'll
             afterwards refuse to resume, and inform the user what
             happened.  */
-         thread_info *wait_thread
-           = find_thread_ptid (wait_ptid);
+         thread_info *wait_thread = find_thread_ptid (wait_target, wait_ptid);
          switch_to_thread (wait_thread);
          should_resume = 0;
        }
          switch_to_thread (wait_thread);
          should_resume = 0;
        }
@@ -744,6 +759,7 @@ follow_fork (void)
        parent = inferior_ptid;
        child = tp->pending_follow.value.related_pid;
 
        parent = inferior_ptid;
        child = tp->pending_follow.value.related_pid;
 
+       process_stratum_target *parent_targ = tp->inf->process_target ();
        /* Set up inferior(s) as specified by the caller, and tell the
           target to do whatever is necessary to follow either parent
           or child.  */
        /* Set up inferior(s) as specified by the caller, and tell the
           target to do whatever is necessary to follow either parent
           or child.  */
@@ -759,7 +775,7 @@ follow_fork (void)
               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.  */
               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);
+           tp = find_thread_ptid (parent_targ, parent);
            if (tp)
              tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
 
            if (tp)
              tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
 
@@ -770,7 +786,7 @@ follow_fork (void)
            /* If we followed the child, switch to it...  */
            if (follow_child)
              {
            /* If we followed the child, switch to it...  */
            if (follow_child)
              {
-               thread_info *child_thr = find_thread_ptid (child);
+               thread_info *child_thr = find_thread_ptid (parent_targ, child);
                switch_to_thread (child_thr);
 
                /* ... and preserve the stepping state, in case the
                switch_to_thread (child_thr);
 
                /* ... and preserve the stepping state, in case the
@@ -876,7 +892,7 @@ proceed_after_vfork_done (struct thread_info *thread,
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming vfork parent thread %s\n",
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming vfork parent thread %s\n",
-                           target_pid_to_str (thread->ptid));
+                           target_pid_to_str (thread->ptid).c_str ());
 
       switch_to_thread (thread);
       clear_proceed_status (0);
 
       switch_to_thread (thread);
       clear_proceed_status (0);
@@ -915,10 +931,14 @@ handle_vfork_child_exec_or_exit (int exec)
       int resume_parent = -1;
 
       /* This exec or exit marks the end of the shared memory region
       int resume_parent = -1;
 
       /* This exec or exit marks the end of the shared memory region
-        between the parent and the child.  If the user wanted to
-        detach from the parent, now is the time.  */
+        between the parent and the child.  Break the bonds.  */
+      inferior *vfork_parent = inf->vfork_parent;
+      inf->vfork_parent->vfork_child = NULL;
+      inf->vfork_parent = NULL;
 
 
-      if (inf->vfork_parent->pending_detach)
+      /* If the user wanted to detach from the parent, now is the
+        time.  */
+      if (vfork_parent->pending_detach)
        {
          struct thread_info *tp;
          struct program_space *pspace;
        {
          struct thread_info *tp;
          struct program_space *pspace;
@@ -926,7 +946,7 @@ handle_vfork_child_exec_or_exit (int exec)
 
          /* follow-fork child, detach-on-fork on.  */
 
 
          /* follow-fork child, detach-on-fork on.  */
 
-         inf->vfork_parent->pending_detach = 0;
+         vfork_parent->pending_detach = 0;
 
          gdb::optional<scoped_restore_exited_inferior>
            maybe_restore_inferior;
 
          gdb::optional<scoped_restore_exited_inferior>
            maybe_restore_inferior;
@@ -941,7 +961,7 @@ handle_vfork_child_exec_or_exit (int exec)
            maybe_restore_thread.emplace ();
 
          /* We're letting loose of the parent.  */
            maybe_restore_thread.emplace ();
 
          /* We're letting loose of the parent.  */
-         tp = any_live_thread_of_inferior (inf->vfork_parent);
+         tp = any_live_thread_of_inferior (vfork_parent);
          switch_to_thread (tp);
 
          /* We're about to detach from the parent, which implicitly
          switch_to_thread (tp);
 
          /* We're about to detach from the parent, which implicitly
@@ -963,8 +983,8 @@ handle_vfork_child_exec_or_exit (int exec)
 
          if (print_inferior_events)
            {
 
          if (print_inferior_events)
            {
-             const char *pidstr
-               = target_pid_to_str (ptid_t (inf->vfork_parent->pid));
+             std::string pidstr
+               = target_pid_to_str (ptid_t (vfork_parent->pid));
 
              target_terminal::ours_for_output ();
 
 
              target_terminal::ours_for_output ();
 
@@ -972,17 +992,17 @@ handle_vfork_child_exec_or_exit (int exec)
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
-                                     "after child exec]\n"), pidstr);
+                                     "after child exec]\n"), pidstr.c_str ());
                }
              else
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
                }
              else
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
-                                     "after child exit]\n"), pidstr);
+                                     "after child exit]\n"), pidstr.c_str ());
                }
            }
 
                }
            }
 
-         target_detach (inf->vfork_parent, 0);
+         target_detach (vfork_parent, 0);
 
          /* Put it back.  */
          inf->pspace = pspace;
 
          /* Put it back.  */
          inf->pspace = pspace;
@@ -997,10 +1017,7 @@ handle_vfork_child_exec_or_exit (int exec)
          inf->removable = 1;
          set_current_program_space (inf->pspace);
 
          inf->removable = 1;
          set_current_program_space (inf->pspace);
 
-         resume_parent = inf->vfork_parent->pid;
-
-         /* Break the bonds.  */
-         inf->vfork_parent->vfork_child = NULL;
+         resume_parent = vfork_parent->pid;
        }
       else
        {
        }
       else
        {
@@ -1030,17 +1047,13 @@ handle_vfork_child_exec_or_exit (int exec)
          set_current_program_space (pspace);
          inf->removable = 1;
          inf->symfile_flags = SYMFILE_NO_READ;
          set_current_program_space (pspace);
          inf->removable = 1;
          inf->symfile_flags = SYMFILE_NO_READ;
-         clone_program_space (pspace, inf->vfork_parent->pspace);
+         clone_program_space (pspace, vfork_parent->pspace);
          inf->pspace = pspace;
          inf->aspace = pspace->aspace;
 
          inf->pspace = pspace;
          inf->aspace = pspace->aspace;
 
-         resume_parent = inf->vfork_parent->pid;
-         /* Break the bonds.  */
-         inf->vfork_parent->vfork_child = NULL;
+         resume_parent = vfork_parent->pid;
        }
 
        }
 
-      inf->vfork_parent = NULL;
-
       gdb_assert (current_program_space == inf->pspace);
 
       if (non_stop && resume_parent != -1)
       gdb_assert (current_program_space == inf->pspace);
 
       if (non_stop && resume_parent != -1)
@@ -1081,12 +1094,16 @@ show_follow_exec_mode_string (struct ui_file *file, int from_tty,
 /* EXEC_FILE_TARGET is assumed to be non-NULL.  */
 
 static void
 /* EXEC_FILE_TARGET is assumed to be non-NULL.  */
 
 static void
-follow_exec (ptid_t ptid, char *exec_file_target)
+follow_exec (ptid_t ptid, const char *exec_file_target)
 {
   struct inferior *inf = current_inferior ();
   int pid = ptid.pid ();
   ptid_t process_ptid;
 
 {
   struct inferior *inf = current_inferior ();
   int pid = ptid.pid ();
   ptid_t process_ptid;
 
+  /* Switch terminal for any messages produced e.g. by
+     breakpoint_re_set.  */
+  target_terminal::ours_for_output ();
+
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
      momentary bp's, etc.
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
      momentary bp's, etc.
@@ -1105,7 +1122,7 @@ follow_exec (ptid_t ptid, char *exec_file_target)
 
      And, we DON'T want to call delete_breakpoints() here, since
      that may write the bp's "shadow contents" (the instruction
 
      And, we DON'T want to call delete_breakpoints() here, since
      that may write the bp's "shadow contents" (the instruction
-     value that was overwritten witha TRAP instruction).  Since
+     value that was overwritten with a TRAP instruction).  Since
      we now have a new a.out, those shadow contents aren't valid.  */
 
   mark_breakpoints_out ();
      we now have a new a.out, those shadow contents aren't valid.  */
 
   mark_breakpoints_out ();
@@ -1154,7 +1171,7 @@ follow_exec (ptid_t ptid, 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"),
   /* 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),
+                    target_pid_to_str (process_ptid).c_str (),
                     exec_file_target);
 
   /* We've followed the inferior through an exec.  Therefore, the
                     exec_file_target);
 
   /* We've followed the inferior through an exec.  Therefore, the
@@ -1198,9 +1215,11 @@ follow_exec (ptid_t ptid, char *exec_file_target)
       inf->pid = pid;
       target_follow_exec (inf, exec_file_target);
 
       inf->pid = pid;
       target_follow_exec (inf, exec_file_target);
 
-      set_current_inferior (inf);
-      set_current_program_space (inf->pspace);
-      add_thread (ptid);
+      inferior *org_inferior = current_inferior ();
+      switch_to_inferior_no_thread (inf);
+      push_target (org_inferior->process_target ());
+      thread_info *thr = add_thread (inf->process_target (), ptid);
+      switch_to_thread (thr);
     }
   else
     {
     }
   else
     {
@@ -1430,7 +1449,7 @@ step_over_info_valid_p (void)
      register contents, and memory.  We use this in step n1.
 
    - gdbarch_displaced_step_fixup adjusts registers and memory after
      register contents, and memory.  We use this in step n1.
 
    - gdbarch_displaced_step_fixup adjusts registers and memory after
-     we have successfuly single-stepped the instruction, to yield the
+     we have successfully single-stepped the instruction, to yield the
      same effect the instruction would have had if we had executed it
      at its original address.  We use this in step n3.
 
      same effect the instruction would have had if we had executed it
      at its original address.  We use this in step n3.
 
@@ -1668,7 +1687,7 @@ displaced_step_prepare_throw (thread_info *tp)
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: deferring step of %s\n",
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: deferring step of %s\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       thread_step_over_chain_enqueue (tp);
       return 0;
 
       thread_step_over_chain_enqueue (tp);
       return 0;
@@ -1678,7 +1697,7 @@ displaced_step_prepare_throw (thread_info *tp)
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: stepping %s now\n",
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: stepping %s now\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
     }
 
   displaced_step_clear (displaced);
     }
 
   displaced_step_clear (displaced);
@@ -1772,23 +1791,23 @@ displaced_step_prepare (thread_info *thread)
 {
   int prepared = -1;
 
 {
   int prepared = -1;
 
-  TRY
+  try
     {
       prepared = displaced_step_prepare_throw (thread);
     }
     {
       prepared = displaced_step_prepare_throw (thread);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       struct displaced_step_inferior_state *displaced_state;
 
       if (ex.error != MEMORY_ERROR
          && ex.error != NOT_SUPPORTED_ERROR)
     {
       struct displaced_step_inferior_state *displaced_state;
 
       if (ex.error != MEMORY_ERROR
          && ex.error != NOT_SUPPORTED_ERROR)
-       throw_exception (ex);
+       throw;
 
       if (debug_infrun)
        {
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: disabling displaced stepping: %s\n",
 
       if (debug_infrun)
        {
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: disabling displaced stepping: %s\n",
-                             ex.message);
+                             ex.what ());
        }
 
       /* Be verbose if "set displaced-stepping" is "on", silent if
        }
 
       /* Be verbose if "set displaced-stepping" is "on", silent if
@@ -1796,7 +1815,7 @@ displaced_step_prepare (thread_info *thread)
       if (can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
        {
          warning (_("disabling displaced stepping: %s"),
       if (can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
        {
          warning (_("disabling displaced stepping: %s"),
-                  ex.message);
+                  ex.what ());
        }
 
       /* Disable further displaced stepping attempts.  */
        }
 
       /* Disable further displaced stepping attempts.  */
@@ -1804,7 +1823,6 @@ displaced_step_prepare (thread_info *thread)
        = get_displaced_stepping_state (thread->inf);
       displaced_state->failed_before = 1;
     }
        = get_displaced_stepping_state (thread->inf);
       displaced_state->failed_before = 1;
     }
-  END_CATCH
 
   return prepared;
 }
 
   return prepared;
 }
@@ -1831,7 +1849,7 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
                     displaced->step_saved_copy.data (), len);
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: restored %s %s\n",
                     displaced->step_saved_copy.data (), len);
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: restored %s %s\n",
-                       target_pid_to_str (ptid),
+                       target_pid_to_str (ptid).c_str (),
                        paddress (displaced->step_gdbarch,
                                  displaced->step_copy));
 }
                        paddress (displaced->step_gdbarch,
                                  displaced->step_copy));
 }
@@ -1895,6 +1913,7 @@ displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
    discarded between events.  */
 struct execution_control_state
 {
    discarded between events.  */
 struct execution_control_state
 {
+  process_stratum_target *target;
   ptid_t ptid;
   /* The thread that got the event, if this was a thread event; NULL
      otherwise.  */
   ptid_t ptid;
   /* The thread that got the event, if this was a thread event; NULL
      otherwise.  */
@@ -1985,7 +2004,7 @@ start_step_over (void)
          internal_error (__FILE__, __LINE__,
                          "[%s] has inconsistent state: "
                          "trap_expected=%d, resumed=%d, executing=%d\n",
          internal_error (__FILE__, __LINE__,
                          "[%s] has inconsistent state: "
                          "trap_expected=%d, resumed=%d, executing=%d\n",
-                         target_pid_to_str (tp->ptid),
+                         target_pid_to_str (tp->ptid).c_str (),
                          tp->control.trap_expected,
                          tp->resumed,
                          tp->executing);
                          tp->control.trap_expected,
                          tp->resumed,
                          tp->executing);
@@ -1994,7 +2013,7 @@ start_step_over (void)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming [%s] for step-over\n",
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming [%s] for step-over\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).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
 
       /* keep_going_pass_signal skips the step-over if the breakpoint
         is no longer inserted.  In all-stop, we want to keep looking
@@ -2089,7 +2108,7 @@ set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c)
 /* True if execution commands resume all threads of all processes by
    default; otherwise, resume only threads of the current inferior
    process.  */
 /* True if execution commands resume all threads of all processes by
    default; otherwise, resume only threads of the current inferior
    process.  */
-int sched_multi = 0;
+bool sched_multi = false;
 
 /* Try to setup for software single stepping over the specified location.
    Return 1 if target_resume() should use hardware single step.
 
 /* Try to setup for software single stepping over the specified location.
    Return 1 if target_resume() should use hardware single step.
@@ -2151,6 +2170,16 @@ user_visible_resume_ptid (int step)
   return resume_ptid;
 }
 
   return resume_ptid;
 }
 
+/* See infrun.h.  */
+
+process_stratum_target *
+user_visible_resume_target (ptid_t resume_ptid)
+{
+  return (resume_ptid == minus_one_ptid && sched_multi
+         ? NULL
+         : current_inferior ()->process_target ());
+}
+
 /* Return a ptid representing the set of threads that we will resume,
    in the perspective of the target, assuming run control handling
    does not require leaving some threads stopped (e.g., stepping past
 /* Return a ptid representing the set of threads that we will resume,
    in the perspective of the target, assuming run control handling
    does not require leaving some threads stopped (e.g., stepping past
@@ -2215,6 +2244,9 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
   target_resume (resume_ptid, step, sig);
 
   target_commit_resume ();
   target_resume (resume_ptid, step, sig);
 
   target_commit_resume ();
+
+  if (target_can_async_p ())
+    target_async (1);
 }
 
 /* Resume the inferior.  SIG is the signal to give the inferior
 }
 
 /* Resume the inferior.  SIG is the signal to give the inferior
@@ -2253,10 +2285,12 @@ resume_1 (enum gdb_signal sig)
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: resume: thread %s has pending wait "
                              "status %s (currently_stepping=%d).\n",
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: resume: thread %s has pending wait "
                              "status %s (currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid), statstr.c_str (),
+                             target_pid_to_str (tp->ptid).c_str (),
+                             statstr.c_str (),
                              currently_stepping (tp));
        }
 
                              currently_stepping (tp));
        }
 
+      tp->inf->process_target ()->threads_executing = true;
       tp->resumed = 1;
 
       /* FIXME: What should we do if we are supposed to resume this
       tp->resumed = 1;
 
       /* FIXME: What should we do if we are supposed to resume this
@@ -2265,7 +2299,8 @@ resume_1 (enum gdb_signal sig)
       if (sig != GDB_SIGNAL_0)
        {
          warning (_("Couldn't deliver signal %s to %s."),
       if (sig != GDB_SIGNAL_0)
        {
          warning (_("Couldn't deliver signal %s to %s."),
-                  gdb_signal_to_name (sig), target_pid_to_str (tp->ptid));
+                  gdb_signal_to_name (sig),
+                  target_pid_to_str (tp->ptid).c_str ());
        }
 
       tp->suspend.stop_signal = GDB_SIGNAL_0;
        }
 
       tp->suspend.stop_signal = GDB_SIGNAL_0;
@@ -2309,7 +2344,7 @@ resume_1 (enum gdb_signal sig)
                        "trap_expected=%d, current thread [%s] at %s\n",
                        step, gdb_signal_to_symbol_string (sig),
                        tp->control.trap_expected,
                        "trap_expected=%d, current thread [%s] at %s\n",
                        step, gdb_signal_to_symbol_string (sig),
                        tp->control.trap_expected,
-                       target_pid_to_str (inferior_ptid),
+                       target_pid_to_str (inferior_ptid).c_str (),
                        paddress (gdbarch, pc));
 
   /* Normally, by the time we reach `resume', the breakpoints are either
                        paddress (gdbarch, pc));
 
   /* Normally, by the time we reach `resume', the breakpoints are either
@@ -2558,7 +2593,7 @@ resume_1 (enum gdb_signal sig)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resume: [%s] stepped breakpoint\n",
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resume: [%s] stepped breakpoint\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       tp->stepped_breakpoint = 1;
 
 
       tp->stepped_breakpoint = 1;
 
@@ -2606,11 +2641,11 @@ resume_1 (enum gdb_signal sig)
 static void
 resume (gdb_signal sig)
 {
 static void
 resume (gdb_signal sig)
 {
-  TRY
+  try
     {
       resume_1 (sig);
     }
     {
       resume_1 (sig);
     }
-  CATCH (ex, RETURN_MASK_ALL)
+  catch (const gdb_exception &ex)
     {
       /* If resuming is being aborted for any reason, delete any
         single-step breakpoint resume_1 may have created, to avoid
     {
       /* If resuming is being aborted for any reason, delete any
         single-step breakpoint resume_1 may have created, to avoid
@@ -2619,9 +2654,8 @@ resume (gdb_signal sig)
         we're running in non-stop mode.  */
       if (inferior_ptid != null_ptid)
        delete_single_step_breakpoints (inferior_thread ());
         we're running in non-stop mode.  */
       if (inferior_ptid != null_ptid)
        delete_single_step_breakpoints (inferior_thread ());
-      throw_exception (ex);
+      throw;
     }
     }
-  END_CATCH
 }
 
 \f
 }
 
 \f
@@ -2663,7 +2697,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: clear_proceed_status_thread (%s)\n",
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: clear_proceed_status_thread (%s)\n",
-                       target_pid_to_str (tp->ptid));
+                       target_pid_to_str (tp->ptid).c_str ());
 
   /* If we're starting a new sequence, then the previous finished
      single-step is no longer relevant.  */
 
   /* If we're starting a new sequence, then the previous finished
      single-step is no longer relevant.  */
@@ -2676,7 +2710,7 @@ clear_proceed_status_thread (struct thread_info *tp)
                                "infrun: clear_proceed_status: pending "
                                "event of %s was a finished step. "
                                "Discarding.\n",
                                "infrun: clear_proceed_status: pending "
                                "event of %s was a finished step. "
                                "Discarding.\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          tp->suspend.waitstatus_pending_p = 0;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
          tp->suspend.waitstatus_pending_p = 0;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
@@ -2690,7 +2724,8 @@ clear_proceed_status_thread (struct thread_info *tp)
                              "infrun: clear_proceed_status_thread: thread %s "
                              "has pending wait status %s "
                              "(currently_stepping=%d).\n",
                              "infrun: clear_proceed_status_thread: thread %s "
                              "has pending wait status %s "
                              "(currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid), statstr.c_str (),
+                             target_pid_to_str (tp->ptid).c_str (),
+                             statstr.c_str (),
                              currently_stepping (tp));
        }
     }
                              currently_stepping (tp));
        }
     }
@@ -2741,10 +2776,12 @@ clear_proceed_status (int step)
   if (!non_stop && inferior_ptid != null_ptid)
     {
       ptid_t resume_ptid = user_visible_resume_ptid (step);
   if (!non_stop && inferior_ptid != null_ptid)
     {
       ptid_t resume_ptid = user_visible_resume_ptid (step);
+      process_stratum_target *resume_target
+       = user_visible_resume_target (resume_ptid);
 
       /* In all-stop mode, delete the per-thread status of all threads
         we're about to resume, implicitly and explicitly.  */
 
       /* In all-stop mode, delete the per-thread status of all threads
         we're about to resume, implicitly and explicitly.  */
-      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+      for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid))
        clear_proceed_status_thread (tp);
     }
 
        clear_proceed_status_thread (tp);
     }
 
@@ -2821,6 +2858,86 @@ schedlock_applies (struct thread_info *tp)
                                            execution_direction)));
 }
 
                                            execution_direction)));
 }
 
+/* Calls target_commit_resume on all targets.  */
+
+static void
+commit_resume_all_targets ()
+{
+  scoped_restore_current_thread restore_thread;
+
+  /* Map between process_target and a representative inferior.  This
+     is to avoid committing a resume in the same target more than
+     once.  Resumptions must be idempotent, so this is an
+     optimization.  */
+  std::unordered_map<process_stratum_target *, inferior *> conn_inf;
+
+  for (inferior *inf : all_non_exited_inferiors ())
+    if (inf->has_execution ())
+      conn_inf[inf->process_target ()] = inf;
+
+  for (const auto &ci : conn_inf)
+    {
+      inferior *inf = ci.second;
+      switch_to_inferior_no_thread (inf);
+      target_commit_resume ();
+    }
+}
+
+/* Check that all the targets we're about to resume are in non-stop
+   mode.  Ideally, we'd only care whether all targets support
+   target-async, but we're not there yet.  E.g., stop_all_threads
+   doesn't know how to handle all-stop targets.  Also, the remote
+   protocol in all-stop mode is synchronous, irrespective of
+   target-async, which means that things like a breakpoint re-set
+   triggered by one target would try to read memory from all targets
+   and fail.  */
+
+static void
+check_multi_target_resumption (process_stratum_target *resume_target)
+{
+  if (!non_stop && resume_target == nullptr)
+    {
+      scoped_restore_current_thread restore_thread;
+
+      /* This is used to track whether we're resuming more than one
+        target.  */
+      process_stratum_target *first_connection = nullptr;
+
+      /* The first inferior we see with a target that does not work in
+        always-non-stop mode.  */
+      inferior *first_not_non_stop = nullptr;
+
+      for (inferior *inf : all_non_exited_inferiors (resume_target))
+       {
+         switch_to_inferior_no_thread (inf);
+
+         if (!target_has_execution)
+           continue;
+
+         process_stratum_target *proc_target
+           = current_inferior ()->process_target();
+
+         if (!target_is_non_stop_p ())
+           first_not_non_stop = inf;
+
+         if (first_connection == nullptr)
+           first_connection = proc_target;
+         else if (first_connection != proc_target
+                  && first_not_non_stop != nullptr)
+           {
+             switch_to_inferior_no_thread (first_not_non_stop);
+
+             proc_target = current_inferior ()->process_target();
+
+             error (_("Connection %d (%s) does not support "
+                      "multi-target resumption."),
+                    proc_target->connection_number,
+                    make_target_connection_string (proc_target).c_str ());
+           }
+       }
+    }
+}
+
 /* Basic routine for continuing the program in various fashions.
 
    ADDR is the address to resume at, or -1 for resume where stopped.
 /* Basic routine for continuing the program in various fashions.
 
    ADDR is the address to resume at, or -1 for resume where stopped.
@@ -2835,7 +2952,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   struct regcache *regcache;
   struct gdbarch *gdbarch;
   CORE_ADDR pc;
   struct regcache *regcache;
   struct gdbarch *gdbarch;
   CORE_ADDR pc;
-  ptid_t resume_ptid;
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
   int started;
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
   int started;
@@ -2867,6 +2983,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
   gdb_assert (!thread_is_in_step_over_chain (cur_thr));
 
 
   gdb_assert (!thread_is_in_step_over_chain (cur_thr));
 
+  ptid_t resume_ptid
+    = user_visible_resume_ptid (cur_thr->control.stepping_command);
+  process_stratum_target *resume_target
+    = user_visible_resume_target (resume_ptid);
+
+  check_multi_target_resumption (resume_target);
+
   if (addr == (CORE_ADDR) -1)
     {
       if (pc == cur_thr->suspend.stop_pc
   if (addr == (CORE_ADDR) -1)
     {
       if (pc == cur_thr->suspend.stop_pc
@@ -2896,12 +3019,10 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   if (siggnal != GDB_SIGNAL_DEFAULT)
     cur_thr->suspend.stop_signal = siggnal;
 
   if (siggnal != GDB_SIGNAL_DEFAULT)
     cur_thr->suspend.stop_signal = siggnal;
 
-  resume_ptid = user_visible_resume_ptid (cur_thr->control.stepping_command);
-
   /* If an exception is thrown from this point on, make sure to
      propagate GDB's knowledge of the executing state to the
      frontend/user running state.  */
   /* If an exception is thrown from this point on, make sure to
      propagate GDB's knowledge of the executing state to the
      frontend/user running state.  */
-  scoped_finish_thread_state finish_state (resume_ptid);
+  scoped_finish_thread_state finish_state (resume_target, resume_ptid);
 
   /* Even if RESUME_PTID is a wildcard, and we end up resuming fewer
      threads (e.g., we might need to set threads stepping over
 
   /* Even if RESUME_PTID is a wildcard, and we end up resuming fewer
      threads (e.g., we might need to set threads stepping over
@@ -2910,7 +3031,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
      inferior function, as in that case we pretend the inferior
      doesn't run at all.  */
   if (!cur_thr->control.in_infcall)
      inferior function, as in that case we pretend the inferior
      doesn't run at all.  */
   if (!cur_thr->control.in_infcall)
-   set_running (resume_ptid, 1);
+    set_running (resume_target, resume_ptid, 1);
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
@@ -2945,8 +3066,11 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
      threads.  */
   if (!non_stop && !schedlock_applies (cur_thr))
     {
      threads.  */
   if (!non_stop && !schedlock_applies (cur_thr))
     {
-      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+      for (thread_info *tp : all_non_exited_threads (resume_target,
+                                                    resume_ptid))
        {
        {
+         switch_to_thread_no_regs (tp);
+
          /* Ignore the current thread here.  It's handled
             afterwards.  */
          if (tp == cur_thr)
          /* Ignore the current thread here.  It's handled
             afterwards.  */
          if (tp == cur_thr)
@@ -2960,10 +3084,12 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: need to step-over [%s] first\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: need to step-over [%s] first\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          thread_step_over_chain_enqueue (tp);
        }
 
          thread_step_over_chain_enqueue (tp);
        }
+
+      switch_to_thread (cur_thr);
     }
 
   /* Enqueue the current thread last, so that we move all other
     }
 
   /* Enqueue the current thread last, so that we move all other
@@ -2998,14 +3124,27 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
       {
        /* In all-stop, but the target is always in non-stop mode.
           Start all other threads that are implicitly resumed too.  */
       {
        /* In all-stop, but the target is always in non-stop mode.
           Start all other threads that are implicitly resumed too.  */
-      for (thread_info *tp : all_non_exited_threads (resume_ptid))
-        {
+       for (thread_info *tp : all_non_exited_threads (resume_target,
+                                                      resume_ptid))
+         {
+           switch_to_thread_no_regs (tp);
+
+         if (!tp->inf->has_execution ())
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: proceed: [%s] target has "
+                                   "no execution\n",
+                                   target_pid_to_str (tp->ptid).c_str ());
+             continue;
+           }
+
          if (tp->resumed)
            {
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] resumed\n",
          if (tp->resumed)
            {
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] resumed\n",
-                                   target_pid_to_str (tp->ptid));
+                                   target_pid_to_str (tp->ptid).c_str ());
              gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
              continue;
            }
              gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
              continue;
            }
@@ -3015,14 +3154,14 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] needs step-over\n",
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] needs step-over\n",
-                                   target_pid_to_str (tp->ptid));
+                                   target_pid_to_str (tp->ptid).c_str ());
              continue;
            }
 
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: proceed: resuming %s\n",
              continue;
            }
 
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: proceed: resuming %s\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          reset_ecs (ecs, tp);
          switch_to_thread (tp);
 
          reset_ecs (ecs, tp);
          switch_to_thread (tp);
@@ -3042,10 +3181,15 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
       }
   }
 
       }
   }
 
-  target_commit_resume ();
+  commit_resume_all_targets ();
 
   finish_state.release ();
 
 
   finish_state.release ();
 
+  /* If we've switched threads above, switch back to the previously
+     current thread.  We don't want the user to see a different
+     selected thread.  */
+  switch_to_thread (cur_thr);
+
   /* Tell the event loop to wait for it to stop.  If the target
      supports asynchronous execution, it'll do this from within
      target_resume.  */
   /* Tell the event loop to wait for it to stop.  If the target
      supports asynchronous execution, it'll do this from within
      target_resume.  */
@@ -3059,10 +3203,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 void
 start_remote (int from_tty)
 {
 void
 start_remote (int from_tty)
 {
-  struct inferior *inferior;
-
-  inferior = current_inferior ();
-  inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
+  inferior *inf = current_inferior ();
+  inf->control.stop_soon = STOP_QUIETLY_REMOTE;
 
   /* Always go on waiting for the target, regardless of the mode.  */
   /* FIXME: cagney/1999-09-23: At present it isn't possible to
 
   /* Always go on waiting for the target, regardless of the mode.  */
   /* FIXME: cagney/1999-09-23: At present it isn't possible to
@@ -3078,7 +3220,7 @@ start_remote (int from_tty)
      target_open() return to the caller an indication that the target
      is currently running and GDB state should be set to the same as
      for an async run.  */
      target_open() return to the caller an indication that the target
      is currently running and GDB state should be set to the same as
      for an async run.  */
-  wait_for_inferior ();
+  wait_for_inferior (inf);
 
   /* Now that the inferior has stopped, do any bookkeeping like
      loading shared libraries.  We want to do this before normal_stop,
 
   /* Now that the inferior has stopped, do any bookkeeping like
      loading shared libraries.  We want to do this before normal_stop,
@@ -3099,7 +3241,7 @@ init_wait_for_inferior (void)
 
   clear_proceed_status (0);
 
 
   clear_proceed_status (0);
 
-  target_last_wait_ptid = minus_one_ptid;
+  nullify_last_target_wait_ptid ();
 
   previous_inferior_ptid = inferior_ptid;
 }
 
   previous_inferior_ptid = inferior_ptid;
 }
@@ -3129,11 +3271,13 @@ static int switch_back_to_stepped_thread (struct execution_control_state *ecs);
 static void
 infrun_thread_stop_requested (ptid_t ptid)
 {
 static void
 infrun_thread_stop_requested (ptid_t ptid)
 {
+  process_stratum_target *curr_target = current_inferior ()->process_target ();
+
   /* PTID was requested to stop.  If the thread was already stopped,
      but the user/frontend doesn't know about that yet (e.g., the
      thread had been temporarily paused for some step-over), set up
      for reporting the stop now.  */
   /* PTID was requested to stop.  If the thread was already stopped,
      but the user/frontend doesn't know about that yet (e.g., the
      thread had been temporarily paused for some step-over), set up
      for reporting the stop now.  */
-  for (thread_info *tp : all_threads (ptid))
+  for (thread_info *tp : all_threads (curr_target, ptid))
     {
       if (tp->state != THREAD_RUNNING)
        continue;
     {
       if (tp->state != THREAD_RUNNING)
        continue;
@@ -3159,7 +3303,7 @@ infrun_thread_stop_requested (ptid_t ptid)
 
       /* Clear the inline-frame state, since we're re-processing the
         stop.  */
 
       /* Clear the inline-frame state, since we're re-processing the
         stop.  */
-      clear_inline_frame_state (tp->ptid);
+      clear_inline_frame_state (tp);
 
       /* If this thread was paused because some other thread was
         doing an inline-step over, let that finish first.  Once
 
       /* If this thread was paused because some other thread was
         doing an inline-step over, let that finish first.  Once
@@ -3178,7 +3322,8 @@ infrun_thread_stop_requested (ptid_t ptid)
 static void
 infrun_thread_thread_exit (struct thread_info *tp, int silent)
 {
 static void
 infrun_thread_thread_exit (struct thread_info *tp, int silent)
 {
-  if (target_last_wait_ptid == tp->ptid)
+  if (target_last_proc_target == tp->inf->process_target ()
+      && target_last_wait_ptid == tp->ptid)
     nullify_last_target_wait_ptid ();
 }
 
     nullify_last_target_wait_ptid ();
 }
 
@@ -3256,13 +3401,13 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
              waiton_ptid.lwp (),
              waiton_ptid.tid ());
   if (waiton_ptid.pid () != -1)
              waiton_ptid.lwp (),
              waiton_ptid.tid ());
   if (waiton_ptid.pid () != -1)
-    stb.printf (" [%s]", target_pid_to_str (waiton_ptid));
+    stb.printf (" [%s]", target_pid_to_str (waiton_ptid).c_str ());
   stb.printf (", status) =\n");
   stb.printf ("infrun:   %d.%ld.%ld [%s],\n",
              result_ptid.pid (),
              result_ptid.lwp (),
              result_ptid.tid (),
   stb.printf (", status) =\n");
   stb.printf ("infrun:   %d.%ld.%ld [%s],\n",
              result_ptid.pid (),
              result_ptid.lwp (),
              result_ptid.tid (),
-             target_pid_to_str (result_ptid));
+             target_pid_to_str (result_ptid).c_str ());
   stb.printf ("infrun:   %s\n", status_string.c_str ());
 
   /* This uses %s in part to handle %'s in the text, but also to avoid
   stb.printf ("infrun:   %s\n", status_string.c_str ());
 
   /* This uses %s in part to handle %'s in the text, but also to avoid
@@ -3274,19 +3419,20 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
    had events.  */
 
 static struct thread_info *
    had events.  */
 
 static struct thread_info *
-random_pending_event_thread (ptid_t waiton_ptid)
+random_pending_event_thread (inferior *inf, ptid_t waiton_ptid)
 {
   int num_events = 0;
 
 {
   int num_events = 0;
 
-  auto has_event = [] (thread_info *tp)
+  auto has_event = [&] (thread_info *tp)
     {
     {
-      return (tp->resumed
+      return (tp->ptid.matches (waiton_ptid)
+             && tp->resumed
              && tp->suspend.waitstatus_pending_p);
     };
 
   /* First see how many events we have.  Count only resumed threads
      that have an event pending.  */
              && tp->suspend.waitstatus_pending_p);
     };
 
   /* First see how many events we have.  Count only resumed threads
      that have an event pending.  */
-  for (thread_info *tp : all_non_exited_threads (waiton_ptid))
+  for (thread_info *tp : inf->non_exited_threads ())
     if (has_event (tp))
       num_events++;
 
     if (has_event (tp))
       num_events++;
 
@@ -3303,7 +3449,7 @@ random_pending_event_thread (ptid_t waiton_ptid)
                        num_events, random_selector);
 
   /* Select the Nth thread that has had an event.  */
                        num_events, random_selector);
 
   /* Select the Nth thread that has had an event.  */
-  for (thread_info *tp : all_non_exited_threads (waiton_ptid))
+  for (thread_info *tp : inf->non_exited_threads ())
     if (has_event (tp))
       if (random_selector-- == 0)
        return tp;
     if (has_event (tp))
       if (random_selector-- == 0)
        return tp;
@@ -3313,10 +3459,12 @@ random_pending_event_thread (ptid_t waiton_ptid)
 
 /* Wrapper for target_wait that first checks whether threads have
    pending statuses to report before actually asking the target for
 
 /* Wrapper for target_wait that first checks whether threads have
    pending statuses to report before actually asking the target for
-   more events.  */
+   more events.  INF is the inferior we're using to call target_wait
+   on.  */
 
 static ptid_t
 
 static ptid_t
-do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
+do_target_wait_1 (inferior *inf, ptid_t ptid,
+                 target_waitstatus *status, int options)
 {
   ptid_t event_ptid;
   struct thread_info *tp;
 {
   ptid_t event_ptid;
   struct thread_info *tp;
@@ -3325,17 +3473,17 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
      pending.  */
   if (ptid == minus_one_ptid || ptid.is_pid ())
     {
      pending.  */
   if (ptid == minus_one_ptid || ptid.is_pid ())
     {
-      tp = random_pending_event_thread (ptid);
+      tp = random_pending_event_thread (inf, ptid);
     }
   else
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: Waiting for specific thread %s.\n",
     }
   else
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: Waiting for specific thread %s.\n",
-                           target_pid_to_str (ptid));
+                           target_pid_to_str (ptid).c_str ());
 
       /* We have a specific thread to check.  */
 
       /* We have a specific thread to check.  */
-      tp = find_thread_ptid (ptid);
+      tp = find_thread_ptid (inf, ptid);
       gdb_assert (tp != NULL);
       if (!tp->suspend.waitstatus_pending_p)
        tp = NULL;
       gdb_assert (tp != NULL);
       if (!tp->suspend.waitstatus_pending_p)
        tp = NULL;
@@ -3357,7 +3505,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: PC of %s changed.  was=%s, now=%s\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: PC of %s changed.  was=%s, now=%s\n",
-                               target_pid_to_str (tp->ptid),
+                               target_pid_to_str (tp->ptid).c_str (),
                                paddress (gdbarch, tp->suspend.stop_pc),
                                paddress (gdbarch, pc));
          discard = 1;
                                paddress (gdbarch, tp->suspend.stop_pc),
                                paddress (gdbarch, pc));
          discard = 1;
@@ -3367,7 +3515,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: previous breakpoint of %s, at %s gone\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: previous breakpoint of %s, at %s gone\n",
-                               target_pid_to_str (tp->ptid),
+                               target_pid_to_str (tp->ptid).c_str (),
                                paddress (gdbarch, pc));
 
          discard = 1;
                                paddress (gdbarch, pc));
 
          discard = 1;
@@ -3378,7 +3526,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: pending event of %s cancelled.\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: pending event of %s cancelled.\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          tp->suspend.waitstatus.kind = TARGET_WAITKIND_SPURIOUS;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
          tp->suspend.waitstatus.kind = TARGET_WAITKIND_SPURIOUS;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
@@ -3395,7 +3543,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: Using pending wait status %s for %s.\n",
                              statstr.c_str (),
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: Using pending wait status %s for %s.\n",
                              statstr.c_str (),
-                             target_pid_to_str (tp->ptid));
+                             target_pid_to_str (tp->ptid).c_str ());
        }
 
       /* Now that we've selected our final event LWP, un-adjust its PC
        }
 
       /* Now that we've selected our final event LWP, un-adjust its PC
@@ -3442,6 +3590,109 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
   return event_ptid;
 }
 
   return event_ptid;
 }
 
+/* Returns true if INF has any resumed thread with a status
+   pending.  */
+
+static bool
+threads_are_resumed_pending_p (inferior *inf)
+{
+  for (thread_info *tp : inf->non_exited_threads ())
+    if (tp->resumed
+       && tp->suspend.waitstatus_pending_p)
+      return true;
+
+  return false;
+}
+
+/* Wrapper for target_wait that first checks whether threads have
+   pending statuses to report before actually asking the target for
+   more events. Polls for events from all inferiors/targets.  */
+
+static bool
+do_target_wait (ptid_t wait_ptid, execution_control_state *ecs, int options)
+{
+  int num_inferiors = 0;
+  int random_selector;
+
+  /* For fairness, we pick the first inferior/target to poll at
+     random, and then continue polling the rest of the inferior list
+     starting from that one in a circular fashion until the whole list
+     is polled once.  */
+
+  auto inferior_matches = [&wait_ptid] (inferior *inf)
+    {
+      return (inf->process_target () != NULL
+             && (threads_are_executing (inf->process_target ())
+                 || threads_are_resumed_pending_p (inf))
+             && ptid_t (inf->pid).matches (wait_ptid));
+    };
+
+  /* First see how many resumed inferiors we have.  */
+  for (inferior *inf : all_inferiors ())
+    if (inferior_matches (inf))
+      num_inferiors++;
+
+  if (num_inferiors == 0)
+    {
+      ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+      return false;
+    }
+
+  /* Now randomly pick an inferior out of those that were resumed.  */
+  random_selector = (int)
+    ((num_inferiors * (double) rand ()) / (RAND_MAX + 1.0));
+
+  if (debug_infrun && num_inferiors > 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: Found %d inferiors, starting at #%d\n",
+                       num_inferiors, random_selector);
+
+  /* Select the Nth inferior that was resumed.  */
+
+  inferior *selected = nullptr;
+
+  for (inferior *inf : all_inferiors ())
+    if (inferior_matches (inf))
+      if (random_selector-- == 0)
+       {
+         selected = inf;
+         break;
+       }
+
+  /* Now poll for events out of each of the resumed inferior's
+     targets, starting from the selected one.  */
+
+  auto do_wait = [&] (inferior *inf)
+  {
+    switch_to_inferior_no_thread (inf);
+
+    ecs->ptid = do_target_wait_1 (inf, wait_ptid, &ecs->ws, options);
+    ecs->target = inf->process_target ();
+    return (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+  };
+
+  /* Needed in all-stop+target-non-stop mode, because we end up here
+     spuriously after the target is all stopped and we've already
+     reported the stop to the user, polling for events.  */
+  scoped_restore_current_thread restore_thread;
+
+  int inf_num = selected->num;
+  for (inferior *inf = selected; inf != NULL; inf = inf->next)
+    if (inferior_matches (inf))
+      if (do_wait (inf))
+       return true;
+
+  for (inferior *inf = inferior_list;
+       inf != NULL && inf->num < inf_num;
+       inf = inf->next)
+    if (inferior_matches (inf))
+      if (do_wait (inf))
+       return true;
+
+  ecs->ws.kind = TARGET_WAITKIND_IGNORE;
+  return false;
+}
+
 /* Prepare and stabilize the inferior for detaching it.  E.g.,
    detaching while a thread is displaced stepping is a recipe for
    crashing it, as nothing would readjust the PC out of the scratch
 /* Prepare and stabilize the inferior for detaching it.  E.g.,
    detaching while a thread is displaced stepping is a recipe for
    crashing it, as nothing would readjust the PC out of the scratch
@@ -3481,7 +3732,7 @@ prepare_for_detach (void)
         don't get any event.  */
       target_dcache_invalidate ();
 
         don't get any event.  */
       target_dcache_invalidate ();
 
-      ecs->ptid = do_target_wait (pid_ptid, &ecs->ws, 0);
+      do_target_wait (pid_ptid, ecs, 0);
 
       if (debug_infrun)
        print_target_wait_results (pid_ptid, ecs->ptid, &ecs->ws);
 
       if (debug_infrun)
        print_target_wait_results (pid_ptid, ecs->ptid, &ecs->ws);
@@ -3489,7 +3740,8 @@ prepare_for_detach (void)
       /* If an error happens while handling the event, propagate GDB's
         knowledge of the executing state to the frontend/user running
         state.  */
       /* If an error happens while handling the event, propagate GDB's
         knowledge of the executing state to the frontend/user running
         state.  */
-      scoped_finish_thread_state finish_state (minus_one_ptid);
+      scoped_finish_thread_state finish_state (inf->process_target (),
+                                              minus_one_ptid);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
@@ -3517,8 +3769,8 @@ prepare_for_detach (void)
    When this function actually returns it means the inferior
    should be left stopped and GDB should read more commands.  */
 
    When this function actually returns it means the inferior
    should be left stopped and GDB should read more commands.  */
 
-void
-wait_for_inferior (void)
+static void
+wait_for_inferior (inferior *inf)
 {
   if (debug_infrun)
     fprintf_unfiltered
 {
   if (debug_infrun)
     fprintf_unfiltered
@@ -3529,13 +3781,13 @@ wait_for_inferior (void)
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
      state.  */
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
      state.  */
-  scoped_finish_thread_state finish_state (minus_one_ptid);
+  scoped_finish_thread_state finish_state
+    (inf->process_target (), minus_one_ptid);
 
   while (1)
     {
       struct execution_control_state ecss;
       struct execution_control_state *ecs = &ecss;
 
   while (1)
     {
       struct execution_control_state ecss;
       struct execution_control_state *ecs = &ecss;
-      ptid_t waiton_ptid = minus_one_ptid;
 
       memset (ecs, 0, sizeof (*ecs));
 
 
       memset (ecs, 0, sizeof (*ecs));
 
@@ -3547,10 +3799,11 @@ wait_for_inferior (void)
         don't get any event.  */
       target_dcache_invalidate ();
 
         don't get any event.  */
       target_dcache_invalidate ();
 
-      ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws, 0);
+      ecs->ptid = do_target_wait_1 (inf, minus_one_ptid, &ecs->ws, 0);
+      ecs->target = inf->process_target ();
 
       if (debug_infrun)
 
       if (debug_infrun)
-       print_target_wait_results (waiton_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);
 
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
@@ -3676,7 +3929,6 @@ fetch_inferior_event (void *client_data)
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
   int cmd_done = 0;
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
   int cmd_done = 0;
-  ptid_t waiton_ptid = minus_one_ptid;
 
   memset (ecs, 0, sizeof (*ecs));
 
 
   memset (ecs, 0, sizeof (*ecs));
 
@@ -3700,14 +3952,11 @@ fetch_inferior_event (void *client_data)
        set_current_traceframe (-1);
       }
 
        set_current_traceframe (-1);
       }
 
-    gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
-
-    if (non_stop)
-      /* In non-stop mode, the user/frontend should not notice a thread
-        switch due to internal events.  Make sure we reverse to the
-        user selected thread and frame after handling the event and
-        running any breakpoint commands.  */
-      maybe_restore_thread.emplace ();
+    /* The user/frontend should not notice a thread switch due to
+       internal events.  Make sure we revert to the user selected
+       thread and frame after handling the event and running any
+       breakpoint commands.  */
+    scoped_restore_current_thread restore_thread;
 
     overlay_cache_invalid = 1;
     /* Flush target cache before starting to handle each event.  Target
 
     overlay_cache_invalid = 1;
     /* Flush target cache before starting to handle each event.  Target
@@ -3720,17 +3969,28 @@ fetch_inferior_event (void *client_data)
       = make_scoped_restore (&execution_direction,
                             target_execution_direction ());
 
       = make_scoped_restore (&execution_direction,
                             target_execution_direction ());
 
-    ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
-                               target_can_async_p () ? TARGET_WNOHANG : 0);
+    if (!do_target_wait (minus_one_ptid, ecs, TARGET_WNOHANG))
+      return;
+
+    gdb_assert (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
+
+    /* Switch to the target that generated the event, so we can do
+       target calls.  Any inferior bound to the target will do, so we
+       just switch to the first we find.  */
+    for (inferior *inf : all_inferiors (ecs->target))
+      {
+       switch_to_inferior_no_thread (inf);
+       break;
+      }
 
     if (debug_infrun)
 
     if (debug_infrun)
-      print_target_wait_results (waiton_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
        state.  */
     ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
 
     /* If an error happens while handling the event, propagate GDB's
        knowledge of the executing state to the frontend/user running
        state.  */
     ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
-    scoped_finish_thread_state finish_state (finish_ptid);
+    scoped_finish_thread_state finish_state (ecs->target, finish_ptid);
 
     /* Get executed before scoped_restore_current_thread above to apply
        still for the thread which has thrown the exception.  */
 
     /* Get executed before scoped_restore_current_thread above to apply
        still for the thread which has thrown the exception.  */
@@ -3744,7 +4004,7 @@ fetch_inferior_event (void *client_data)
 
     if (!ecs->wait_some_more)
       {
 
     if (!ecs->wait_some_more)
       {
-       struct inferior *inf = find_inferior_ptid (ecs->ptid);
+       struct inferior *inf = find_inferior_ptid (ecs->target, ecs->ptid);
        int should_stop = 1;
        struct thread_info *thr = ecs->event_thread;
 
        int should_stop = 1;
        struct thread_info *thr = ecs->event_thread;
 
@@ -3784,6 +4044,19 @@ fetch_inferior_event (void *client_data)
                inferior_event_handler (INF_EXEC_COMPLETE, NULL);
                cmd_done = 1;
              }
                inferior_event_handler (INF_EXEC_COMPLETE, NULL);
                cmd_done = 1;
              }
+
+           /* If we got a TARGET_WAITKIND_NO_RESUMED event, then the
+              previously selected thread is gone.  We have two
+              choices - switch to no thread selected, or restore the
+              previously selected thread (now exited).  We chose the
+              later, just because that's what GDB used to do.  After
+              this, "info threads" says "The current thread <Thread
+              ID 2> has terminated." instead of "No thread
+              selected.".  */
+           if (!non_stop
+               && cmd_done
+               && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
+             restore_thread.dont_restore ();
          }
       }
 
          }
       }
 
@@ -3833,31 +4106,39 @@ init_thread_stepping_state (struct thread_info *tss)
   tss->step_after_step_resume_breakpoint = 0;
 }
 
   tss->step_after_step_resume_breakpoint = 0;
 }
 
-/* Set the cached copy of the last ptid/waitstatus.  */
+/* See infrun.h.  */
 
 void
 
 void
-set_last_target_status (ptid_t ptid, struct target_waitstatus status)
+set_last_target_status (process_stratum_target *target, ptid_t ptid,
+                       target_waitstatus status)
 {
 {
+  target_last_proc_target = target;
   target_last_wait_ptid = ptid;
   target_last_waitstatus = status;
 }
 
   target_last_wait_ptid = ptid;
   target_last_waitstatus = status;
 }
 
-/* Return the cached copy of the last pid/waitstatus returned by
-   target_wait()/deprecated_target_wait_hook().  The data is actually
-   cached by handle_inferior_event(), which gets called immediately
-   after target_wait()/deprecated_target_wait_hook().  */
+/* See infrun.h.  */
 
 void
 
 void
-get_last_target_status (ptid_t *ptidp, struct target_waitstatus *status)
+get_last_target_status (process_stratum_target **target, ptid_t *ptid,
+                       target_waitstatus *status)
 {
 {
-  *ptidp = target_last_wait_ptid;
-  *status = target_last_waitstatus;
+  if (target != nullptr)
+    *target = target_last_proc_target;
+  if (ptid != nullptr)
+    *ptid = target_last_wait_ptid;
+  if (status != nullptr)
+    *status = target_last_waitstatus;
 }
 
 }
 
+/* See infrun.h.  */
+
 void
 nullify_last_target_wait_ptid (void)
 {
 void
 nullify_last_target_wait_ptid (void)
 {
+  target_last_proc_target = nullptr;
   target_last_wait_ptid = minus_one_ptid;
   target_last_wait_ptid = minus_one_ptid;
+  target_last_waitstatus = {};
 }
 
 /* Switch thread contexts.  */
 }
 
 /* Switch thread contexts.  */
@@ -3867,12 +4148,13 @@ context_switch (execution_control_state *ecs)
 {
   if (debug_infrun
       && ecs->ptid != inferior_ptid
 {
   if (debug_infrun
       && ecs->ptid != inferior_ptid
-      && ecs->event_thread != inferior_thread ())
+      && (inferior_ptid == null_ptid
+         || ecs->event_thread != inferior_thread ()))
     {
       fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
     {
       fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
-                         target_pid_to_str (inferior_ptid));
+                         target_pid_to_str (inferior_ptid).c_str ());
       fprintf_unfiltered (gdb_stdlog, "to %s\n",
       fprintf_unfiltered (gdb_stdlog, "to %s\n",
-                         target_pid_to_str (ecs->ptid));
+                         target_pid_to_str (ecs->ptid).c_str ());
     }
 
   switch_to_thread (ecs->event_thread);
     }
 
   switch_to_thread (ecs->event_thread);
@@ -4041,6 +4323,45 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
   return 0;
 }
 
   return 0;
 }
 
+/* Look for an inline frame that is marked for skip.
+   If PREV_FRAME is TRUE start at the previous frame,
+   otherwise start at the current frame.  Stop at the
+   first non-inline frame, or at the frame where the
+   step started.  */
+
+static bool
+inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
+{
+  struct frame_info *frame = get_current_frame ();
+
+  if (prev_frame)
+    frame = get_prev_frame (frame);
+
+  for (; frame != NULL; frame = get_prev_frame (frame))
+    {
+      const char *fn = NULL;
+      symtab_and_line sal;
+      struct symbol *sym;
+
+      if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+       break;
+      if (get_frame_type (frame) != INLINE_FRAME)
+       break;
+
+      sal = find_frame_sal (frame);
+      sym = get_frame_function (frame);
+
+      if (sym != NULL)
+       fn = sym->print_name ();
+
+      if (sal.line != 0
+         && function_name_is_marked_for_skip (fn, sal))
+       return true;
+    }
+
+  return false;
+}
+
 /* If the event thread has the stop requested flag set, pretend it
    stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
    target_stop).  */
 /* If the event thread has the stop requested flag set, pretend it
    stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
    target_stop).  */
@@ -4113,18 +4434,35 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 {
   if (!ecs->stop_func_filled_in)
     {
 {
   if (!ecs->stop_func_filled_in)
     {
+      const block *block;
+
       /* Don't care about return value; stop_func_start and stop_func_name
         will both be 0 if it doesn't work.  */
       /* Don't care about return value; stop_func_start and stop_func_name
         will both be 0 if it doesn't work.  */
-      find_function_entry_range_from_pc (ecs->event_thread->suspend.stop_pc,
-                                        &ecs->stop_func_name,
-                                        &ecs->stop_func_start,
-                                        &ecs->stop_func_end);
-      ecs->stop_func_start
-       += gdbarch_deprecated_function_start_offset (gdbarch);
-
-      if (gdbarch_skip_entrypoint_p (gdbarch))
-       ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
-                                                       ecs->stop_func_start);
+      find_pc_partial_function (ecs->event_thread->suspend.stop_pc,
+                               &ecs->stop_func_name,
+                               &ecs->stop_func_start,
+                               &ecs->stop_func_end,
+                               &block);
+
+      /* The call to find_pc_partial_function, above, will set
+        stop_func_start and stop_func_end to the start and end
+        of the range containing the stop pc.  If this range
+        contains the entry pc for the block (which is always the
+        case for contiguous blocks), advance stop_func_start past
+        the function's start offset and entrypoint.  Note that
+        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
+           += gdbarch_deprecated_function_start_offset (gdbarch);
+
+         if (gdbarch_skip_entrypoint_p (gdbarch))
+           ecs->stop_func_start
+             = gdbarch_skip_entrypoint (gdbarch, ecs->stop_func_start);
+       }
 
       ecs->stop_func_filled_in = 1;
     }
 
       ecs->stop_func_filled_in = 1;
     }
@@ -4136,20 +4474,19 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 static enum stop_kind
 get_inferior_stop_soon (execution_control_state *ecs)
 {
 static enum stop_kind
 get_inferior_stop_soon (execution_control_state *ecs)
 {
-  struct inferior *inf = find_inferior_ptid (ecs->ptid);
+  struct inferior *inf = find_inferior_ptid (ecs->target, ecs->ptid);
 
   gdb_assert (inf != NULL);
   return inf->control.stop_soon;
 }
 
 
   gdb_assert (inf != NULL);
   return inf->control.stop_soon;
 }
 
-/* Wait for one event.  Store the resulting waitstatus in WS, and
-   return the event ptid.  */
+/* Poll for one event out of the current target.  Store the resulting
+   waitstatus in WS, and return the event ptid.  Does not block.  */
 
 static ptid_t
 
 static ptid_t
-wait_one (struct target_waitstatus *ws)
+poll_one_curr_target (struct target_waitstatus *ws)
 {
   ptid_t event_ptid;
 {
   ptid_t event_ptid;
-  ptid_t wait_ptid = minus_one_ptid;
 
   overlay_cache_invalid = 1;
 
 
   overlay_cache_invalid = 1;
 
@@ -4160,16 +4497,101 @@ wait_one (struct target_waitstatus *ws)
   target_dcache_invalidate ();
 
   if (deprecated_target_wait_hook)
   target_dcache_invalidate ();
 
   if (deprecated_target_wait_hook)
-    event_ptid = deprecated_target_wait_hook (wait_ptid, ws, 0);
+    event_ptid = deprecated_target_wait_hook (minus_one_ptid, ws, TARGET_WNOHANG);
   else
   else
-    event_ptid = target_wait (wait_ptid, ws, 0);
+    event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG);
 
   if (debug_infrun)
 
   if (debug_infrun)
-    print_target_wait_results (wait_ptid, event_ptid, ws);
+    print_target_wait_results (minus_one_ptid, event_ptid, ws);
 
   return event_ptid;
 }
 
 
   return event_ptid;
 }
 
+/* An event reported by wait_one.  */
+
+struct wait_one_event
+{
+  /* The target the event came out of.  */
+  process_stratum_target *target;
+
+  /* The PTID the event was for.  */
+  ptid_t ptid;
+
+  /* The waitstatus.  */
+  target_waitstatus ws;
+};
+
+/* Wait for one event out of any target.  */
+
+static wait_one_event
+wait_one ()
+{
+  while (1)
+    {
+      for (inferior *inf : all_inferiors ())
+       {
+         process_stratum_target *target = inf->process_target ();
+         if (target == NULL
+             || !target->is_async_p ()
+             || !target->threads_executing)
+           continue;
+
+         switch_to_inferior_no_thread (inf);
+
+         wait_one_event event;
+         event.target = target;
+         event.ptid = poll_one_curr_target (&event.ws);
+
+         if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+           {
+             /* If nothing is resumed, remove the target from the
+                event loop.  */
+             target_async (0);
+           }
+         else if (event.ws.kind != TARGET_WAITKIND_IGNORE)
+           return event;
+       }
+
+      /* Block waiting for some event.  */
+
+      fd_set readfds;
+      int nfds = 0;
+
+      FD_ZERO (&readfds);
+
+      for (inferior *inf : all_inferiors ())
+       {
+         process_stratum_target *target = inf->process_target ();
+         if (target == NULL
+             || !target->is_async_p ()
+             || !target->threads_executing)
+           continue;
+
+         int fd = target->async_wait_fd ();
+         FD_SET (fd, &readfds);
+         if (nfds <= fd)
+           nfds = fd + 1;
+       }
+
+      if (nfds == 0)
+       {
+         /* No waitable targets left.  All must be stopped.  */
+         return {NULL, minus_one_ptid, {TARGET_WAITKIND_NO_RESUMED}};
+       }
+
+      QUIT;
+
+      int numfds = interruptible_select (nfds, &readfds, 0, NULL, 0);
+      if (numfds < 0)
+       {
+         if (errno == EINTR)
+           continue;
+         else
+           perror_with_name ("interruptible_select");
+       }
+    }
+}
+
 /* Generate a wrapper for target_stopped_by_REASON that works on PTID
    instead of the current thread.  */
 #define THREAD_STOPPED_BY(REASON)              \
 /* Generate a wrapper for target_stopped_by_REASON that works on PTID
    instead of the current thread.  */
 #define THREAD_STOPPED_BY(REASON)              \
@@ -4192,7 +4614,7 @@ THREAD_STOPPED_BY (hw_breakpoint)
 /* Save the thread's event and stop reason to process it later.  */
 
 static void
 /* Save the thread's event and stop reason to process it later.  */
 
 static void
-save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
+save_waitstatus (struct thread_info *tp, const target_waitstatus *ws)
 {
   if (debug_infrun)
     {
 {
   if (debug_infrun)
     {
@@ -4292,8 +4714,6 @@ stop_all_threads (void)
                            "iterations=%d\n", pass, iterations);
       while (1)
        {
                            "iterations=%d\n", pass, iterations);
       while (1)
        {
-         ptid_t event_ptid;
-         struct target_waitstatus ws;
          int need_wait = 0;
 
          update_thread_list ();
          int need_wait = 0;
 
          update_thread_list ();
@@ -4312,7 +4732,8 @@ stop_all_threads (void)
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "need stop\n",
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "need stop\n",
-                                           target_pid_to_str (t->ptid));
+                                           target_pid_to_str (t->ptid).c_str ());
+                     switch_to_thread_no_regs (t);
                      target_stop (t->ptid);
                      t->stop_requested = 1;
                    }
                      target_stop (t->ptid);
                      t->stop_requested = 1;
                    }
@@ -4322,7 +4743,7 @@ stop_all_threads (void)
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "already stopping\n",
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "already stopping\n",
-                                           target_pid_to_str (t->ptid));
+                                           target_pid_to_str (t->ptid).c_str ());
                    }
 
                  if (t->stop_requested)
                    }
 
                  if (t->stop_requested)
@@ -4333,7 +4754,7 @@ stop_all_threads (void)
                  if (debug_infrun)
                    fprintf_unfiltered (gdb_stdlog,
                                        "infrun:   %s not executing\n",
                  if (debug_infrun)
                    fprintf_unfiltered (gdb_stdlog,
                                        "infrun:   %s not executing\n",
-                                       target_pid_to_str (t->ptid));
+                                       target_pid_to_str (t->ptid).c_str ());
 
                  /* The thread may be not executing, but still be
                     resumed with a pending status to process.  */
 
                  /* The thread may be not executing, but still be
                     resumed with a pending status to process.  */
@@ -4350,31 +4771,29 @@ stop_all_threads (void)
          if (pass > 0)
            pass = -1;
 
          if (pass > 0)
            pass = -1;
 
-         event_ptid = wait_one (&ws);
+         wait_one_event event = wait_one ();
 
 
-         if (ws.kind == TARGET_WAITKIND_NO_RESUMED)
+         if (debug_infrun)
            {
            {
-             /* All resumed threads exited.  */
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: stop_all_threads %s %s\n",
+                                 target_waitstatus_to_string (&event.ws).c_str (),
+                                 target_pid_to_str (event.ptid).c_str ());
            }
            }
-         else if (ws.kind == TARGET_WAITKIND_THREAD_EXITED
-                  || ws.kind == TARGET_WAITKIND_EXITED
-                  || ws.kind == TARGET_WAITKIND_SIGNALLED)
-           {
-             if (debug_infrun)
-               {
-                 ptid_t ptid = ptid_t (ws.value.integer);
 
 
-                 fprintf_unfiltered (gdb_stdlog,
-                                     "infrun: %s exited while "
-                                     "stopping threads\n",
-                                     target_pid_to_str (ptid));
-               }
+         if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED
+             || event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
+             || event.ws.kind == TARGET_WAITKIND_EXITED
+             || event.ws.kind == TARGET_WAITKIND_SIGNALLED)
+           {
+             /* All resumed threads exited
+                or one thread/process exited/signalled.  */
            }
          else
            {
            }
          else
            {
-             thread_info *t = find_thread_ptid (event_ptid);
+             thread_info *t = find_thread_ptid (event.target, event.ptid);
              if (t == NULL)
              if (t == NULL)
-               t = add_thread (event_ptid);
+               t = add_thread (event.target, event.ptid);
 
              t->stop_requested = 0;
              t->executing = 0;
 
              t->stop_requested = 0;
              t->executing = 0;
@@ -4383,15 +4802,15 @@ stop_all_threads (void)
 
              /* This may be the first time we see the inferior report
                 a stop.  */
 
              /* This may be the first time we see the inferior report
                 a stop.  */
-             inferior *inf = find_inferior_ptid (event_ptid);
+             inferior *inf = find_inferior_ptid (event.target, event.ptid);
              if (inf->needs_setup)
                {
                  switch_to_thread_no_regs (t);
                  setup_inferior (0);
                }
 
              if (inf->needs_setup)
                {
                  switch_to_thread_no_regs (t);
                  setup_inferior (0);
                }
 
-             if (ws.kind == TARGET_WAITKIND_STOPPED
-                 && ws.value.sig == GDB_SIGNAL_0)
+             if (event.ws.kind == TARGET_WAITKIND_STOPPED
+                 && event.ws.value.sig == GDB_SIGNAL_0)
                {
                  /* We caught the event that we intended to catch, so
                     there's no event pending.  */
                {
                  /* We caught the event that we intended to catch, so
                     there's no event pending.  */
@@ -4407,7 +4826,7 @@ stop_all_threads (void)
                                              "infrun: displaced-step of %s "
                                              "canceled: adding back to the "
                                              "step-over queue\n",
                                              "infrun: displaced-step of %s "
                                              "canceled: adding back to the "
                                              "step-over queue\n",
-                                             target_pid_to_str (t->ptid));
+                                             target_pid_to_str (t->ptid).c_str ());
                        }
                      t->control.trap_expected = 0;
                      thread_step_over_chain_enqueue (t);
                        }
                      t->control.trap_expected = 0;
                      thread_step_over_chain_enqueue (t);
@@ -4420,7 +4839,7 @@ stop_all_threads (void)
 
                  if (debug_infrun)
                    {
 
                  if (debug_infrun)
                    {
-                     std::string statstr = target_waitstatus_to_string (&ws);
+                     std::string statstr = target_waitstatus_to_string (&event.ws);
 
                      fprintf_unfiltered (gdb_stdlog,
                                          "infrun: target_wait %s, saving "
 
                      fprintf_unfiltered (gdb_stdlog,
                                          "infrun: target_wait %s, saving "
@@ -4432,10 +4851,10 @@ stop_all_threads (void)
                    }
 
                  /* Record for later.  */
                    }
 
                  /* Record for later.  */
-                 save_waitstatus (t, &ws);
+                 save_waitstatus (t, &event.ws);
 
 
-                 sig = (ws.kind == TARGET_WAITKIND_STOPPED
-                        ? ws.value.sig : GDB_SIGNAL_0);
+                 sig = (event.ws.kind == TARGET_WAITKIND_STOPPED
+                        ? event.ws.value.sig : GDB_SIGNAL_0);
 
                  if (displaced_step_fixup (t, sig) < 0)
                    {
 
                  if (displaced_step_fixup (t, sig) < 0)
                    {
@@ -4454,7 +4873,7 @@ stop_all_threads (void)
                                          "(currently_stepping=%d)\n",
                                          paddress (target_gdbarch (),
                                                    t->suspend.stop_pc),
                                          "(currently_stepping=%d)\n",
                                          paddress (target_gdbarch (),
                                                    t->suspend.stop_pc),
-                                         target_pid_to_str (t->ptid),
+                                         target_pid_to_str (t->ptid).c_str (),
                                          currently_stepping (t));
                    }
                }
                                          currently_stepping (t));
                    }
                }
@@ -4533,7 +4952,7 @@ handle_no_resumed (struct execution_control_state *ecs)
      the synchronous command show "no unwaited-for " to the user.  */
   update_thread_list ();
 
      the synchronous command show "no unwaited-for " to the user.  */
   update_thread_list ();
 
-  for (thread_info *thread : all_non_exited_threads ())
+  for (thread_info *thread : all_non_exited_threads (ecs->target))
     {
       if (thread->executing
          || thread->suspend.waitstatus_pending_p)
     {
       if (thread->executing
          || thread->suspend.waitstatus_pending_p)
@@ -4553,11 +4972,8 @@ handle_no_resumed (struct execution_control_state *ecs)
      process exited meanwhile (thus updating the thread list results
      in an empty thread list).  In this case we know we'll be getting
      a process exit event shortly.  */
      process exited meanwhile (thus updating the thread list results
      in an empty thread list).  In this case we know we'll be getting
      a process exit event shortly.  */
-  for (inferior *inf : all_inferiors ())
+  for (inferior *inf : all_non_exited_inferiors (ecs->target))
     {
     {
-      if (inf->pid == 0)
-       continue;
-
       thread_info *thread = any_live_thread_of_inferior (inf);
       if (thread == NULL)
        {
       thread_info *thread = any_live_thread_of_inferior (inf);
       if (thread == NULL)
        {
@@ -4588,10 +5004,19 @@ handle_no_resumed (struct execution_control_state *ecs)
    once).  */
 
 static void
    once).  */
 
 static void
-handle_inferior_event_1 (struct execution_control_state *ecs)
+handle_inferior_event (struct execution_control_state *ecs)
 {
 {
+  /* Make sure that all temporary struct value objects that were
+     created during the handling of the event get deleted at the
+     end.  */
+  scoped_value_mark free_values;
+
   enum stop_kind stop_soon;
 
   enum stop_kind stop_soon;
 
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog, "infrun: handle_inferior_event %s\n",
+                       target_waitstatus_to_string (&ecs->ws).c_str ());
+
   if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
     {
       /* We had an event in the inferior, but we are not interested in
   if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
     {
       /* We had an event in the inferior, but we are not interested in
@@ -4603,16 +5028,12 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
         not stopped, and we are ignoring the event.  Another possible
         circumstance is any event which the lower level knows will be
         reported multiple times without an intervening resume.  */
         not stopped, and we are ignoring the event.  Another possible
         circumstance is any event which the lower level knows will be
         reported multiple times without an intervening resume.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
       prepare_to_wait (ecs);
       return;
     }
 
   if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
     {
       prepare_to_wait (ecs);
       return;
     }
 
   if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
     {
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_EXITED\n");
       prepare_to_wait (ecs);
       return;
     }
       prepare_to_wait (ecs);
       return;
     }
@@ -4621,8 +5042,8 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
       && handle_no_resumed (ecs))
     return;
 
       && handle_no_resumed (ecs))
     return;
 
-  /* Cache the last pid/waitstatus.  */
-  set_last_target_status (ecs->ptid, ecs->ws);
+  /* Cache the last target/ptid/waitstatus.  */
+  set_last_target_status (ecs->target, ecs->ptid, ecs->ws);
 
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
 
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
@@ -4631,9 +5052,6 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
     {
       /* No unwaited-for children left.  IOW, all resumed children
         have exited.  */
     {
       /* No unwaited-for children left.  IOW, all resumed children
         have exited.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
-
       stop_print_frame = 0;
       stop_waiting (ecs);
       return;
       stop_print_frame = 0;
       stop_waiting (ecs);
       return;
@@ -4642,10 +5060,10 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
   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->ptid);
+      ecs->event_thread = find_thread_ptid (ecs->target, ecs->ptid);
       /* If it's a new thread, add it to the thread database.  */
       if (ecs->event_thread == NULL)
       /* If it's a new thread, add it to the thread database.  */
       if (ecs->event_thread == NULL)
-       ecs->event_thread = add_thread (ecs->ptid);
+       ecs->event_thread = add_thread (ecs->target, ecs->ptid);
 
       /* Disable range stepping.  If the next step request could use a
         range, this will be end up re-enabled then.  */
 
       /* Disable range stepping.  If the next step request could use a
         range, this will be end up re-enabled then.  */
@@ -4717,17 +5135,15 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
     else
       mark_ptid = ecs->ptid;
 
     else
       mark_ptid = ecs->ptid;
 
-    set_executing (mark_ptid, 0);
+    set_executing (ecs->target, mark_ptid, 0);
 
     /* Likewise the resumed flag.  */
 
     /* Likewise the resumed flag.  */
-    set_resumed (mark_ptid, 0);
+    set_resumed (ecs->target, mark_ptid, 0);
   }
 
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
   }
 
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
       context_switch (ecs);
       /* Ignore gracefully during startup of the inferior, as it might
          be the shell which has just loaded some objects, otherwise
       context_switch (ecs);
       /* Ignore gracefully during startup of the inferior, as it might
          be the shell which has just loaded some objects, otherwise
@@ -4805,8 +5221,6 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
                      _("unhandled stop_soon: %d"), (int) stop_soon);
 
     case TARGET_WAITKIND_SPURIOUS:
                      _("unhandled stop_soon: %d"), (int) stop_soon);
 
     case TARGET_WAITKIND_SPURIOUS:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
       if (handle_stop_requested (ecs))
        return;
       context_switch (ecs);
       if (handle_stop_requested (ecs))
        return;
       context_switch (ecs);
@@ -4815,8 +5229,6 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
       return;
 
     case TARGET_WAITKIND_THREAD_CREATED:
       return;
 
     case TARGET_WAITKIND_THREAD_CREATED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_CREATED\n");
       if (handle_stop_requested (ecs))
        return;
       context_switch (ecs);
       if (handle_stop_requested (ecs))
        return;
       context_switch (ecs);
@@ -4826,18 +5238,8 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
 
     case TARGET_WAITKIND_EXITED:
     case TARGET_WAITKIND_SIGNALLED:
 
     case TARGET_WAITKIND_EXITED:
     case TARGET_WAITKIND_SIGNALLED:
-      if (debug_infrun)
-       {
-         if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: TARGET_WAITKIND_EXITED\n");
-         else
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: TARGET_WAITKIND_SIGNALLED\n");
-       }
-
       inferior_ptid = ecs->ptid;
       inferior_ptid = ecs->ptid;
-      set_current_inferior (find_inferior_ptid (ecs->ptid));
+      set_current_inferior (find_inferior_ptid (ecs->target, ecs->ptid));
       set_current_program_space (current_inferior ()->pspace);
       handle_vfork_child_exec_or_exit (0);
       target_terminal::ours ();        /* Must do this before mourn anyway.  */
       set_current_program_space (current_inferior ()->pspace);
       handle_vfork_child_exec_or_exit (0);
       target_terminal::ours ();        /* Must do this before mourn anyway.  */
@@ -4900,14 +5302,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          the above cases end in a continue or goto.  */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
          the above cases end in a continue or goto.  */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
-      if (debug_infrun)
-       {
-         if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
-           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
-         else
-           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORKED\n");
-       }
-
       /* Check whether the inferior is displaced stepping.  */
       {
        struct regcache *regcache = get_thread_regcache (ecs->event_thread);
       /* Check whether the inferior is displaced stepping.  */
       {
        struct regcache *regcache = get_thread_regcache (ecs->event_thread);
@@ -4918,7 +5312,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
        if (displaced_step_in_progress_thread (ecs->event_thread))
          {
            struct inferior *parent_inf
        if (displaced_step_in_progress_thread (ecs->event_thread))
          {
            struct inferior *parent_inf
-             = find_inferior_ptid (ecs->ptid);
+             = find_inferior_ptid (ecs->target, ecs->ptid);
            struct regcache *child_regcache;
            CORE_ADDR parent_pc;
 
            struct regcache *child_regcache;
            CORE_ADDR parent_pc;
 
@@ -4949,7 +5343,8 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
               list yet at this point.  */
 
            child_regcache
               list yet at this point.  */
 
            child_regcache
-             = get_thread_arch_aspace_regcache (ecs->ws.value.related_pid,
+             = get_thread_arch_aspace_regcache (parent_inf->process_target (),
+                                                ecs->ws.value.related_pid,
                                                 gdbarch,
                                                 parent_inf->aspace);
            /* Read PC value of parent process.  */
                                                 gdbarch,
                                                 parent_inf->aspace);
            /* Read PC value of parent process.  */
@@ -5017,10 +5412,16 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
 
          ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
 
          ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
+         process_stratum_target *targ
+           = ecs->event_thread->inf->process_target ();
+
          should_resume = follow_fork ();
 
          should_resume = follow_fork ();
 
+         /* Note that one of these may be an invalid pointer,
+            depending on detach_fork.  */
          thread_info *parent = ecs->event_thread;
          thread_info *parent = ecs->event_thread;
-         thread_info *child = find_thread_ptid (ecs->ws.value.related_pid);
+         thread_info *child
+           = find_thread_ptid (targ, ecs->ws.value.related_pid);
 
          /* At this point, the parent is marked running, and the
             child is marked stopped.  */
 
          /* At this point, the parent is marked running, and the
             child is marked stopped.  */
@@ -5068,10 +5469,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       /* Done with the shared memory region.  Re-insert breakpoints in
         the parent, and keep going.  */
 
       /* Done with the shared memory region.  Re-insert breakpoints in
         the parent, and keep going.  */
 
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_VFORK_DONE\n");
-
       context_switch (ecs);
 
       current_inferior ()->waiting_for_vfork_done = 0;
       context_switch (ecs);
 
       current_inferior ()->waiting_for_vfork_done = 0;
@@ -5086,8 +5483,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       return;
 
     case TARGET_WAITKIND_EXECD:
       return;
 
     case TARGET_WAITKIND_EXECD:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
 
       /* Note we can't read registers yet (the stop_pc), because we
         don't yet know the inferior's post-exec architecture.
 
       /* Note we can't read registers yet (the stop_pc), because we
         don't yet know the inferior's post-exec architecture.
@@ -5136,9 +5531,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       /* Be careful not to try to gather much state about a thread
          that's in a syscall.  It's frequently a losing proposition.  */
     case TARGET_WAITKIND_SYSCALL_ENTRY:
       /* Be careful not to try to gather much state about a thread
          that's in a syscall.  It's frequently a losing proposition.  */
     case TARGET_WAITKIND_SYSCALL_ENTRY:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
       /* Getting the current syscall number.  */
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
       /* Getting the current syscall number.  */
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
@@ -5150,22 +5542,15 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          syscall.  Stepping one instruction seems to get it back
          into user code.)  */
     case TARGET_WAITKIND_SYSCALL_RETURN:
          syscall.  Stepping one instruction seems to get it back
          into user code.)  */
     case TARGET_WAITKIND_SYSCALL_RETURN:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
       return;
 
     case TARGET_WAITKIND_STOPPED:
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
       return;
 
     case TARGET_WAITKIND_STOPPED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
       handle_signal_stop (ecs);
       return;
 
     case TARGET_WAITKIND_NO_HISTORY:
       handle_signal_stop (ecs);
       return;
 
     case TARGET_WAITKIND_NO_HISTORY:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
       /* Reverse execution: target ran out of history info.  */
 
       /* Switch to the stopped thread.  */
       /* Reverse execution: target ran out of history info.  */
 
       /* Switch to the stopped thread.  */
@@ -5186,22 +5571,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
     }
 }
 
     }
 }
 
-/* A wrapper around handle_inferior_event_1, which also makes sure
-   that all temporary struct value objects that were created during
-   the handling of the event get deleted at the end.  */
-
-static void
-handle_inferior_event (struct execution_control_state *ecs)
-{
-  struct value *mark = value_mark ();
-
-  handle_inferior_event_1 (ecs);
-  /* Purge all temporary values created during the event handling,
-     as it could be a long time before we return to the command level
-     where such values would otherwise be purged.  */
-  value_free_to_mark (mark);
-}
-
 /* 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.  */
 /* 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.  */
@@ -5214,13 +5583,15 @@ restart_threads (struct thread_info *event_thread)
 
   for (thread_info *tp : all_non_exited_threads ())
     {
 
   for (thread_info *tp : all_non_exited_threads ())
     {
+      switch_to_thread_no_regs (tp);
+
       if (tp == event_thread)
        {
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] is event thread\n",
       if (tp == event_thread)
        {
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] is event thread\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          continue;
        }
 
          continue;
        }
 
@@ -5230,7 +5601,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] not meant to be running\n",
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] not meant to be running\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          continue;
        }
 
          continue;
        }
 
@@ -5239,7 +5610,7 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] resumed\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] resumed\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
          continue;
        }
          gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
          continue;
        }
@@ -5250,7 +5621,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] needs step-over\n",
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] needs step-over\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          gdb_assert (!tp->resumed);
          continue;
        }
          gdb_assert (!tp->resumed);
          continue;
        }
@@ -5262,7 +5633,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] has pending status\n",
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] has pending status\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          tp->resumed = 1;
          continue;
        }
          tp->resumed = 1;
          continue;
        }
@@ -5277,7 +5648,7 @@ restart_threads (struct thread_info *event_thread)
          internal_error (__FILE__, __LINE__,
                          "thread [%s] needs a step-over, but not in "
                          "step-over queue\n",
          internal_error (__FILE__, __LINE__,
                          "thread [%s] needs a step-over, but not in "
                          "step-over queue\n",
-                         target_pid_to_str (tp->ptid));
+                         target_pid_to_str (tp->ptid).c_str ());
        }
 
       if (currently_stepping (tp))
        }
 
       if (currently_stepping (tp))
@@ -5285,7 +5656,7 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] was stepping\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] was stepping\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          keep_going_stepped_thread (tp);
        }
       else
          keep_going_stepped_thread (tp);
        }
       else
@@ -5296,7 +5667,7 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] continuing\n",
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] continuing\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          reset_ecs (ecs, tp);
          switch_to_thread (tp);
          keep_going_pass_signal (ecs);
          reset_ecs (ecs, tp);
          switch_to_thread (tp);
          keep_going_pass_signal (ecs);
@@ -5367,7 +5738,12 @@ finish_step_over (struct execution_control_state *ecs)
       context_switch (ecs);
       insert_breakpoints ();
 
       context_switch (ecs);
       insert_breakpoints ();
 
-      restart_threads (ecs->event_thread);
+      {
+        scoped_restore save_defer_tc
+          = make_scoped_defer_target_commit_resume ();
+        restart_threads (ecs->event_thread);
+      }
+      target_commit_resume ();
 
       /* If we have events pending, go through handle_inferior_event
         again, picking up a pending event at random.  This avoids
 
       /* If we have events pending, go through handle_inferior_event
         again, picking up a pending event at random.  This avoids
@@ -5417,7 +5793,7 @@ finish_step_over (struct execution_control_state *ecs)
                                  "(currently_stepping=%d)\n",
                                  paddress (target_gdbarch (),
                                            tp->suspend.stop_pc),
                                  "(currently_stepping=%d)\n",
                                  paddress (target_gdbarch (),
                                            tp->suspend.stop_pc),
-                                 target_pid_to_str (tp->ptid),
+                                 target_pid_to_str (tp->ptid).c_str (),
                                  currently_stepping (tp));
            }
 
                                  currently_stepping (tp));
            }
 
@@ -5472,9 +5848,8 @@ handle_signal_stop (struct execution_control_state *ecs)
     {
       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
       struct gdbarch *reg_gdbarch = regcache->arch ();
     {
       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
       struct gdbarch *reg_gdbarch = regcache->arch ();
-      scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
 
-      inferior_ptid = ecs->ptid;
+      switch_to_thread (ecs->event_thread);
 
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
                          paddress (reg_gdbarch,
 
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
                          paddress (reg_gdbarch,
@@ -5580,7 +5955,7 @@ handle_signal_stop (struct execution_control_state *ecs)
                  fprintf_unfiltered (gdb_stdlog,
                                      "infrun: [%s] hit another thread's "
                                      "single-step breakpoint\n",
                  fprintf_unfiltered (gdb_stdlog,
                                      "infrun: [%s] hit another thread's "
                                      "single-step breakpoint\n",
-                                     target_pid_to_str (ecs->ptid));
+                                     target_pid_to_str (ecs->ptid).c_str ());
                }
              ecs->hit_singlestep_breakpoint = 1;
            }
                }
              ecs->hit_singlestep_breakpoint = 1;
            }
@@ -5592,7 +5967,7 @@ handle_signal_stop (struct execution_control_state *ecs)
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: [%s] hit its "
                                  "single-step breakpoint\n",
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: [%s] hit its "
                                  "single-step breakpoint\n",
-                                 target_pid_to_str (ecs->ptid));
+                                 target_pid_to_str (ecs->ptid).c_str ());
            }
        }
     }
            }
        }
     }
@@ -5864,7 +6239,7 @@ handle_signal_stop (struct execution_control_state *ecs)
   if (random_signal)
     {
       /* Signal not for debugging purposes.  */
   if (random_signal)
     {
       /* Signal not for debugging purposes.  */
-      struct inferior *inf = find_inferior_ptid (ecs->ptid);
+      struct inferior *inf = find_inferior_ptid (ecs->target, ecs->ptid);
       enum gdb_signal stop_signal = ecs->event_thread->suspend.stop_signal;
 
       if (debug_infrun)
       enum gdb_signal stop_signal = ecs->event_thread->suspend.stop_signal;
 
       if (debug_infrun)
@@ -5962,7 +6337,7 @@ handle_signal_stop (struct execution_control_state *ecs)
          return;
        }
 
          return;
        }
 
-      /* Note: step_resume_breakpoint may be non-NULL.  This occures
+      /* Note: step_resume_breakpoint may be non-NULL.  This occurs
         when either there's a nested signal, or when there's a
         pending signal enabled just as the signal handler returns
         (leaving the inferior at the step-resume-breakpoint without
         when either there's a nested signal, or when there's a
         pending signal enabled just as the signal handler returns
         (leaving the inferior at the step-resume-breakpoint without
@@ -6571,7 +6946,8 @@ process_event_stop_test (struct execution_control_state *ecs)
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
            && !function_name_is_marked_for_skip (ecs->stop_func_name,
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
            && !function_name_is_marked_for_skip (ecs->stop_func_name,
-                                                 tmp_sal))
+                                                 tmp_sal)
+           && !inline_frame_is_marked_for_skip (true, ecs->event_thread))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -6737,7 +7113,14 @@ process_event_stop_test (struct execution_control_state *ecs)
 
          if (call_sal.line == ecs->event_thread->current_line
              && call_sal.symtab == ecs->event_thread->current_symtab)
 
          if (call_sal.line == ecs->event_thread->current_line
              && call_sal.symtab == ecs->event_thread->current_symtab)
-           step_into_inline_frame (ecs->event_thread);
+           {
+             step_into_inline_frame (ecs->event_thread);
+             if (inline_frame_is_marked_for_skip (false, ecs->event_thread))
+               {
+                 keep_going (ecs);
+                 return;
+               }
+           }
 
          end_stepping_range (ecs);
          return;
 
          end_stepping_range (ecs);
          return;
@@ -6771,7 +7154,8 @@ process_event_stop_test (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: stepping through inlined function\n");
 
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: stepping through inlined function\n");
 
-      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL
+         || inline_frame_is_marked_for_skip (false, ecs->event_thread))
        keep_going (ecs);
       else
        end_stepping_range (ecs);
        keep_going (ecs);
       else
        end_stepping_range (ecs);
@@ -6842,7 +7226,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: need to finish step-over of [%s]\n",
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: need to finish step-over of [%s]\n",
-                                 target_pid_to_str (ecs->event_thread->ptid));
+                                 target_pid_to_str (ecs->event_thread->ptid).c_str ());
            }
          keep_going (ecs);
          return 1;
            }
          keep_going (ecs);
          return 1;
@@ -6857,7 +7241,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: need to step [%s] over single-step "
                                 "breakpoint\n",
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: need to step [%s] over single-step "
                                 "breakpoint\n",
-                                target_pid_to_str (ecs->ptid));
+                                target_pid_to_str (ecs->ptid).c_str ());
           }
         keep_going (ecs);
         return 1;
           }
         keep_going (ecs);
         return 1;
@@ -6872,7 +7256,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: thread [%s] still needs step-over\n",
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: thread [%s] still needs step-over\n",
-                                 target_pid_to_str (ecs->event_thread->ptid));
+                                 target_pid_to_str (ecs->event_thread->ptid).c_str ());
            }
          keep_going (ecs);
          return 1;
            }
          keep_going (ecs);
          return 1;
@@ -6908,10 +7292,13 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 
       for (thread_info *tp : all_non_exited_threads ())
         {
 
       for (thread_info *tp : all_non_exited_threads ())
         {
+         switch_to_thread_no_regs (tp);
+
          /* Ignore threads of processes the caller is not
             resuming.  */
          if (!sched_multi
          /* Ignore threads of processes the caller is not
             resuming.  */
          if (!sched_multi
-             && tp->ptid.pid () != ecs->ptid.pid ())
+             && (tp->inf->process_target () != ecs->target
+                 || tp->inf->pid != ecs->ptid.pid ()))
            continue;
 
          /* When stepping over a breakpoint, we lock all threads
            continue;
 
          /* When stepping over a breakpoint, we lock all threads
@@ -6923,7 +7310,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
              internal_error (__FILE__, __LINE__,
                              "[%s] has inconsistent state: "
                              "trap_expected=%d\n",
              internal_error (__FILE__, __LINE__,
                              "[%s] has inconsistent state: "
                              "trap_expected=%d\n",
-                             target_pid_to_str (tp->ptid),
+                             target_pid_to_str (tp->ptid).c_str (),
                              tp->control.trap_expected);
            }
 
                              tp->control.trap_expected);
            }
 
@@ -6959,6 +7346,8 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
              return 1;
            }
        }
              return 1;
            }
        }
+
+      switch_to_thread (ecs->event_thread);
     }
 
   return 0;
     }
 
   return 0;
@@ -7320,14 +7709,14 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
                                    struct frame_info *frame,
                                    struct symbol *sym)
 {
                                    struct frame_info *frame,
                                    struct symbol *sym)
 {
-  TRY
+  try
     {
       struct block_symbol vsym;
       struct value *value;
       CORE_ADDR handler;
       struct breakpoint *bp;
 
     {
       struct block_symbol vsym;
       struct value *value;
       CORE_ADDR handler;
       struct breakpoint *bp;
 
-      vsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+      vsym = lookup_symbol_search_name (sym->search_name (),
                                        b, VAR_DOMAIN);
       value = read_var_value (vsym.symbol, vsym.block, frame);
       /* If the value was optimized out, revert to the old behavior.  */
                                        b, VAR_DOMAIN);
       value = read_var_value (vsym.symbol, vsym.block, frame);
       /* If the value was optimized out, revert to the old behavior.  */
@@ -7351,11 +7740,10 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
          inferior_thread ()->control.exception_resume_breakpoint = bp;
        }
     }
          inferior_thread ()->control.exception_resume_breakpoint = bp;
        }
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
       /* We want to ignore errors here.  */
     }
     {
       /* We want to ignore errors here.  */
     }
-  END_CATCH
 }
 
 /* A helper for check_exception_resume that sets an
 }
 
 /* A helper for check_exception_resume that sets an
@@ -7414,7 +7802,7 @@ check_exception_resume (struct execution_control_state *ecs,
   if (!func)
     return;
 
   if (!func)
     return;
 
-  TRY
+  try
     {
       const struct block *b;
       struct block_iterator iter;
     {
       const struct block *b;
       struct block_iterator iter;
@@ -7451,10 +7839,9 @@ check_exception_resume (struct execution_control_state *ecs,
            }
        }
     }
            }
        }
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
     }
     {
     }
-  END_CATCH
 }
 
 static void
 }
 
 static void
@@ -7493,7 +7880,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: %s has trap_expected set, "
                            "resuming to collect trap\n",
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: %s has trap_expected set, "
                            "resuming to collect trap\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).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
 
       /* We haven't yet gotten our trap, and either: intercepted a
         non-signal event (e.g., a fork); or took a signal which we
@@ -7515,7 +7902,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over already in progress: "
                                "step-over for %s deferred\n",
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over already in progress: "
                                "step-over for %s deferred\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          thread_step_over_chain_enqueue (tp);
        }
       else
          thread_step_over_chain_enqueue (tp);
        }
       else
@@ -7524,7 +7911,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over in progress: "
                                "resume of %s deferred\n",
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over in progress: "
                                "resume of %s deferred\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
        }
     }
   else
        }
     }
   else
@@ -7581,18 +7968,17 @@ keep_going_pass_signal (struct execution_control_state *ecs)
        stop_all_threads ();
 
       /* Stop stepping if inserting breakpoints fails.  */
        stop_all_threads ();
 
       /* Stop stepping if inserting breakpoints fails.  */
-      TRY
+      try
        {
          insert_breakpoints ();
        }
        {
          insert_breakpoints ();
        }
-      CATCH (e, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &e)
        {
          exception_print (gdb_stderr, e);
          stop_waiting (ecs);
          clear_step_over_info ();
          return;
        }
        {
          exception_print (gdb_stderr, e);
          stop_waiting (ecs);
          clear_step_over_info ();
          return;
        }
-      END_CATCH
 
       ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
 
       ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
@@ -7692,31 +8078,26 @@ void
 print_exited_reason (struct ui_out *uiout, int exitstatus)
 {
   struct inferior *inf = current_inferior ();
 print_exited_reason (struct ui_out *uiout, int exitstatus)
 {
   struct inferior *inf = current_inferior ();
-  const char *pidstr = target_pid_to_str (ptid_t (inf->pid));
+  std::string pidstr = target_pid_to_str (ptid_t (inf->pid));
 
   annotate_exited (exitstatus);
   if (exitstatus)
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
 
   annotate_exited (exitstatus);
   if (exitstatus)
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr);
-      uiout->text (") exited with code ");
-      uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
-      uiout->text ("]\n");
+      std::string exit_code_str
+       = string_printf ("0%o", (unsigned int) exitstatus);
+      uiout->message ("[Inferior %s (%s) exited with code %pF]\n",
+                     plongest (inf->num), pidstr.c_str (),
+                     string_field ("exit-code", exit_code_str.c_str ()));
     }
   else
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string
          ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
     }
   else
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string
          ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr);
-      uiout->text (") exited normally]\n");
+      uiout->message ("[Inferior %s (%s) exited normally]\n",
+                     plongest (inf->num), pidstr.c_str ());
     }
 }
 
     }
 }
 
@@ -7748,13 +8129,13 @@ print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
       const char *name;
 
       uiout->text ("\nThread ");
       const char *name;
 
       uiout->text ("\nThread ");
-      uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
+      uiout->field_string ("thread-id", print_thread_id (thr));
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
        {
          uiout->text (" \"");
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
        {
          uiout->text (" \"");
-         uiout->field_fmt ("name", "%s", name);
+         uiout->field_string ("name", name);
          uiout->text ("\"");
        }
     }
          uiout->text ("\"");
        }
     }
@@ -7853,13 +8234,12 @@ print_stop_location (struct target_waitstatus *ws)
 /* See infrun.h.  */
 
 void
 /* See infrun.h.  */
 
 void
-print_stop_event (struct ui_out *uiout)
+print_stop_event (struct ui_out *uiout, bool displays)
 {
   struct target_waitstatus last;
 {
   struct target_waitstatus last;
-  ptid_t last_ptid;
   struct thread_info *tp;
 
   struct thread_info *tp;
 
-  get_last_target_status (&last_ptid, &last);
+  get_last_target_status (nullptr, nullptr, &last);
 
   {
     scoped_restore save_uiout = make_scoped_restore (&current_uiout, uiout);
 
   {
     scoped_restore save_uiout = make_scoped_restore (&current_uiout, uiout);
@@ -7867,7 +8247,8 @@ print_stop_event (struct ui_out *uiout)
     print_stop_location (&last);
 
     /* Display the auto-display expressions.  */
     print_stop_location (&last);
 
     /* Display the auto-display expressions.  */
-    do_displays ();
+    if (displays)
+      do_displays ();
   }
 
   tp = inferior_thread ();
   }
 
   tp = inferior_thread ();
@@ -7977,9 +8358,8 @@ int
 normal_stop (void)
 {
   struct target_waitstatus last;
 normal_stop (void)
 {
   struct target_waitstatus last;
-  ptid_t last_ptid;
 
 
-  get_last_target_status (&last_ptid, &last);
+  get_last_target_status (nullptr, nullptr, &last);
 
   new_stop_id ();
 
 
   new_stop_id ();
 
@@ -7988,10 +8368,10 @@ normal_stop (void)
      frontend/user running state.  A QUIT is an easy exception to see
      here, so do this before any filtered output.  */
 
      frontend/user running state.  A QUIT is an easy exception to see
      here, so do this before any filtered output.  */
 
-  gdb::optional<scoped_finish_thread_state> maybe_finish_thread_state;
+  ptid_t finish_ptid = null_ptid;
 
   if (!non_stop)
 
   if (!non_stop)
-    maybe_finish_thread_state.emplace (minus_one_ptid);
+    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)
     {
@@ -8001,10 +8381,17 @@ normal_stop (void)
         linux-fork.c automatically switches to another fork from
         within target_mourn_inferior.  */
       if (inferior_ptid != null_ptid)
         linux-fork.c automatically switches to another fork from
         within target_mourn_inferior.  */
       if (inferior_ptid != null_ptid)
-       maybe_finish_thread_state.emplace (ptid_t (inferior_ptid.pid ()));
+       finish_ptid = ptid_t (inferior_ptid.pid ());
     }
   else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
     }
   else if (last.kind != TARGET_WAITKIND_NO_RESUMED)
-    maybe_finish_thread_state.emplace (inferior_ptid);
+    finish_ptid = inferior_ptid;
+
+  gdb::optional<scoped_finish_thread_state> maybe_finish_thread_state;
+  if (finish_ptid != null_ptid)
+    {
+      maybe_finish_thread_state.emplace
+       (user_visible_resume_target (finish_ptid), finish_ptid);
+    }
 
   /* As we're presenting a stop, and potentially removing breakpoints,
      update the thread list so we can tell whether there are threads
 
   /* As we're presenting a stop, and potentially removing breakpoints,
      update the thread list so we can tell whether there are threads
@@ -8046,7 +8433,7 @@ normal_stop (void)
        {
          target_terminal::ours_for_output ();
          printf_filtered (_("[Switching to %s]\n"),
        {
          target_terminal::ours_for_output ();
          printf_filtered (_("[Switching to %s]\n"),
-                          target_pid_to_str (inferior_ptid));
+                          target_pid_to_str (inferior_ptid).c_str ());
          annotate_thread_changed ();
        }
       previous_inferior_ptid = inferior_ptid;
          annotate_thread_changed ();
        }
       previous_inferior_ptid = inferior_ptid;
@@ -8113,16 +8500,15 @@ normal_stop (void)
     {
       stop_context saved_context;
 
     {
       stop_context saved_context;
 
-      TRY
+      try
        {
          execute_cmd_pre_hook (stop_command);
        }
        {
          execute_cmd_pre_hook (stop_command);
        }
-      CATCH (ex, RETURN_MASK_ALL)
+      catch (const gdb_exception &ex)
        {
          exception_fprintf (gdb_stderr, ex,
                             "Error while running hook_stop:\n");
        }
        {
          exception_fprintf (gdb_stderr, ex,
                             "Error while running hook_stop:\n");
        }
-      END_CATCH
 
       /* If the stop hook resumes the target, then there's no point in
         trying to notify about the previous stop; its context is
 
       /* If the stop hook resumes the target, then there's no point in
         trying to notify about the previous stop; its context is
@@ -8819,11 +9205,11 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
       /* The point of the try/catch is that if the stack is clobbered,
          walking the stack might encounter a garbage pointer and
          error() trying to dereference it.  */
       /* The point of the try/catch is that if the stack is clobbered,
          walking the stack might encounter a garbage pointer and
          error() trying to dereference it.  */
-      TRY
+      try
        {
          restore_selected_frame (inf_status->selected_frame_id);
        }
        {
          restore_selected_frame (inf_status->selected_frame_id);
        }
-      CATCH (ex, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &ex)
        {
          exception_fprintf (gdb_stderr, ex,
                             "Unable to restore previously selected frame:\n");
        {
          exception_fprintf (gdb_stderr, ex,
                             "Unable to restore previously selected frame:\n");
@@ -8831,7 +9217,6 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
             innermost frame.  */
          select_frame (get_current_frame ());
        }
             innermost frame.  */
          select_frame (get_current_frame ());
        }
-      END_CATCH
     }
 
   delete inf_status;
     }
 
   delete inf_status;
This page took 0.063385 seconds and 4 git commands to generate.