+2020-01-10  Pedro Alves  <palves@redhat.com>
+
+       * gdbthread.h (scoped_restore_current_thread)
+       <dont_restore, restore, m_dont_restore>: Declare.
+       * thread.c (thread_alive): Add assertion.  Return bool.
+       (switch_to_thread_if_alive): New.
+       (prune_threads): Switch inferior/thread.
+       (print_thread_info_1): Switch thread before calling target methods.
+       (scoped_restore_current_thread::restore): New, factored out from
+       ...
+       (scoped_restore_current_thread::~scoped_restore_current_thread):
+       ... this.
+       (scoped_restore_current_thread::scoped_restore_current_thread):
+       Add assertion.
+       (thread_apply_all_command, thread_select): Use
+       switch_to_thread_if_alive.
+       * infrun.c (proceed, restart_threads, handle_signal_stop)
+       (switch_back_to_stepped_thread): Switch current thread before
+       calling target methods.
+
 2020-01-10  Pedro Alves <palves@redhat.com>
 
        * inferior.c (switch_to_inferior_no_thread): New function,
 
     {
       for (thread_info *tp : all_non_exited_threads (resume_ptid))
        {
+         switch_to_thread_no_regs (tp);
+
          /* Ignore the current thread here.  It's handled
             afterwards.  */
          if (tp == cur_thr)
 
          thread_step_over_chain_enqueue (tp);
        }
+
+      switch_to_thread (cur_thr);
     }
 
   /* Enqueue the current thread last, so that we move all other
           Start all other threads that are implicitly resumed too.  */
       for (thread_info *tp : all_non_exited_threads (resume_ptid))
         {
+         switch_to_thread_no_regs (tp);
+
          if (tp->resumed)
            {
              if (debug_infrun)
                                            "infrun:   %s executing, "
                                            "need stop\n",
                                            target_pid_to_str (t->ptid).c_str ());
+                     switch_to_thread_no_regs (t);
                      target_stop (t->ptid);
                      t->stop_requested = 1;
                    }
 
   for (thread_info *tp : all_non_exited_threads ())
     {
+      switch_to_thread_no_regs (tp);
+
       if (tp == event_thread)
        {
          if (debug_infrun)
     {
       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,
 
       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
              return 1;
            }
        }
+
+      switch_to_thread (ecs->event_thread);
     }
 
   return 0;
 
    spawned new threads we haven't heard of yet.  */
 static int threads_executing;
 
-static int thread_alive (struct thread_info *);
-
 /* RAII type used to increase / decrease the refcount of each thread
    in a given list of threads.  */
 
 }
 
 /* Return true if TP is an active thread.  */
-static int
-thread_alive (struct thread_info *tp)
+static bool
+thread_alive (thread_info *tp)
 {
   if (tp->state == THREAD_EXITED)
-    return 0;
-  if (!target_thread_alive (tp->ptid))
-    return 0;
-  return 1;
+    return false;
+
+  /* Ensure we're looking at the right target stack.  */
+  gdb_assert (tp->inf == current_inferior ());
+
+  return target_thread_alive (tp->ptid);
+}
+
+/* Switch to thread TP if it is alive.  Returns true if successfully
+   switched, false otherwise.  */
+
+static bool
+switch_to_thread_if_alive (thread_info *thr)
+{
+  scoped_restore_current_thread restore_thread;
+
+  /* Switch inferior first, so that we're looking at the right target
+     stack.  */
+  switch_to_inferior_no_thread (thr->inf);
+
+  if (thread_alive (thr))
+    {
+      switch_to_thread (thr);
+      restore_thread.dont_restore ();
+      return true;
+    }
+
+  return false;
 }
 
 /* See gdbthreads.h.  */
 void
 prune_threads (void)
 {
+  scoped_restore_current_thread restore_thread;
+
   for (thread_info *tp : all_threads_safe ())
-    if (!thread_alive (tp))
-      delete_thread (tp);
+    {
+      switch_to_inferior_no_thread (tp->inf);
+
+      if (!thread_alive (tp))
+       delete_thread (tp);
+    }
 }
 
 /* See gdbthreads.h.  */
     gdb::optional<ui_out_emit_list> list_emitter;
     gdb::optional<ui_out_emit_table> table_emitter;
 
+    /* We'll be switching threads temporarily below.  */
+    scoped_restore_current_thread restore_thread;
+
     if (uiout->is_mi_like_p ())
       list_emitter.emplace (uiout, "threads");
     else
 
            if (!uiout->is_mi_like_p ())
              {
+               /* Switch inferiors so we're looking at the right
+                  target stack.  */
+               switch_to_inferior_no_thread (tp->inf);
+
                target_id_col_width
                  = std::max (target_id_col_width,
                              thread_target_id_str (tp).size ());
        uiout->table_body ();
       }
 
-    /* We'll be switching threads temporarily.  */
-    scoped_restore_current_thread restore_thread;
-
     for (inferior *inf : all_inferiors ())
       for (thread_info *tp : inf->threads ())
        {
          if (show_global_ids || uiout->is_mi_like_p ())
            uiout->field_signed ("id", tp->global_num);
 
+         /* Switch to the thread (and inferior / target).  */
+         switch_to_thread (tp);
+
          /* For the CLI, we stuff everything into the target-id field.
             This is a gross hack to make the output come out looking
             correct.  The underlying problem here is that ui-out has no
            uiout->text ("(running)\n");
          else
            {
-             /* The switch below puts us at the top of the stack (leaf
+             /* The switch above put us at the top of the stack (leaf
                 frame).  */
-             switch_to_thread (tp);
              print_stack_frame (get_selected_frame (NULL),
                                 /* For MI output, print frame level.  */
                                 uiout->is_mi_like_p (),
       scoped_restore_current_thread restore_thread;
 
       for (thread_info *thr : thr_list_cpy)
-       if (thread_alive (thr))
+       if (switch_to_thread_if_alive (thr))
          thr_try_catch_cmd (thr, cmd, from_tty, flags);
     }
 }
          continue;
        }
 
-      if (!thread_alive (tp))
+      if (!switch_to_thread_if_alive (tp))
        {
          warning (_("Thread %s has terminated."), print_thread_id (tp));
          continue;
 void
 thread_select (const char *tidstr, thread_info *tp)
 {
-  if (!thread_alive (tp))
+  if (!switch_to_thread_if_alive (tp))
     error (_("Thread ID %s has terminated."), tidstr);
 
-  switch_to_thread (tp);
-
   annotate_thread_changed ();
 
   /* Since the current thread may have changed, see if there is any