void
 linux_process_target::arch_setup_thread (thread_info *thread)
 {
-  struct thread_info *saved_thread;
-
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   low_arch_setup ();
-
-  current_thread = saved_thread;
 }
 
 int
 
       /* Delete the execing process and all its threads.  */
       mourn (proc);
-      current_thread = NULL;
+      switch_to_thread (nullptr);
 
       /* Create a new process/lwp/thread.  */
       proc = add_linux_process (event_pid, 0);
 CORE_ADDR
 linux_process_target::get_pc (lwp_info *lwp)
 {
-  struct thread_info *saved_thread;
   struct regcache *regcache;
   CORE_ADDR pc;
 
   if (!low_supports_breakpoints ())
     return 0;
 
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
   regcache = get_thread_regcache (current_thread, 1);
   pc = low_get_pc (regcache);
   if (debug_threads)
     debug_printf ("pc is 0x%lx\n", (long) pc);
 
-  current_thread = saved_thread;
   return pc;
 }
 
 void
 linux_process_target::get_syscall_trapinfo (lwp_info *lwp, int *sysno)
 {
-  struct thread_info *saved_thread;
   struct regcache *regcache;
 
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
   regcache = get_thread_regcache (current_thread, 1);
   low_get_syscall_trapinfo (regcache, sysno);
 
   if (debug_threads)
     debug_printf ("get_syscall_trapinfo sysno %d\n", *sysno);
-
-  current_thread = saved_thread;
 }
 
 void
 {
   CORE_ADDR pc;
   CORE_ADDR sw_breakpoint_pc;
-  struct thread_info *saved_thread;
 #if USE_SIGTRAP_SIGINFO
   siginfo_t siginfo;
 #endif
   sw_breakpoint_pc = pc - low_decr_pc_after_break ();
 
   /* breakpoint_at reads from the current thread.  */
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
 #if USE_SIGTRAP_SIGINFO
   if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
     }
 
   lwp->stop_pc = pc;
-  current_thread = saved_thread;
   return true;
 }
 
       && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
          || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
     {
-      struct thread_info *saved_thread;
       CORE_ADDR pc;
       int discard = 0;
 
 
       pc = get_pc (lp);
 
-      saved_thread = current_thread;
-      current_thread = thread;
+      scoped_restore_current_thread restore_thread;
+      switch_to_thread (thread);
 
       if (pc != lp->stop_pc)
        {
        }
 #endif
 
-      current_thread = saved_thread;
-
       if (discard)
        {
          if (debug_threads)
 bool
 linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
 {
-  struct thread_info *saved_thread;
-
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
   if ((wstat == NULL
        || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
                debug_printf ("Checking whether LWP %ld needs to move out of "
                              "the jump pad...it does\n",
                              lwpid_of (current_thread));
-             current_thread = saved_thread;
 
              return true;
            }
                  "jump pad...no\n",
                  lwpid_of (current_thread));
 
-  current_thread = saved_thread;
   return false;
 }
 
 bool
 linux_process_target::check_stopped_by_watchpoint (lwp_info *child)
 {
-  struct thread_info *saved_thread = current_thread;
-  current_thread = get_lwp_thread (child);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (child));
 
   if (low_stopped_by_watchpoint ())
     {
       child->stopped_data_address = low_stopped_data_address ();
     }
 
-  current_thread = saved_thread;
-
   return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
       child_ptid = ptid_t (lwpid, lwpid);
       child = add_lwp (child_ptid);
       child->stopped = 1;
-      current_thread = child->thread;
+      switch_to_thread (child->thread);
     }
 
   /* If we didn't find a process, one of two things presumably happened:
       *wstatp = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
-      current_thread = event_thread;
+      switch_to_thread (event_thread);
       return lwpid_of (event_thread);
     }
 
 
   gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
 
-  current_thread = event_thread;
+  switch_to_thread (event_thread);
 
   return lwpid_of (event_thread);
 }
       return;
     }
 
-  thread_info *saved_thread = current_thread;
+  scoped_restore_current_thread restore_thread;
 
   stabilizing_threads = 1;
 
 
   stabilizing_threads = 0;
 
-  current_thread = saved_thread;
-
   if (debug_threads)
     {
       thread_stuck = find_thread ([this] (thread_info *thread)
          select_event_lwp (&event_child);
 
          /* current_thread and event_child must stay in sync.  */
-         current_thread = get_lwp_thread (event_child);
+         switch_to_thread (get_lwp_thread (event_child));
 
          event_child->status_pending_p = 0;
          w = event_child->status_pending;
 void
 linux_process_target::move_out_of_jump_pad (thread_info *thread)
 {
-  struct thread_info *saved_thread;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int *wstat;
 
   gdb_assert (lwp->stopped);
 
   /* For gdb_breakpoint_here.  */
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   wstat = lwp->status_pending_p ? &lwp->status_pending : NULL;
 
     }
   else
     lwp_suspended_inc (lwp);
-
-  current_thread = saved_thread;
 }
 
 static bool
   struct thread_info *thread = get_lwp_thread (lwp);
   struct regcache *regcache = get_thread_regcache (thread, 1);
 
-  scoped_restore save_current_thread = make_scoped_restore (¤t_thread);
+  scoped_restore_current_thread restore_thread;
 
-  current_thread = thread;
+  switch_to_thread (thread);
   std::vector<CORE_ADDR> next_pcs = low_get_next_pcs (regcache);
 
   for (CORE_ADDR pc : next_pcs)
                                            int signal, siginfo_t *info)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
-  struct thread_info *saved_thread;
   int ptrace_request;
   struct process_info *proc = get_thread_process (thread);
 
       return;
     }
 
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
             of coercing an 8 byte integer to a 4 byte pointer.  */
          (PTRACE_TYPE_ARG4) (uintptr_t) signal);
 
-  current_thread = saved_thread;
   if (errno)
     perror_with_name ("resuming thread");
 
 linux_process_target::thread_needs_step_over (thread_info *thread)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
-  struct thread_info *saved_thread;
   CORE_ADDR pc;
   struct process_info *proc = get_thread_process (thread);
 
       return false;
     }
 
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   /* We can only step over breakpoints we know about.  */
   if (breakpoint_here (pc) || fast_tracepoint_jump_here (pc))
                          " GDB breakpoint at 0x%s; skipping step over\n",
                          lwpid_of (thread), paddress (pc));
 
-         current_thread = saved_thread;
          return false;
        }
       else
 
          /* We've found an lwp that needs stepping over --- return 1 so
             that find_thread stops looking.  */
-         current_thread = saved_thread;
-
          return true;
        }
     }
 
-  current_thread = saved_thread;
-
   if (debug_threads)
     debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
                  " at 0x%s\n",
 linux_process_target::start_step_over (lwp_info *lwp)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
-  struct thread_info *saved_thread;
   CORE_ADDR pc;
-  int step;
 
   if (debug_threads)
     debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
      shouldn't care about.  */
   pc = get_pc (lwp);
 
-  saved_thread = current_thread;
-  current_thread = thread;
-
-  lwp->bp_reinsert = pc;
-  uninsert_breakpoints_at (pc);
-  uninsert_fast_tracepoint_jumps_at (pc);
+  bool step = false;
+  {
+    scoped_restore_current_thread restore_thread;
+    switch_to_thread (thread);
 
-  step = single_step (lwp);
+    lwp->bp_reinsert = pc;
+    uninsert_breakpoints_at (pc);
+    uninsert_fast_tracepoint_jumps_at (pc);
 
-  current_thread = saved_thread;
+    step = single_step (lwp);
+  }
 
   resume_one_lwp (lwp, step, 0, NULL);
 
 {
   if (lwp->bp_reinsert != 0)
     {
-      struct thread_info *saved_thread = current_thread;
+      scoped_restore_current_thread restore_thread;
 
       if (debug_threads)
        debug_printf ("Finished step over.\n");
 
-      current_thread = get_lwp_thread (lwp);
+      switch_to_thread (get_lwp_thread (lwp));
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
         may be no breakpoint to reinsert there by now.  */
        }
 
       step_over_bkpt = null_ptid;
-      current_thread = saved_thread;
       return true;
     }
   else