]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdbserver/linux-low.cc
gdb, gdbserver, gdbsupport: fix whitespace issues
[thirdparty/binutils-gdb.git] / gdbserver / linux-low.cc
index bde6c767e87e4e8b1d7f4f702a21610429e52df4..e6a39202a98af314738aa6a46c7f091e1c298424 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995-2020 Free Software Foundation, Inc.
+   Copyright (C) 1995-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +21,8 @@
 #include "nat/linux-osdata.h"
 #include "gdbsupport/agent.h"
 #include "tdesc.h"
+#include "gdbsupport/event-loop.h"
+#include "gdbsupport/event-pipe.h"
 #include "gdbsupport/rsp-low.h"
 #include "gdbsupport/signals-state-save-restore.h"
 #include "nat/linux-nat.h"
 #endif
 #include "nat/linux-namespaces.h"
 
-#ifdef HAVE_PERSONALITY
-# include <sys/personality.h>
-# if !HAVE_DECL_ADDR_NO_RANDOMIZE
-#  define ADDR_NO_RANDOMIZE 0x0040000
-# endif
-#endif
-
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
@@ -140,6 +135,15 @@ typedef struct
 /* Does the current host support PTRACE_GETREGSET?  */
 int have_ptrace_getregset = -1;
 
+/* Return TRUE if THREAD is the leader thread of the process.  */
+
+static bool
+is_leader (thread_info *thread)
+{
+  ptid_t ptid = ptid_of (thread);
+  return ptid.pid () == ptid.lwp ();
+}
+
 /* LWP accessors.  */
 
 /* See nat/linux-nat.h.  */
@@ -206,7 +210,7 @@ struct simple_pid_list
   /* Next in chain.  */
   struct simple_pid_list *next;
 };
-struct simple_pid_list *stopped_pids;
+static struct simple_pid_list *stopped_pids;
 
 /* Trivial list manipulation functions to keep track of a list of new
    stopped processes.  */
@@ -253,7 +257,7 @@ enum stopping_threads_kind
   };
 
 /* This is set while stop_all_lwps is in effect.  */
-enum stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
+static stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
 
 /* FIXME make into a target method?  */
 int using_threads = 1;
@@ -272,7 +276,7 @@ static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 
 /* When the event-loop is doing a step-over, this points at the thread
    being stepped.  */
-ptid_t step_over_bkpt;
+static ptid_t step_over_bkpt;
 
 bool
 linux_process_target::low_supports_breakpoints ()
@@ -315,19 +319,11 @@ lwp_in_step_range (struct lwp_info *lwp)
   return (pc >= lwp->step_range_start && pc < lwp->step_range_end);
 }
 
-struct pending_signals
-{
-  int signal;
-  siginfo_t info;
-  struct pending_signals *prev;
-};
-
-/* The read/write ends of the pipe registered as waitable file in the
-   event loop.  */
-static int linux_event_pipe[2] = { -1, -1 };
+/* The event pipe registered as a waitable file in the event loop.  */
+static event_pipe linux_event_pipe;
 
 /* True if we're currently in async mode.  */
-#define target_is_async_p() (linux_event_pipe[0] != -1)
+#define target_is_async_p() (linux_event_pipe.is_open ())
 
 static void send_sigstop (struct lwp_info *lwp);
 
@@ -390,14 +386,13 @@ linux_process_target::delete_lwp (lwp_info *lwp)
 {
   struct thread_info *thr = get_lwp_thread (lwp);
 
-  if (debug_threads)
-    debug_printf ("deleting %ld\n", lwpid_of (thr));
+  threads_debug_printf ("deleting %ld", lwpid_of (thr));
 
   remove_thread (thr);
 
   low_delete_thread (lwp->arch_private);
 
-  free (lwp);
+  delete lwp;
 }
 
 void
@@ -408,8 +403,22 @@ linux_process_target::low_delete_thread (arch_lwp_info *info)
   gdb_assert (info == nullptr);
 }
 
+/* Open the /proc/PID/mem file for PROC.  */
+
+static void
+open_proc_mem_file (process_info *proc)
+{
+  gdb_assert (proc->priv->mem_fd == -1);
+
+  char filename[64];
+  xsnprintf (filename, sizeof filename, "/proc/%d/mem", proc->pid);
+
+  proc->priv->mem_fd
+    = gdb_open_cloexec (filename, O_RDWR | O_LARGEFILE, 0).release ();
+}
+
 process_info *
-linux_process_target::add_linux_process (int pid, int attached)
+linux_process_target::add_linux_process_no_mem_file (int pid, int attached)
 {
   struct process_info *proc;
 
@@ -417,10 +426,34 @@ linux_process_target::add_linux_process (int pid, int attached)
   proc->priv = XCNEW (struct process_info_private);
 
   proc->priv->arch_private = low_new_process ();
+  proc->priv->mem_fd = -1;
+
+  return proc;
+}
+
 
+process_info *
+linux_process_target::add_linux_process (int pid, int attached)
+{
+  process_info *proc = add_linux_process_no_mem_file (pid, attached);
+  open_proc_mem_file (proc);
   return proc;
 }
 
+void
+linux_process_target::remove_linux_process (process_info *proc)
+{
+  if (proc->priv->mem_fd >= 0)
+    close (proc->priv->mem_fd);
+
+  this->low_delete_process (proc->priv->arch_private);
+
+  xfree (proc->priv);
+  proc->priv = nullptr;
+
+  remove_process (proc);
+}
+
 arch_process_info *
 linux_process_target::low_new_process ()
 {
@@ -444,14 +477,10 @@ linux_process_target::low_new_fork (process_info *parent, process_info *child)
 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
@@ -464,7 +493,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
   struct thread_info *event_thr = get_lwp_thread (event_lwp);
   struct lwp_info *new_lwp;
 
-  gdb_assert (event_lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (event_lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   /* All extended events we currently use are mid-syscall.  Only
      PTRACE_EVENT_STOP is delivered more like a signal-stop, but
@@ -504,17 +533,13 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
          struct process_info *child_proc;
          struct lwp_info *child_lwp;
          struct thread_info *child_thr;
-         struct target_desc *tdesc;
 
-         ptid = ptid_t (new_pid, new_pid, 0);
+         ptid = ptid_t (new_pid, new_pid);
 
-         if (debug_threads)
-           {
-             debug_printf ("HEW: Got fork event from LWP %ld, "
-                           "new child is %d\n",
-                           ptid_of (event_thr).lwp (),
-                           ptid.pid ());
-           }
+         threads_debug_printf ("Got fork event from LWP %ld, "
+                               "new child is %d",
+                               ptid_of (event_thr).lwp (),
+                               ptid.pid ());
 
          /* Add the new process to the tables and clone the breakpoint
             lists of the parent.  We need to do this even if the new process
@@ -530,7 +555,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
          child_lwp->status_pending_p = 0;
          child_thr = get_lwp_thread (child_lwp);
          child_thr->last_resume_kind = resume_stop;
-         child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
+         child_thr->last_status.set_stopped (GDB_SIGNAL_0);
 
          /* If we're suspending all threads, leave this one suspended
             too.  If the fork/clone parent is stepping over a breakpoint,
@@ -539,8 +564,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
          if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
              || event_lwp->bp_reinsert != 0)
            {
-             if (debug_threads)
-               debug_printf ("HEW: leaving child suspended\n");
+             threads_debug_printf ("leaving child suspended");
              child_lwp->suspended = 1;
            }
 
@@ -560,20 +584,18 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
 
          clone_all_breakpoints (child_thr, event_thr);
 
-         tdesc = allocate_target_description ();
-         copy_target_description (tdesc, parent_proc->tdesc);
-         child_proc->tdesc = tdesc;
+         target_desc_up tdesc = allocate_target_description ();
+         copy_target_description (tdesc.get (), parent_proc->tdesc);
+         child_proc->tdesc = tdesc.release ();
 
          /* Clone arch-specific process data.  */
          low_new_fork (parent_proc, child_proc);
 
          /* Save fork info in the parent thread.  */
          if (event == PTRACE_EVENT_FORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_FORKED;
+           event_lwp->waitstatus.set_forked (ptid);
          else if (event == PTRACE_EVENT_VFORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORKED;
-
-         event_lwp->waitstatus.value.related_pid = ptid;
+           event_lwp->waitstatus.set_vforked (ptid);
 
          /* The status_pending field contains bits denoting the
             extended event, so when the pending event is handled,
@@ -607,12 +629,11 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
          return 0;
        }
 
-      if (debug_threads)
-       debug_printf ("HEW: Got clone event "
-                     "from LWP %ld, new child is LWP %ld\n",
-                     lwpid_of (event_thr), new_pid);
+      threads_debug_printf
+       ("Got clone event from LWP %ld, new child is LWP %ld",
+        lwpid_of (event_thr), new_pid);
 
-      ptid = ptid_t (pid_of (event_thr), new_pid, 0);
+      ptid = ptid_t (pid_of (event_thr), new_pid);
       new_lwp = add_lwp (ptid);
 
       /* Either we're going to immediately resume the new thread
@@ -640,7 +661,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
        }
       else if (cs.report_thread_events)
        {
-         new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+         new_lwp->waitstatus.set_thread_created ();
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
@@ -654,7 +675,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
     }
   else if (event == PTRACE_EVENT_VFORK_DONE)
     {
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
+      event_lwp->waitstatus.set_vfork_done ();
 
       if (event_lwp->bp_reinsert != 0 && supports_software_single_step ())
        {
@@ -673,11 +694,8 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
       ptid_t event_ptid;
       pid_t event_pid;
 
-      if (debug_threads)
-       {
-         debug_printf ("HEW: Got exec event from LWP %ld\n",
-                       lwpid_of (event_thr));
-       }
+      threads_debug_printf ("Got exec event from LWP %ld",
+                           lwpid_of (event_thr));
 
       /* Get the event ptid.  */
       event_ptid = ptid_of (event_thr);
@@ -689,7 +707,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
 
       /* 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);
@@ -699,16 +717,16 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
       arch_setup_thread (event_thr);
 
       /* Set the event status.  */
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_EXECD;
-      event_lwp->waitstatus.value.execd_pathname
-       = xstrdup (linux_proc_pid_to_exec_file (lwpid_of (event_thr)));
+      event_lwp->waitstatus.set_execd
+       (make_unique_xstrdup
+          (linux_proc_pid_to_exec_file (lwpid_of (event_thr))));
 
       /* Mark the exec status as pending.  */
       event_lwp->stopped = 1;
       event_lwp->status_pending_p = 1;
       event_lwp->status_pending = wstat;
       event_thr->last_resume_kind = resume_continue;
-      event_thr->last_status.kind = TARGET_WAITKIND_IGNORE;
+      event_thr->last_status.set_ignore ();
 
       /* Update syscall state in the new lwp, effectively mid-syscall too.  */
       event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY;
@@ -723,48 +741,41 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
       return 0;
     }
 
-  internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event);
+  internal_error (_("unknown ptrace event %d"), event);
 }
 
 CORE_ADDR
 linux_process_target::get_pc (lwp_info *lwp)
 {
-  struct thread_info *saved_thread;
-  struct regcache *regcache;
-  CORE_ADDR pc;
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  gdb_assert (!proc->starting_up);
 
   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);
+  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  CORE_ADDR pc = low_get_pc (regcache);
 
-  if (debug_threads)
-    debug_printf ("pc is 0x%lx\n", (long) pc);
+  threads_debug_printf ("pc is 0x%lx", (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;
+  threads_debug_printf ("get_syscall_trapinfo sysno %d", *sysno);
 }
 
 void
@@ -779,7 +790,6 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
 {
   CORE_ADDR pc;
   CORE_ADDR sw_breakpoint_pc;
-  struct thread_info *saved_thread;
 #if USE_SIGTRAP_SIGINFO
   siginfo_t siginfo;
 #endif
@@ -787,12 +797,20 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
   if (!low_supports_breakpoints ())
     return false;
 
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  if (proc->starting_up)
+    {
+      /* Claim we have the stop PC so that the caller doesn't try to
+        fetch it itself.  */
+      return true;
+    }
+
   pc = get_pc (lwp);
   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),
@@ -854,13 +872,9 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
 
   if (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
     {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by software breakpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
+      threads_debug_printf
+       ("%s stopped by software breakpoint",
+        target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
 
       /* Back up the PC if necessary.  */
       if (pc != sw_breakpoint_pc)
@@ -874,49 +888,26 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
       pc = sw_breakpoint_pc;
     }
   else if (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by hardware breakpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by hardware breakpoint",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
   else if (lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by hardware watchpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by hardware watchpoint",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
   else if (lwp->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by trace\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by trace",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
 
   lwp->stop_pc = pc;
-  current_thread = saved_thread;
   return true;
 }
 
 lwp_info *
 linux_process_target::add_lwp (ptid_t ptid)
 {
-  struct lwp_info *lwp;
-
-  lwp = XCNEW (struct lwp_info);
-
-  lwp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+  lwp_info *lwp = new lwp_info;
 
   lwp->thread = add_thread (ptid, lwp);
 
@@ -987,14 +978,22 @@ linux_process_target::create_inferior (const char *program,
                         NULL, NULL, NULL, NULL);
   }
 
-  add_linux_process (pid, 0);
+  /* When spawning a new process, we can't open the mem file yet.  We
+     still have to nurse the process through the shell, and that execs
+     a couple times.  The address space a /proc/PID/mem file is
+     accessing is destroyed on exec.  */
+  process_info *proc = add_linux_process_no_mem_file (pid, 0);
 
-  ptid = ptid_t (pid, pid, 0);
+  ptid = ptid_t (pid, pid);
   new_lwp = add_lwp (ptid);
   new_lwp->must_set_ptrace_flags = 1;
 
   post_fork_inferior (pid, program);
 
+  /* PROC is now past the shell running the program we want, so we can
+     open the /proc/PID/mem file.  */
+  open_proc_mem_file (proc);
+
   return pid;
 }
 
@@ -1035,8 +1034,7 @@ linux_process_target::attach_lwp (ptid_t ptid)
 
   if (linux_proc_pid_is_stopped (lwpid))
     {
-      if (debug_threads)
-       debug_printf ("Attached to a stopped process\n");
+      threads_debug_printf ("Attached to a stopped process");
 
       /* The process is definitely stopped.  It is in a job control
         stop, unless the kernel predates the TASK_STOPPED /
@@ -1112,8 +1110,7 @@ attach_proc_task_lwp_callback (ptid_t ptid)
       int lwpid = ptid.lwp ();
       int err;
 
-      if (debug_threads)
-       debug_printf ("Found new lwp %d\n", lwpid);
+      threads_debug_printf ("Found new lwp %d", lwpid);
 
       err = the_linux_target->attach_lwp (ptid);
 
@@ -1123,14 +1120,9 @@ attach_proc_task_lwp_callback (ptid_t ptid)
         case, confirm the status in /proc/PID/status.  */
       if (err == ESRCH
          || (err == EPERM && linux_proc_pid_is_gone (lwpid)))
-       {
-         if (debug_threads)
-           {
-             debug_printf ("Cannot attach to lwp %d: "
-                           "thread is gone (%d: %s)\n",
-                           lwpid, err, safe_strerror (err));
-           }
-       }
+       threads_debug_printf
+         ("Cannot attach to lwp %d: thread is gone (%d: %s)",
+          lwpid, err, safe_strerror (err));
       else if (err != 0)
        {
          std::string reason
@@ -1154,25 +1146,29 @@ linux_process_target::attach (unsigned long pid)
 {
   struct process_info *proc;
   struct thread_info *initial_thread;
-  ptid_t ptid = ptid_t (pid, pid, 0);
+  ptid_t ptid = ptid_t (pid, pid);
   int err;
 
-  proc = add_linux_process (pid, 1);
+  /* Delay opening the /proc/PID/mem file until we've successfully
+     attached.  */
+  proc = add_linux_process_no_mem_file (pid, 1);
 
   /* Attach to PID.  We will check for other threads
      soon.  */
   err = attach_lwp (ptid);
   if (err != 0)
     {
-      remove_process (proc);
+      this->remove_linux_process (proc);
 
       std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
       error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
     }
 
+  open_proc_mem_file (proc);
+
   /* Don't ignore the initial SIGSTOP if we just attached to this
      process.  It will be collected by wait shortly.  */
-  initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
+  initial_thread = find_thread_ptid (ptid_t (pid, pid));
   initial_thread->last_resume_kind = resume_stop;
 
   /* We must attach to every LWP.  If /proc is mounted, use that to
@@ -1269,9 +1265,9 @@ linux_kill_one_lwp (struct lwp_info *lwp)
     {
       int save_errno = errno;
 
-      debug_printf ("LKL:  kill_lwp (SIGKILL) %s, 0, 0 (%s)\n",
-                   target_pid_to_str (ptid_of (thr)),
-                   save_errno ? safe_strerror (save_errno) : "OK");
+      threads_debug_printf ("kill_lwp (SIGKILL) %s, 0, 0 (%s)",
+                           target_pid_to_str (ptid_of (thr)).c_str (),
+                           save_errno ? safe_strerror (save_errno) : "OK");
     }
 
   errno = 0;
@@ -1280,9 +1276,9 @@ linux_kill_one_lwp (struct lwp_info *lwp)
     {
       int save_errno = errno;
 
-      debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-                   target_pid_to_str (ptid_of (thr)),
-                   save_errno ? safe_strerror (save_errno) : "OK");
+      threads_debug_printf ("PTRACE_KILL %s, 0, 0 (%s)",
+                           target_pid_to_str (ptid_of (thr)).c_str (),
+                           save_errno ? safe_strerror (save_errno) : "OK");
     }
 }
 
@@ -1297,8 +1293,7 @@ kill_wait_lwp (struct lwp_info *lwp)
   int wstat;
   int res;
 
-  if (debug_threads)
-    debug_printf ("kwl: killing lwp %d, for pid: %d\n", lwpid, pid);
+  threads_debug_printf ("killing lwp %d, for pid: %d", lwpid, pid);
 
   do
     {
@@ -1344,9 +1339,8 @@ kill_one_lwp_callback (thread_info *thread, int pid)
 
   if (lwpid_of (thread) == pid)
     {
-      if (debug_threads)
-       debug_printf ("lkop: is last of process %s\n",
-                     target_pid_to_str (thread->id));
+      threads_debug_printf ("is last of process %s",
+                           target_pid_to_str (thread->id).c_str ());
       return;
     }
 
@@ -1372,11 +1366,7 @@ linux_process_target::kill (process_info *process)
   lwp_info *lwp = find_lwp_pid (ptid_t (pid));
 
   if (lwp == NULL)
-    {
-      if (debug_threads)
-       debug_printf ("lk_1: cannot find lwp for pid: %d\n",
-                     pid);
-    }
+    threads_debug_printf ("cannot find lwp for pid: %d", pid);
   else
     kill_wait_lwp (lwp);
 
@@ -1407,8 +1397,8 @@ get_detach_signal (struct thread_info *thread)
       /* If the thread had been suspended by gdbserver, and it stopped
         cleanly, then it'll have stopped with SIGSTOP.  But we don't
         want to deliver that SIGSTOP.  */
-      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-         || thread->last_status.value.sig == GDB_SIGNAL_0)
+      if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED
+         || thread->last_status.sig () == GDB_SIGNAL_0)
        return 0;
 
       /* Otherwise, we may need to deliver the signal we
@@ -1418,19 +1408,17 @@ get_detach_signal (struct thread_info *thread)
 
   if (!WIFSTOPPED (status))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("lwp %s hasn't stopped: no pending signal",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
       return 0;
     }
 
   /* Extended wait statuses aren't real SIGTRAPs.  */
   if (WSTOPSIG (status) == SIGTRAP && linux_is_extended_waitstatus (status))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had stopped with extended "
-                     "status: no pending signal\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("lwp %s had stopped with extended "
+                           "status: no pending signal",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
       return 0;
     }
 
@@ -1438,10 +1426,9 @@ get_detach_signal (struct thread_info *thread)
 
   if (cs.program_signals_p && !cs.program_signals[signo])
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s had signal %s, but it is in nopass state",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
       return 0;
     }
   else if (!cs.program_signals_p
@@ -1450,20 +1437,18 @@ get_detach_signal (struct thread_info *thread)
              SIGTRAP/SIGINT, which is GDB's default.  */
           && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had signal %s, "
-                     "but we don't know if we should pass it. "
-                     "Default to not.\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s had signal %s, "
+                           "but we don't know if we should pass it. "
+                           "Default to not.",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s has pending signal %s: delivering it",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
@@ -1479,9 +1464,8 @@ linux_process_target::detach_one_lwp (lwp_info *lwp)
   /* If there is a pending SIGSTOP, get rid of it.  */
   if (lwp->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Sending SIGCONT to %s\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("Sending SIGCONT to %s",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
 
       kill_lwp (lwpid_of (thread), SIGCONT);
       lwp->stop_expected = 0;
@@ -1537,16 +1521,14 @@ linux_process_target::detach_one_lwp (lwp_info *lwp)
       else
        {
          error (_("Can't detach %s: %s"),
-                target_pid_to_str (ptid_of (thread)),
+                target_pid_to_str (ptid_of (thread)).c_str (),
                 safe_strerror (save_errno));
        }
     }
-  else if (debug_threads)
-    {
-      debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)\n",
-                   target_pid_to_str (ptid_of (thread)),
-                   strsignal (sig));
-    }
+  else
+    threads_debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)",
+                         target_pid_to_str (ptid_of (thread)).c_str (),
+                         strsignal (sig));
 
   delete_lwp (lwp);
 }
@@ -1605,8 +1587,6 @@ linux_process_target::detach (process_info *process)
 void
 linux_process_target::mourn (process_info *process)
 {
-  struct process_info_private *priv;
-
 #ifdef USE_THREAD_DB
   thread_db_mourn (process);
 #endif
@@ -1616,13 +1596,7 @@ linux_process_target::mourn (process_info *process)
       delete_lwp (get_thread_lwp (thread));
     });
 
-  /* Freeing all private data.  */
-  priv = process->priv;
-  low_delete_process (priv->arch_private);
-  free (priv);
-  process->priv = NULL;
-
-  remove_process (process);
+  this->remove_linux_process (process);
 }
 
 void
@@ -1665,7 +1639,6 @@ linux_process_target::thread_still_has_status_pending (thread_info *thread)
       && (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;
 
@@ -1673,14 +1646,13 @@ linux_process_target::thread_still_has_status_pending (thread_info *thread)
 
       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)
        {
-         if (debug_threads)
-           debug_printf ("PC of %ld changed\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("PC of %ld changed",
+                               lwpid_of (thread));
          discard = 1;
        }
 
@@ -1688,27 +1660,22 @@ linux_process_target::thread_still_has_status_pending (thread_info *thread)
       else if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
               && !low_breakpoint_at (pc))
        {
-         if (debug_threads)
-           debug_printf ("previous SW breakpoint of %ld gone\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("previous SW breakpoint of %ld gone",
+                               lwpid_of (thread));
          discard = 1;
        }
       else if (lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT
               && !hardware_breakpoint_inserted_here (pc))
        {
-         if (debug_threads)
-           debug_printf ("previous HW breakpoint of %ld gone\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("previous HW breakpoint of %ld gone",
+                               lwpid_of (thread));
          discard = 1;
        }
 #endif
 
-      current_thread = saved_thread;
-
       if (discard)
        {
-         if (debug_threads)
-           debug_printf ("discarding pending breakpoint status\n");
+         threads_debug_printf ("discarding pending breakpoint status");
          lp->status_pending_p = 0;
          return 0;
        }
@@ -1731,7 +1698,7 @@ lwp_resumed (struct lwp_info *lwp)
      corresponding stop to gdb yet?  If so, the thread is still
      resumed/running from gdb's perspective.  */
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     return 1;
 
   return 0;
@@ -1764,9 +1731,9 @@ linux_process_target::status_pending_p_callback (thread_info *thread,
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  thread_info *thread = find_thread ([&] (thread_info *thr_arg)
+  long lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+  thread_info *thread = find_thread ([lwp] (thread_info *thr_arg)
     {
-      int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
       return thr_arg->id.lwp () == lwp;
     });
 
@@ -1813,59 +1780,77 @@ iterate_over_lwps (ptid_t filter,
 void
 linux_process_target::check_zombie_leaders ()
 {
-  for_each_process ([this] (process_info *proc) {
-    pid_t leader_pid = pid_of (proc);
-    struct lwp_info *leader_lp;
-
-    leader_lp = find_lwp_pid (ptid_t (leader_pid));
-
-    if (debug_threads)
-      debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
-                   "num_lwps=%d, zombie=%d\n",
-                   leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
-                   linux_proc_pid_is_zombie (leader_pid));
-
-    if (leader_lp != NULL && !leader_lp->stopped
-       /* Check if there are other threads in the group, as we may
-          have raced with the inferior simply exiting.  */
-       && !last_thread_of_process_p (leader_pid)
-       && linux_proc_pid_is_zombie (leader_pid))
-      {
-       /* A leader zombie can mean one of two things:
-
-          - It exited, and there's an exit status pending
-          available, or only the leader exited (not the whole
-          program).  In the latter case, we can't waitpid the
-          leader's exit status until all other threads are gone.
-
-          - There are 3 or more threads in the group, and a thread
-          other than the leader exec'd.  On an exec, the Linux
-          kernel destroys all other threads (except the execing
-          one) in the thread group, and resets the execing thread's
-          tid to the tgid.  No exit notification is sent for the
-          execing thread -- from the ptracer's perspective, it
-          appears as though the execing thread just vanishes.
-          Until we reap all other threads except the leader and the
-          execing thread, the leader will be zombie, and the
-          execing thread will be in `D (disc sleep)'.  As soon as
-          all other threads are reaped, the execing thread changes
-          it's tid to the tgid, and the previous (zombie) leader
-          vanishes, giving place to the "new" leader.  We could try
-          distinguishing the exit and exec cases, by waiting once
-          more, and seeing if something comes out, but it doesn't
-          sound useful.  The previous leader _does_ go away, and
-          we'll re-add the new one once we see the exec event
-          (which is just the same as what would happen if the
-          previous leader did exit voluntarily before some other
-          thread execs).  */
-
-       if (debug_threads)
-         debug_printf ("CZL: Thread group leader %d zombie "
-                       "(it exited, or another thread execd).\n",
-                       leader_pid);
-
-       delete_lwp (leader_lp);
-      }
+  for_each_process ([this] (process_info *proc)
+    {
+      pid_t leader_pid = pid_of (proc);
+      lwp_info *leader_lp = find_lwp_pid (ptid_t (leader_pid));
+
+      threads_debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
+                           "num_lwps=%d, zombie=%d",
+                           leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
+                           linux_proc_pid_is_zombie (leader_pid));
+
+      if (leader_lp != NULL && !leader_lp->stopped
+         /* Check if there are other threads in the group, as we may
+            have raced with the inferior simply exiting.  Note this
+            isn't a watertight check.  If the inferior is
+            multi-threaded and is exiting, it may be we see the
+            leader as zombie before we reap all the non-leader
+            threads.  See comments below.  */
+         && !last_thread_of_process_p (leader_pid)
+         && linux_proc_pid_is_zombie (leader_pid))
+       {
+         /* A zombie leader in a multi-threaded program can mean one
+            of three things:
+
+            #1 - Only the leader exited, not the whole program, e.g.,
+            with pthread_exit.  Since we can't reap the leader's exit
+            status until all other threads are gone and reaped too,
+            we want to delete the zombie leader right away, as it
+            can't be debugged, we can't read its registers, etc.
+            This is the main reason we check for zombie leaders
+            disappearing.
+
+            #2 - The whole thread-group/process exited (a group exit,
+            via e.g. exit(3), and there is (or will be shortly) an
+            exit reported for each thread in the process, and then
+            finally an exit for the leader once the non-leaders are
+            reaped.
+
+            #3 - There are 3 or more threads in the group, and a
+            thread other than the leader exec'd.  See comments on
+            exec events at the top of the file.
+
+            Ideally we would never delete the leader for case #2.
+            Instead, we want to collect the exit status of each
+            non-leader thread, and then finally collect the exit
+            status of the leader as normal and use its exit code as
+            whole-process exit code.  Unfortunately, there's no
+            race-free way to distinguish cases #1 and #2.  We can't
+            assume the exit events for the non-leaders threads are
+            already pending in the kernel, nor can we assume the
+            non-leader threads are in zombie state already.  Between
+            the leader becoming zombie and the non-leaders exiting
+            and becoming zombie themselves, there's a small time
+            window, so such a check would be racy.  Temporarily
+            pausing all threads and checking to see if all threads
+            exit or not before re-resuming them would work in the
+            case that all threads are running right now, but it
+            wouldn't work if some thread is currently already
+            ptrace-stopped, e.g., due to scheduler-locking.
+
+            So what we do is we delete the leader anyhow, and then
+            later on when we see its exit status, we re-add it back.
+            We also make sure that we only report a whole-process
+            exit when we see the leader exiting, as opposed to when
+            the last LWP in the LWP list exits, which can be a
+            non-leader if we deleted the leader here.  */
+         threads_debug_printf ("Thread group leader %d zombie "
+                               "(it exited, or another thread execd), "
+                               "deleting it.",
+                               leader_pid);
+         delete_lwp (leader_lp);
+       }
     });
 }
 
@@ -1890,13 +1875,10 @@ lwp_suspended_inc (struct lwp_info *lwp)
 {
   lwp->suspended++;
 
-  if (debug_threads && lwp->suspended > 4)
-    {
-      struct thread_info *thread = get_lwp_thread (lwp);
-
-      debug_printf ("LWP %ld has a suspiciously high suspend count,"
-                   " suspended=%d\n", lwpid_of (thread), lwp->suspended);
-    }
+  if (lwp->suspended > 4)
+    threads_debug_printf
+      ("LWP %ld has a suspiciously high suspend count, suspended=%d",
+       lwpid_of (get_lwp_thread (lwp)), lwp->suspended);
 }
 
 /* Decrement LWP's suspend count.  */
@@ -1910,8 +1892,7 @@ lwp_suspended_decr (struct lwp_info *lwp)
     {
       struct thread_info *thread = get_lwp_thread (lwp);
 
-      internal_error (__FILE__, __LINE__,
-                     "unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
+      internal_error ("unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 }
@@ -1958,8 +1939,7 @@ handle_tracepoints (struct lwp_info *lwp)
 
   if (tpoint_related_event)
     {
-      if (debug_threads)
-       debug_printf ("got a tracepoint event\n");
+      threads_debug_printf ("got a tracepoint event");
       return 1;
     }
 
@@ -1992,10 +1972,8 @@ linux_process_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
 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))
@@ -2004,10 +1982,9 @@ linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
     {
       struct fast_tpoint_collect_status status;
 
-      if (debug_threads)
-       debug_printf ("Checking whether LWP %ld needs to move out of the "
-                     "jump pad.\n",
-                     lwpid_of (current_thread));
+      threads_debug_printf
+       ("Checking whether LWP %ld needs to move out of the jump pad.",
+        lwpid_of (current_thread));
 
       fast_tpoint_collect_result r
        = linux_fast_tracepoint_collecting (lwp, &status);
@@ -2032,11 +2009,9 @@ linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
                    = set_breakpoint_at (status.adjusted_insn_addr, NULL);
                }
 
-             if (debug_threads)
-               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;
+             threads_debug_printf
+               ("Checking whether LWP %ld needs to move out of the jump pad..."
+                " it does", lwpid_of (current_thread));
 
              return true;
            }
@@ -2088,9 +2063,9 @@ linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
 
          if (lwp->exit_jump_pad_bkpt != NULL)
            {
-             if (debug_threads)
-               debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
-                             "stopping all threads momentarily.\n");
+             threads_debug_printf
+               ("Cancelling fast exit-jump-pad: removing bkpt."
+                "stopping all threads momentarily.");
 
              stop_all_lwps (1, lwp);
 
@@ -2104,12 +2079,10 @@ linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
        }
     }
 
-  if (debug_threads)
-    debug_printf ("Checking whether LWP %ld needs to move out of the "
-                 "jump pad...no\n",
-                 lwpid_of (current_thread));
+  threads_debug_printf
+    ("Checking whether LWP %ld needs to move out of the jump pad... no",
+     lwpid_of (current_thread));
 
-  current_thread = saved_thread;
   return false;
 }
 
@@ -2119,24 +2092,17 @@ linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
 static void
 enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 {
-  struct pending_signals *p_sig;
   struct thread_info *thread = get_lwp_thread (lwp);
 
-  if (debug_threads)
-    debug_printf ("Deferring signal %d for LWP %ld.\n",
-                 WSTOPSIG (*wstat), lwpid_of (thread));
+  threads_debug_printf ("Deferring signal %d for LWP %ld.",
+                       WSTOPSIG (*wstat), lwpid_of (thread));
 
   if (debug_threads)
     {
-      struct pending_signals *sig;
+      for (const auto &sig : lwp->pending_signals_to_report)
+       threads_debug_printf ("   Already queued %d", sig.signal);
 
-      for (sig = lwp->pending_signals_to_report;
-          sig != NULL;
-          sig = sig->prev)
-       debug_printf ("   Already queued %d\n",
-                     sig->signal);
-
-      debug_printf ("   (no more currently queued signals)\n");
+      threads_debug_printf ("   (no more currently queued signals)");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -2144,32 +2110,22 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
      twice)  */
   if (WSTOPSIG (*wstat) < __SIGRTMIN)
     {
-      struct pending_signals *sig;
-
-      for (sig = lwp->pending_signals_to_report;
-          sig != NULL;
-          sig = sig->prev)
+      for (const auto &sig : lwp->pending_signals_to_report)
        {
-         if (sig->signal == WSTOPSIG (*wstat))
+         if (sig.signal == WSTOPSIG (*wstat))
            {
-             if (debug_threads)
-               debug_printf ("Not requeuing already queued non-RT signal %d"
-                             " for LWP %ld\n",
-                             sig->signal,
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("Not requeuing already queued non-RT signal %d for LWP %ld",
+                sig.signal, lwpid_of (thread));
              return;
            }
        }
     }
 
-  p_sig = XCNEW (struct pending_signals);
-  p_sig->prev = lwp->pending_signals_to_report;
-  p_sig->signal = WSTOPSIG (*wstat);
+  lwp->pending_signals_to_report.emplace_back (WSTOPSIG (*wstat));
 
   ptrace (PTRACE_GETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-         &p_sig->info);
-
-  lwp->pending_signals_to_report = p_sig;
+         &lwp->pending_signals_to_report.back ().info);
 }
 
 /* Dequeue one signal from the "signals to report later when out of
@@ -2180,36 +2136,26 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
 
-  if (lwp->pending_signals_to_report != NULL)
+  if (!lwp->pending_signals_to_report.empty ())
     {
-      struct pending_signals **p_sig;
-
-      p_sig = &lwp->pending_signals_to_report;
-      while ((*p_sig)->prev != NULL)
-       p_sig = &(*p_sig)->prev;
+      const pending_signal &p_sig = lwp->pending_signals_to_report.front ();
 
-      *wstat = W_STOPCODE ((*p_sig)->signal);
-      if ((*p_sig)->info.si_signo != 0)
+      *wstat = W_STOPCODE (p_sig.signal);
+      if (p_sig.info.si_signo != 0)
        ptrace (PTRACE_SETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-               &(*p_sig)->info);
-      free (*p_sig);
-      *p_sig = NULL;
+               &p_sig.info);
 
-      if (debug_threads)
-       debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
-                     WSTOPSIG (*wstat), lwpid_of (thread));
+      lwp->pending_signals_to_report.pop_front ();
+
+      threads_debug_printf ("Reporting deferred signal %d for LWP %ld.",
+                           WSTOPSIG (*wstat), lwpid_of (thread));
 
       if (debug_threads)
        {
-         struct pending_signals *sig;
+         for (const auto &sig : lwp->pending_signals_to_report)
+           threads_debug_printf ("   Still queued %d", sig.signal);
 
-         for (sig = lwp->pending_signals_to_report;
-              sig != NULL;
-              sig = sig->prev)
-           debug_printf ("   Still queued %d\n",
-                         sig->signal);
-
-         debug_printf ("   (no more queued signals)\n");
+         threads_debug_printf ("   (no more queued signals)");
        }
 
       return 1;
@@ -2221,8 +2167,8 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 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 ())
     {
@@ -2230,8 +2176,6 @@ linux_process_target::check_stopped_by_watchpoint (lwp_info *child)
       child->stopped_data_address = low_stopped_data_address ();
     }
 
-  current_thread = saved_thread;
-
   return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
@@ -2272,7 +2216,7 @@ linux_low_ptrace_options (int attached)
   return options;
 }
 
-lwp_info *
+void
 linux_process_target::filter_event (int lwpid, int wstat)
 {
   client_state &cs = get_client_state ();
@@ -2282,49 +2226,65 @@ linux_process_target::filter_event (int lwpid, int wstat)
 
   child = find_lwp_pid (ptid_t (lwpid));
 
-  /* Check for stop events reported by a process we didn't already
-     know about - anything not already in our LWP list.
-
-     If we're expecting to receive stopped processes after
-     fork, vfork, and clone events, then we'll just add the
-     new one to our list and go back to waiting for the event
-     to be reported - the stopped process might be returned
-     from waitpid before or after the event is.
-
-     But note the case of a non-leader thread exec'ing after the
-     leader having exited, and gone from our lists (because
-     check_zombie_leaders deleted it).  The non-leader thread
-     changes its tid to the tgid.  */
-
-  if (WIFSTOPPED (wstat) && child == NULL && WSTOPSIG (wstat) == SIGTRAP
-      && linux_ptrace_get_extended_event (wstat) == PTRACE_EVENT_EXEC)
+  /* Check for events reported by anything not in our LWP list.  */
+  if (child == nullptr)
     {
-      ptid_t child_ptid;
-
-      /* A multi-thread exec after we had seen the leader exiting.  */
-      if (debug_threads)
+      if (WIFSTOPPED (wstat))
        {
-         debug_printf ("LLW: Re-adding thread group leader LWP %d"
-                       "after exec.\n", lwpid);
+         if (WSTOPSIG (wstat) == SIGTRAP
+             && linux_ptrace_get_extended_event (wstat) == PTRACE_EVENT_EXEC)
+           {
+             /* A non-leader thread exec'ed after we've seen the
+                leader zombie, and removed it from our lists (in
+                check_zombie_leaders).  The non-leader thread changes
+                its tid to the tgid.  */
+             threads_debug_printf
+               ("Re-adding thread group leader LWP %d after exec.",
+                lwpid);
+
+             child = add_lwp (ptid_t (lwpid, lwpid));
+             child->stopped = 1;
+             switch_to_thread (child->thread);
+           }
+         else
+           {
+             /* A process we are controlling has forked and the new
+                child's stop was reported to us by the kernel.  Save
+                its PID and go back to waiting for the fork event to
+                be reported - the stopped process might be returned
+                from waitpid before or after the fork event is.  */
+             threads_debug_printf
+               ("Saving LWP %d status %s in stopped_pids list",
+                lwpid, status_to_str (wstat).c_str ());
+             add_to_pid_list (&stopped_pids, lwpid, wstat);
+           }
        }
+      else
+       {
+         /* Don't report an event for the exit of an LWP not in our
+            list, i.e. not part of any inferior we're debugging.
+            This can happen if we detach from a program we originally
+            forked and then it exits.  However, note that we may have
+            earlier deleted a leader of an inferior we're debugging,
+            in check_zombie_leaders.  Re-add it back here if so.  */
+         find_process ([&] (process_info *proc)
+           {
+             if (proc->pid == lwpid)
+               {
+                 threads_debug_printf
+                   ("Re-adding thread group leader LWP %d after exit.",
+                    lwpid);
 
-      child_ptid = ptid_t (lwpid, lwpid, 0);
-      child = add_lwp (child_ptid);
-      child->stopped = 1;
-      current_thread = child->thread;
-    }
+                 child = add_lwp (ptid_t (lwpid, lwpid));
+                 return true;
+               }
+             return false;
+           });
+       }
 
-  /* If we didn't find a process, one of two things presumably happened:
-     - A process we started and then detached from has exited.  Ignore it.
-     - A process we are controlling has forked and the new child's stop
-     was reported to us by the kernel.  Save its PID.  */
-  if (child == NULL && WIFSTOPPED (wstat))
-    {
-      add_to_pid_list (&stopped_pids, lwpid, wstat);
-      return NULL;
+      if (child == nullptr)
+       return;
     }
-  else if (child == NULL)
-    return NULL;
 
   thread = get_lwp_thread (child);
 
@@ -2335,8 +2295,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
   /* Check if the thread has exited.  */
   if ((WIFEXITED (wstat) || WIFSIGNALED (wstat)))
     {
-      if (debug_threads)
-       debug_printf ("LLFE: %d exited.\n", lwpid);
+      threads_debug_printf ("%d exited", lwpid);
 
       if (finish_step_over (child))
        {
@@ -2344,22 +2303,21 @@ linux_process_target::filter_event (int lwpid, int wstat)
          unsuspend_all_lwps (child);
        }
 
-      /* If there is at least one more LWP, then the exit signal was
-        not the end of the debugged application and should be
-        ignored, unless GDB wants to hear about thread exits.  */
-      if (cs.report_thread_events
-         || last_thread_of_process_p (pid_of (thread)))
+      /* If this is not the leader LWP, then the exit signal was not
+        the end of the debugged application and should be ignored,
+        unless GDB wants to hear about thread exits.  */
+      if (cs.report_thread_events || is_leader (thread))
        {
          /* Since events are serialized to GDB core, and we can't
             report this one right now.  Leave the status pending for
             the next time we're able to report it.  */
          mark_lwp_dead (child, wstat);
-         return child;
+         return;
        }
       else
        {
          delete_lwp (child);
-         return NULL;
+         return;
        }
     }
 
@@ -2387,7 +2345,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
                 the first instruction.  */
              child->status_pending_p = 1;
              child->status_pending = wstat;
-             return child;
+             return;
            }
        }
     }
@@ -2426,7 +2384,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
        {
          /* The event has been handled, so just return without
             reporting it.  */
-         return NULL;
+         return;
        }
     }
 
@@ -2442,44 +2400,40 @@ linux_process_target::filter_event (int lwpid, int wstat)
   if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGSTOP
       && child->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Expected stop.\n");
+      threads_debug_printf ("Expected stop.");
+
       child->stop_expected = 0;
 
       if (thread->last_resume_kind == resume_stop)
        {
          /* We want to report the stop to the core.  Treat the
             SIGSTOP as a normal event.  */
-         if (debug_threads)
-           debug_printf ("LLW: resume_stop SIGSTOP caught for %s.\n",
-                         target_pid_to_str (ptid_of (thread)));
+         threads_debug_printf ("resume_stop SIGSTOP caught for %s.",
+                               target_pid_to_str (ptid_of (thread)).c_str ());
        }
       else if (stopping_threads != NOT_STOPPING_THREADS)
        {
          /* Stopping threads.  We don't want this SIGSTOP to end up
             pending.  */
-         if (debug_threads)
-           debug_printf ("LLW: SIGSTOP caught for %s "
-                         "while stopping threads.\n",
-                         target_pid_to_str (ptid_of (thread)));
-         return NULL;
+         threads_debug_printf ("SIGSTOP caught for %s while stopping threads.",
+                               target_pid_to_str (ptid_of (thread)).c_str ());
+         return;
        }
       else
        {
          /* This is a delayed SIGSTOP.  Filter out the event.  */
-         if (debug_threads)
-           debug_printf ("LLW: %s %s, 0, 0 (discard delayed SIGSTOP)\n",
+         threads_debug_printf ("%s %s, 0, 0 (discard delayed SIGSTOP)",
                          child->stepping ? "step" : "continue",
-                         target_pid_to_str (ptid_of (thread)));
+                         target_pid_to_str (ptid_of (thread)).c_str ());
 
          resume_one_lwp (child, child->stepping, 0, NULL);
-         return NULL;
+         return;
        }
     }
 
   child->status_pending_p = 1;
   child->status_pending = wstat;
-  return child;
+  return;
 }
 
 bool
@@ -2504,18 +2458,16 @@ linux_process_target::resume_stopped_resumed_lwps (thread_info *thread)
   if (lp->stopped
       && !lp->suspended
       && !lp->status_pending_p
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     {
       int step = 0;
 
       if (thread->last_resume_kind == resume_step)
        step = maybe_hw_step (thread);
 
-      if (debug_threads)
-       debug_printf ("RSRL: resuming stopped-resumed LWP %s at %s: step=%d\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     paddress (lp->stop_pc),
-                     step);
+      threads_debug_printf ("resuming stopped-resumed LWP %s at %s: step=%d",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           paddress (lp->stop_pc), step);
 
       resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL);
     }
@@ -2547,9 +2499,10 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
        });
 
       if (event_thread != NULL)
-       event_child = get_thread_lwp (event_thread);
-      if (debug_threads && event_thread)
-       debug_printf ("Got a pending child %ld\n", lwpid_of (event_thread));
+       {
+         event_child = get_thread_lwp (event_thread);
+         threads_debug_printf ("Got a pending child %ld", lwpid_of (event_thread));
+       }
     }
   else if (filter_ptid != null_ptid)
     {
@@ -2570,8 +2523,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
       if (requested_child->suspended
          && requested_child->status_pending_p)
        {
-         internal_error (__FILE__, __LINE__,
-                         "requesting an event out of a"
+         internal_error ("requesting an event out of a"
                          " suspended child?");
        }
 
@@ -2584,13 +2536,14 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
 
   if (event_child != NULL)
     {
-      if (debug_threads)
-       debug_printf ("Got an event from pending child %ld (%04x)\n",
-                     lwpid_of (event_thread), event_child->status_pending);
+      threads_debug_printf ("Got an event from pending child %ld (%04x)",
+                           lwpid_of (event_thread),
+                           event_child->status_pending);
+
       *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);
     }
 
@@ -2628,17 +2581,13 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
       errno = 0;
       ret = my_waitpid (-1, wstatp, options | WNOHANG);
 
-      if (debug_threads)
-       debug_printf ("LWFE: waitpid(-1, ...) returned %d, %s\n",
-                     ret, errno ? safe_strerror (errno) : "ERRNO-OK");
+      threads_debug_printf ("waitpid(-1, ...) returned %d, %s",
+                           ret, errno ? safe_strerror (errno) : "ERRNO-OK");
 
       if (ret > 0)
        {
-         if (debug_threads)
-           {
-             debug_printf ("LLW: waitpid %ld received %s\n",
-                           (long) ret, status_to_str (*wstatp));
-           }
+         threads_debug_printf ("waitpid %ld received %s",
+                               (long) ret, status_to_str (*wstatp).c_str ());
 
          /* Filter all events.  IOW, leave all events pending.  We'll
             randomly select an event LWP out of all that have events
@@ -2691,8 +2640,8 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
         over 0 (below), as it is more detailed.  */
       if (find_thread (not_stopped) == NULL)
        {
-         if (debug_threads)
-           debug_printf ("LLW: exit (no unwaited-for LWP)\n");
+         threads_debug_printf ("exit (no unwaited-for LWP)");
+
          gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return -1;
        }
@@ -2700,16 +2649,14 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
       /* No interesting event to report to the caller.  */
       if ((options & WNOHANG))
        {
-         if (debug_threads)
-           debug_printf ("WNOHANG set, no event found\n");
+         threads_debug_printf ("WNOHANG set, no event found");
 
          gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return 0;
        }
 
       /* Block until we get an event reported with SIGCHLD.  */
-      if (debug_threads)
-       debug_printf ("sigsuspend'ing\n");
+      threads_debug_printf ("sigsuspend'ing");
 
       sigsuspend (&prev_mask);
       gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
@@ -2718,7 +2665,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
 
   gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
 
-  current_thread = event_thread;
+  switch_to_thread (event_thread);
 
   return lwpid_of (event_thread);
 }
@@ -2750,29 +2697,27 @@ select_event_lwp (struct lwp_info **orig_lp)
        {
          lwp_info *lp = get_thread_lwp (thread);
 
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && thread->last_resume_kind == resume_step
                  && lp->status_pending_p);
        });
 
       if (event_thread != NULL)
-       {
-         if (debug_threads)
-           debug_printf ("SEL: Select single-step %s\n",
-                         target_pid_to_str (ptid_of (event_thread)));
-       }
+       threads_debug_printf
+         ("Select single-step %s",
+          target_pid_to_str (ptid_of (event_thread)).c_str ());
     }
   if (event_thread == NULL)
     {
       /* No single-stepping LWP.  Select one at random, out of those
-         which have had events.  */
+        which have had events.  */
 
       event_thread = find_thread_in_random ([&] (thread_info *thread)
        {
          lwp_info *lp = get_thread_lwp (thread);
 
          /* Only resumed LWPs that have an event pending. */
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && lp->status_pending_p);
        });
     }
@@ -2843,13 +2788,12 @@ linux_process_target::stabilize_threads ()
 
   if (thread_stuck != NULL)
     {
-      if (debug_threads)
-       debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
-                     lwpid_of (thread_stuck));
+      threads_debug_printf ("can't stabilize, LWP %ld is stuck in jump pad",
+                           lwpid_of (thread_stuck));
       return;
     }
 
-  thread_info *saved_thread = current_thread;
+  scoped_restore_current_thread restore_thread;
 
   stabilizing_threads = 1;
 
@@ -2871,17 +2815,17 @@ linux_process_target::stabilize_threads ()
         over internal breakpoints and such.  */
       wait_1 (minus_one_ptid, &ourstatus, 0);
 
-      if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
+      if (ourstatus.kind () == TARGET_WAITKIND_STOPPED)
        {
          lwp = get_thread_lwp (current_thread);
 
          /* Lock it.  */
          lwp_suspended_inc (lwp);
 
-         if (ourstatus.value.sig != GDB_SIGNAL_0
+         if (ourstatus.sig () != GDB_SIGNAL_0
              || current_thread->last_resume_kind == resume_stop)
            {
-             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig));
+             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.sig ()));
              enqueue_one_deferred_signal (lwp, &wstat);
            }
        }
@@ -2891,8 +2835,6 @@ linux_process_target::stabilize_threads ()
 
   stabilizing_threads = 0;
 
-  current_thread = saved_thread;
-
   if (debug_threads)
     {
       thread_stuck = find_thread ([this] (thread_info *thread)
@@ -2901,8 +2843,9 @@ linux_process_target::stabilize_threads ()
                       });
 
       if (thread_stuck != NULL)
-       debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
-                     lwpid_of (thread_stuck));
+       threads_debug_printf
+         ("couldn't stabilize, LWP %ld got stuck in jump pad",
+          lwpid_of (thread_stuck));
     }
 }
 
@@ -2917,7 +2860,7 @@ ignore_event (struct target_waitstatus *ourstatus)
      another target_wait call.  */
   async_file_mark ();
 
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
   return null_ptid;
 }
 
@@ -2929,12 +2872,12 @@ linux_process_target::filter_exit_event (lwp_info *event_child,
   struct thread_info *thread = get_lwp_thread (event_child);
   ptid_t ptid = ptid_of (thread);
 
-  if (!last_thread_of_process_p (pid_of (thread)))
+  if (!is_leader (thread))
     {
       if (cs.report_thread_events)
-       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+       ourstatus->set_thread_exited (0);
       else
-       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+       ourstatus->set_ignore ();
 
       delete_lwp (event_child);
     }
@@ -2976,8 +2919,10 @@ linux_process_target::gdb_catch_this_syscall (lwp_info *event_child)
 
 ptid_t
 linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
-                             int target_options)
+                             target_wait_flags target_options)
 {
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
   client_state &cs = get_client_state ();
   int w;
   struct lwp_info *event_child;
@@ -2991,11 +2936,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
   int in_step_range;
   int any_resumed;
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("wait_1: [%s]\n", target_pid_to_str (ptid));
-    }
+  threads_debug_printf ("[%s]", target_pid_to_str (ptid).c_str ());
 
   /* Translate generic target options into linux options.  */
   options = __WALL;
@@ -3005,7 +2946,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
   bp_explains_trap = 0;
   trace_event = 0;
   in_step_range = 0;
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
 
   auto status_pending_p_any = [&] (thread_info *thread)
     {
@@ -3029,9 +2970,8 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
     pid = wait_for_event (ptid, &w, options);
   else
     {
-      if (debug_threads)
-       debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
-                     target_pid_to_str (step_over_bkpt));
+      threads_debug_printf ("step_over_bkpt set [%s], doing a blocking wait",
+                           target_pid_to_str (step_over_bkpt).c_str ());
       pid = wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
@@ -3039,26 +2979,16 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
     {
       gdb_assert (target_options & TARGET_WNOHANG);
 
-      if (debug_threads)
-       {
-         debug_printf ("wait_1 ret = null_ptid, "
-                       "TARGET_WAITKIND_IGNORE\n");
-         debug_exit ();
-       }
+      threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_IGNORE");
 
-      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+      ourstatus->set_ignore ();
       return null_ptid;
     }
   else if (pid == -1)
     {
-      if (debug_threads)
-       {
-         debug_printf ("wait_1 ret = null_ptid, "
-                       "TARGET_WAITKIND_NO_RESUMED\n");
-         debug_exit ();
-       }
+      threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_NO_RESUMED");
 
-      ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
+      ourstatus->set_no_resumed ();
       return null_ptid;
     }
 
@@ -3070,34 +3000,24 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
     {
       if (WIFEXITED (w))
        {
-         ourstatus->kind = TARGET_WAITKIND_EXITED;
-         ourstatus->value.integer = WEXITSTATUS (w);
+         ourstatus->set_exited (WEXITSTATUS (w));
 
-         if (debug_threads)
-           {
-             debug_printf ("wait_1 ret = %s, exited with "
-                           "retcode %d\n",
-                           target_pid_to_str (ptid_of (current_thread)),
-                           WEXITSTATUS (w));
-             debug_exit ();
-           }
+         threads_debug_printf
+           ("ret = %s, exited with retcode %d",
+            target_pid_to_str (ptid_of (current_thread)).c_str (),
+            WEXITSTATUS (w));
        }
       else
        {
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
+         ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (w)));
 
-         if (debug_threads)
-           {
-             debug_printf ("wait_1 ret = %s, terminated with "
-                           "signal %d\n",
-                           target_pid_to_str (ptid_of (current_thread)),
-                           WTERMSIG (w));
-             debug_exit ();
-           }
+         threads_debug_printf
+           ("ret = %s, terminated with signal %d",
+            target_pid_to_str (ptid_of (current_thread)).c_str (),
+            WTERMSIG (w));
        }
 
-      if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+      if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
        return filter_exit_event (event_child, ourstatus);
 
       return ptid_of (current_thread);
@@ -3126,11 +3046,9 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
       breakpoint_kind = breakpoint_kind_from_current_state (&stop_pc);
       sw_breakpoint_from_kind (breakpoint_kind, &increment_pc);
 
-      if (debug_threads)
-       {
-         debug_printf ("step-over for %s executed software breakpoint\n",
-                       target_pid_to_str (ptid_of (current_thread)));
-       }
+      threads_debug_printf
+       ("step-over for %s executed software breakpoint",
+        target_pid_to_str (ptid_of (current_thread)).c_str ());
 
       if (increment_pc != 0)
        {
@@ -3183,10 +3101,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
       trace_event = handle_tracepoints (event_child);
 
       if (bp_explains_trap)
-       {
-         if (debug_threads)
-           debug_printf ("Hit a gdbserver breakpoint.\n");
-       }
+       threads_debug_printf ("Hit a gdbserver breakpoint.");
     }
   else
     {
@@ -3207,10 +3122,9 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
       && supports_fast_tracepoints ()
       && agent_loaded_p ())
     {
-      if (debug_threads)
-       debug_printf ("Got signal %d for LWP %ld.  Check if we need "
-                     "to defer or adjust it.\n",
-                     WSTOPSIG (w), lwpid_of (current_thread));
+      threads_debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+                           "to defer or adjust it.",
+                           WSTOPSIG (w), lwpid_of (current_thread));
 
       /* Allow debugging the jump pad itself.  */
       if (current_thread->last_resume_kind != resume_step
@@ -3218,14 +3132,11 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
        {
          enqueue_one_deferred_signal (event_child, &w);
 
-         if (debug_threads)
-           debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
-                         WSTOPSIG (w), lwpid_of (current_thread));
+         threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad)",
+                               WSTOPSIG (w), lwpid_of (current_thread));
 
          resume_one_lwp (event_child, 0, 0, NULL);
 
-         if (debug_threads)
-           debug_exit ();
          return ignore_event (ourstatus);
        }
     }
@@ -3233,11 +3144,11 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
   if (event_child->collecting_fast_tracepoint
       != fast_tpoint_collect_result::not_collecting)
     {
-      if (debug_threads)
-       debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
-                     "Check if we're already there.\n",
-                     lwpid_of (current_thread),
-                     (int) event_child->collecting_fast_tracepoint);
+      threads_debug_printf
+       ("LWP %ld was trying to move out of the jump pad (%d). "
+        "Check if we're already there.",
+        lwpid_of (current_thread),
+        (int) event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -3250,9 +3161,9 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
          /* No longer need this breakpoint.  */
          if (event_child->exit_jump_pad_bkpt != NULL)
            {
-             if (debug_threads)
-               debug_printf ("No longer need exit-jump-pad bkpt; removing it."
-                             "stopping all threads momentarily.\n");
+             threads_debug_printf
+               ("No longer need exit-jump-pad bkpt; removing it."
+                "stopping all threads momentarily.");
 
              /* Other running threads could hit this breakpoint.
                 We don't handle moribund locations like GDB does,
@@ -3275,33 +3186,23 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
       if (event_child->collecting_fast_tracepoint
          == fast_tpoint_collect_result::not_collecting)
        {
-         if (debug_threads)
-           debug_printf ("fast tracepoint finished "
-                         "collecting successfully.\n");
+         threads_debug_printf
+           ("fast tracepoint finished collecting successfully.");
 
          /* We may have a deferred signal to report.  */
          if (dequeue_one_deferred_signal (event_child, &w))
-           {
-             if (debug_threads)
-               debug_printf ("dequeued one signal.\n");
-           }
+           threads_debug_printf ("dequeued one signal.");
          else
            {
-             if (debug_threads)
-               debug_printf ("no deferred signals.\n");
+             threads_debug_printf ("no deferred signals.");
 
              if (stabilizing_threads)
                {
-                 ourstatus->kind = TARGET_WAITKIND_STOPPED;
-                 ourstatus->value.sig = GDB_SIGNAL_0;
+                 ourstatus->set_stopped (GDB_SIGNAL_0);
 
-                 if (debug_threads)
-                   {
-                     debug_printf ("wait_1 ret = %s, stopped "
-                                   "while stabilizing threads\n",
-                                   target_pid_to_str (ptid_of (current_thread)));
-                     debug_exit ();
-                   }
+                 threads_debug_printf
+                   ("ret = %s, stopped while stabilizing threads",
+                    target_pid_to_str (ptid_of (current_thread)).c_str ());
 
                  return ptid_of (current_thread);
                }
@@ -3316,16 +3217,11 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
       && WSTOPSIG (w) == SYSCALL_SIGTRAP
       && !gdb_catch_this_syscall (event_child))
     {
-      if (debug_threads)
-       {
-         debug_printf ("Ignored syscall for LWP %ld.\n",
-                       lwpid_of (current_thread));
-       }
+      threads_debug_printf ("Ignored syscall for LWP %ld.",
+                           lwpid_of (current_thread));
 
       resume_one_lwp (event_child, event_child->stepping, 0, NULL);
 
-      if (debug_threads)
-       debug_exit ();
       return ignore_event (ourstatus);
     }
 
@@ -3353,9 +3249,8 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
     {
       siginfo_t info, *info_p;
 
-      if (debug_threads)
-       debug_printf ("Ignored signal %d for LWP %ld.\n",
-                     WSTOPSIG (w), lwpid_of (current_thread));
+      threads_debug_printf ("Ignored signal %d for LWP %ld.",
+                           WSTOPSIG (w), lwpid_of (current_thread));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
                  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -3382,9 +3277,6 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
                          WSTOPSIG (w), info_p);
        }
 
-      if (debug_threads)
-       debug_exit ();
-
       return ignore_event (ourstatus);
     }
 
@@ -3418,7 +3310,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
                   || (gdb_breakpoint_here (event_child->stop_pc)
                       && gdb_condition_true_at_breakpoint (event_child->stop_pc)
                       && gdb_no_commands_at_breakpoint (event_child->stop_pc))
-                  || event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE);
+                  || event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE);
 
   run_breakpoint_commands (event_child->stop_pc);
 
@@ -3427,20 +3319,20 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
      shouldn't know about.  */
   if (!report_to_gdb)
     {
-      if (debug_threads)
-       {
-         if (bp_explains_trap)
-           debug_printf ("Hit a gdbserver breakpoint.\n");
-         if (step_over_finished)
-           debug_printf ("Step-over finished.\n");
-         if (trace_event)
-           debug_printf ("Tracepoint event.\n");
-         if (lwp_in_step_range (event_child))
-           debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
-                         paddress (event_child->stop_pc),
-                         paddress (event_child->step_range_start),
-                         paddress (event_child->step_range_end));
-       }
+      if (bp_explains_trap)
+       threads_debug_printf ("Hit a gdbserver breakpoint.");
+
+      if (step_over_finished)
+       threads_debug_printf ("Step-over finished.");
+
+      if (trace_event)
+       threads_debug_printf ("Tracepoint event.");
+
+      if (lwp_in_step_range (event_child))
+       threads_debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).",
+                             paddress (event_child->stop_pc),
+                             paddress (event_child->step_range_start),
+                             paddress (event_child->step_range_end));
 
       /* We're not reporting this breakpoint to GDB, so apply the
         decr_pc_after_break adjustment to the inferior's regcache
@@ -3476,40 +3368,36 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
            }
        }
 
-      if (debug_threads)
-       debug_printf ("proceeding all threads.\n");
-      proceed_all_lwps ();
+      threads_debug_printf ("proceeding all threads.");
 
-      if (debug_threads)
-       debug_exit ();
+      proceed_all_lwps ();
 
       return ignore_event (ourstatus);
     }
 
-  if (debug_threads)
-    {
-      if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
-       {
-         std::string str
-           = target_waitstatus_to_string (&event_child->waitstatus);
+    if (debug_threads)
+      {
+       if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
+         threads_debug_printf ("LWP %ld: extended event with waitstatus %s",
+                               lwpid_of (get_lwp_thread (event_child)),
+                               event_child->waitstatus.to_string ().c_str ());
 
-         debug_printf ("LWP %ld: extended event with waitstatus %s\n",
-                       lwpid_of (get_lwp_thread (event_child)), str.c_str ());
-       }
-      if (current_thread->last_resume_kind == resume_step)
-       {
-         if (event_child->step_range_start == event_child->step_range_end)
-           debug_printf ("GDB wanted to single-step, reporting event.\n");
-         else if (!lwp_in_step_range (event_child))
-           debug_printf ("Out of step range, reporting event.\n");
-       }
-      if (event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
-       debug_printf ("Stopped by watchpoint.\n");
-      else if (gdb_breakpoint_here (event_child->stop_pc))
-       debug_printf ("Stopped by GDB breakpoint.\n");
-      if (debug_threads)
-       debug_printf ("Hit a non-gdbserver trap event.\n");
-    }
+       if (current_thread->last_resume_kind == resume_step)
+         {
+           if (event_child->step_range_start == event_child->step_range_end)
+             threads_debug_printf
+               ("GDB wanted to single-step, reporting event.");
+           else if (!lwp_in_step_range (event_child))
+             threads_debug_printf ("Out of step range, reporting event.");
+         }
+
+       if (event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
+         threads_debug_printf ("Stopped by watchpoint.");
+       else if (gdb_breakpoint_here (event_child->stop_pc))
+         threads_debug_printf ("Stopped by GDB breakpoint.");
+      }
+
+    threads_debug_printf ("Hit a non-gdbserver trap event.");
 
   /* Alright, we're going to report a stop.  */
 
@@ -3608,7 +3496,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
          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;
@@ -3629,14 +3517,17 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
        unstop_all_lwps (1, event_child);
     }
 
-  if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  /* At this point, we haven't set OURSTATUS.  This is where we do it.  */
+  gdb_assert (ourstatus->kind () == TARGET_WAITKIND_IGNORE);
+
+  if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* If the reported event is an exit, fork, vfork or exec, let
         GDB know.  */
 
       /* Break the unreported fork relationship chain.  */
-      if (event_child->waitstatus.kind == TARGET_WAITKIND_FORKED
-         || event_child->waitstatus.kind == TARGET_WAITKIND_VFORKED)
+      if (event_child->waitstatus.kind () == TARGET_WAITKIND_FORKED
+         || event_child->waitstatus.kind () == TARGET_WAITKIND_VFORKED)
        {
          event_child->fork_relative->fork_relative = NULL;
          event_child->fork_relative = NULL;
@@ -3644,10 +3535,36 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
 
       *ourstatus = event_child->waitstatus;
       /* Clear the event lwp's waitstatus since we handled it already.  */
-      event_child->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      event_child->waitstatus.set_ignore ();
     }
   else
-    ourstatus->kind = TARGET_WAITKIND_STOPPED;
+    {
+      /* The LWP stopped due to a plain signal or a syscall signal.  Either way,
+        event_chid->waitstatus wasn't filled in with the details, so look at
+        the wait status W.  */
+      if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
+       {
+         int syscall_number;
+
+         get_syscall_trapinfo (event_child, &syscall_number);
+         if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+           ourstatus->set_syscall_entry (syscall_number);
+         else if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN)
+           ourstatus->set_syscall_return (syscall_number);
+         else
+           gdb_assert_not_reached ("unexpected syscall state");
+       }
+      else if (current_thread->last_resume_kind == resume_stop
+              && WSTOPSIG (w) == SIGSTOP)
+       {
+         /* A thread that has been requested to stop by GDB with vCont;t,
+            and it stopped cleanly, so report as SIG0.  The use of
+            SIGSTOP is an implementation detail.  */
+         ourstatus->set_stopped (GDB_SIGNAL_0);
+       }
+      else
+       ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));
+    }
 
   /* Now that we've selected our final event LWP, un-adjust its PC if
      it was a software breakpoint, and the client doesn't know we can
@@ -3665,43 +3582,13 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
        }
     }
 
-  if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
-    {
-      get_syscall_trapinfo (event_child,
-                           &ourstatus->value.syscall_number);
-      ourstatus->kind = event_child->syscall_state;
-    }
-  else if (current_thread->last_resume_kind == resume_stop
-          && WSTOPSIG (w) == SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        and it stopped cleanly, so report as SIG0.  The use of
-        SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = GDB_SIGNAL_0;
-    }
-  else if (current_thread->last_resume_kind == resume_stop
-          && WSTOPSIG (w) != SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        but, it stopped for other reasons.  */
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
-    }
-  else if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
-    {
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
-    }
-
   gdb_assert (step_over_bkpt == null_ptid);
 
-  if (debug_threads)
-    {
-      debug_printf ("wait_1 ret = %s, %d, %d\n",
-                   target_pid_to_str (ptid_of (current_thread)),
-                   ourstatus->kind, ourstatus->value.sig);
-      debug_exit ();
-    }
+  threads_debug_printf ("ret = %s, %s",
+                       target_pid_to_str (ptid_of (current_thread)).c_str (),
+                       ourstatus->to_string ().c_str ());
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
     return filter_exit_event (event_child, ourstatus);
 
   return ptid_of (current_thread);
@@ -3711,34 +3598,20 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
 static void
 async_file_flush (void)
 {
-  int ret;
-  char buf;
-
-  do
-    ret = read (linux_event_pipe[0], &buf, 1);
-  while (ret >= 0 || (ret == -1 && errno == EINTR));
+  linux_event_pipe.flush ();
 }
 
 /* Put something in the pipe, so the event loop wakes up.  */
 static void
 async_file_mark (void)
 {
-  int ret;
-
-  async_file_flush ();
-
-  do
-    ret = write (linux_event_pipe[1], "+", 1);
-  while (ret == 0 || (ret == -1 && errno == EINTR));
-
-  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
-     be awakened anyway.  */
+  linux_event_pipe.mark ();
 }
 
 ptid_t
 linux_process_target::wait (ptid_t ptid,
                            target_waitstatus *ourstatus,
-                           int target_options)
+                           target_wait_flags target_options)
 {
   ptid_t event_ptid;
 
@@ -3752,7 +3625,7 @@ linux_process_target::wait (ptid_t ptid,
     }
   while ((target_options & TARGET_WNOHANG) == 0
         && event_ptid == null_ptid
-        && ourstatus->kind == TARGET_WAITKIND_IGNORE);
+        && ourstatus->kind () == TARGET_WAITKIND_IGNORE);
 
   /* If at least one stop was reported, there may be more.  A single
      SIGCHLD can signal more than one child stop.  */
@@ -3799,14 +3672,12 @@ send_sigstop (struct lwp_info *lwp)
      send another.  */
   if (lwp->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Have pending sigstop for lwp %d\n", pid);
+      threads_debug_printf ("Have pending sigstop for lwp %d", pid);
 
       return;
     }
 
-  if (debug_threads)
-    debug_printf ("Sending sigstop to lwp %d\n", pid);
+  threads_debug_printf ("Sending sigstop to lwp %d", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -3853,15 +3724,9 @@ mark_lwp_dead (struct lwp_info *lwp, int wstat)
   /* Store in waitstatus as well, as there's nothing else to process
      for this event.  */
   if (WIFEXITED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_EXITED;
-      lwp->waitstatus.value.integer = WEXITSTATUS (wstat);
-    }
+    lwp->waitstatus.set_exited (WEXITSTATUS (wstat));
   else if (WIFSIGNALED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_SIGNALLED;
-      lwp->waitstatus.value.sig = gdb_signal_from_host (WTERMSIG (wstat));
-    }
+    lwp->waitstatus.set_signalled (gdb_signal_from_host (WTERMSIG (wstat)));
 
   /* Prevent trying to stop it.  */
   lwp->stopped = 1;
@@ -3895,8 +3760,9 @@ linux_process_target::wait_for_sigstop ()
   else
     saved_tid = null_ptid; /* avoid bogus unused warning */
 
-  if (debug_threads)
-    debug_printf ("wait_for_sigstop: pulling events\n");
+  scoped_restore_current_thread restore_thread;
+
+  threads_debug_printf ("pulling events");
 
   /* Passing NULL_PTID as filter indicates we want all events to be
      left pending.  Eventually this returns when there are no
@@ -3905,16 +3771,16 @@ linux_process_target::wait_for_sigstop ()
   gdb_assert (ret == -1);
 
   if (saved_thread == NULL || mythread_alive (saved_tid))
-    current_thread = saved_thread;
+    return;
   else
     {
-      if (debug_threads)
-       debug_printf ("Previously current thread died.\n");
+      threads_debug_printf ("Previously current thread died.");
 
       /* We can't change the current inferior behind GDB's back,
         otherwise, a subsequent command may apply to the wrong
         process.  */
-      current_thread = NULL;
+      restore_thread.dont_restore ();
+      switch_to_thread (nullptr);
     }
 }
 
@@ -3925,8 +3791,7 @@ linux_process_target::stuck_in_jump_pad (thread_info *thread)
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   gdb_assert (lwp->stopped);
@@ -3944,21 +3809,19 @@ linux_process_target::stuck_in_jump_pad (thread_info *thread)
 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;
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   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;
 
@@ -3968,27 +3831,22 @@ linux_process_target::move_out_of_jump_pad (thread_info *thread)
       && thread->last_resume_kind != resume_step
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
-      if (debug_threads)
-       debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("LWP %ld needs stabilizing (in jump pad)",
+                           lwpid_of (thread));
 
       if (wstat)
        {
          lwp->status_pending_p = 0;
          enqueue_one_deferred_signal (lwp, wstat);
 
-         if (debug_threads)
-           debug_printf ("Signal %d for LWP %ld deferred "
-                         "(in jump pad)\n",
-                         WSTOPSIG (*wstat), lwpid_of (thread));
+         threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad",
+                               WSTOPSIG (*wstat), lwpid_of (thread));
        }
 
       resume_one_lwp (lwp, 0, 0, NULL);
     }
   else
     lwp_suspended_inc (lwp);
-
-  current_thread = saved_thread;
 }
 
 static bool
@@ -4008,15 +3866,13 @@ linux_process_target::stop_all_lwps (int suspend, lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("stop_all_lwps (%s, except=%s)\n",
-                   suspend ? "stop-and-suspend" : "stop",
-                   except != NULL
-                   ? target_pid_to_str (ptid_of (get_lwp_thread (except)))
-                   : "none");
-    }
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
+  threads_debug_printf
+    ("%s, except=%s", suspend ? "stop-and-suspend" : "stop",
+     (except != NULL
+      ? target_pid_to_str (ptid_of (get_lwp_thread (except))).c_str ()
+      : "none"));
 
   stopping_threads = (suspend
                      ? STOPPING_AND_SUSPENDING_THREADS
@@ -4036,12 +3892,7 @@ linux_process_target::stop_all_lwps (int suspend, lwp_info *except)
   wait_for_sigstop ();
   stopping_threads = NOT_STOPPING_THREADS;
 
-  if (debug_threads)
-    {
-      debug_printf ("stop_all_lwps done, setting stopping_threads "
-                   "back to !stopping\n");
-      debug_exit ();
-    }
+  threads_debug_printf ("setting stopping_threads back to !stopping");
 }
 
 /* Enqueue one signal in the chain of signals which need to be
@@ -4050,15 +3901,11 @@ linux_process_target::stop_all_lwps (int suspend, lwp_info *except)
 static void
 enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info)
 {
-  struct pending_signals *p_sig = XNEW (struct pending_signals);
-
-  p_sig->prev = lwp->pending_signals;
-  p_sig->signal = signal;
-  if (info == NULL)
-    memset (&p_sig->info, 0, sizeof (siginfo_t));
+  lwp->pending_signals.emplace_back (signal);
+  if (info == nullptr)
+    memset (&lwp->pending_signals.back ().info, 0, sizeof (siginfo_t));
   else
-    memcpy (&p_sig->info, info, sizeof (siginfo_t));
-  lwp->pending_signals = p_sig;
+    lwp->pending_signals.back ().info = *info;
 }
 
 void
@@ -4067,9 +3914,9 @@ linux_process_target::install_software_single_step_breakpoints (lwp_info *lwp)
   struct thread_info *thread = get_lwp_thread (lwp);
   struct regcache *regcache = get_thread_regcache (thread, 1);
 
-  scoped_restore save_current_thread = make_scoped_restore (&current_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)
@@ -4091,10 +3938,7 @@ linux_process_target::single_step (lwp_info* lwp)
       step = 0;
     }
   else
-    {
-      if (debug_threads)
-       debug_printf ("stepping is not implemented on this target");
-    }
+    threads_debug_printf ("stepping is not implemented on this target");
 
   return step;
 }
@@ -4117,7 +3961,6 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
                                            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);
 
@@ -4131,7 +3974,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
   if (lwp->stopped == 0)
     return;
 
-  gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   fast_tpoint_collect_result fast_tp_collecting
     = lwp->collecting_fast_tracepoint;
@@ -4154,7 +3997,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
      inferior right now.  */
   if (signal != 0
       && (lwp->status_pending_p
-         || lwp->pending_signals != NULL
+         || !lwp->pending_signals.empty ()
          || !lwp_signal_can_be_delivered (lwp)))
     {
       enqueue_pending_signal (lwp, signal, info);
@@ -4165,16 +4008,15 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("Not resuming lwp %ld (%s, stop %s);"
-                     " has pending status\n",
-                     lwpid_of (thread), step ? "step" : "continue",
-                     lwp->stop_expected ? "expected" : "not expected");
+      threads_debug_printf
+       ("Not resuming lwp %ld (%s, stop %s); has pending status",
+        lwpid_of (thread), step ? "step" : "continue",
+        lwp->stop_expected ? "expected" : "not expected");
       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,
@@ -4188,9 +4030,8 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
      worthwhile just to solve this one, however.  */
   if (lwp->bp_reinsert != 0)
     {
-      if (debug_threads)
-       debug_printf ("  pending reinsert at 0x%s\n",
-                     paddress (lwp->bp_reinsert));
+      threads_debug_printf ("  pending reinsert at 0x%s",
+                           paddress (lwp->bp_reinsert));
 
       if (supports_hardware_single_step ())
        {
@@ -4208,25 +4049,21 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
     }
 
   if (fast_tp_collecting == fast_tpoint_collect_result::before_insn)
-    {
-      if (debug_threads)
-       debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
-                     " (exit-jump-pad-bkpt)\n",
-                     lwpid_of (thread));
-    }
+    threads_debug_printf
+      ("lwp %ld wants to get out of fast tracepoint jump pad "
+       "(exit-jump-pad-bkpt)", lwpid_of (thread));
+
   else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn)
     {
-      if (debug_threads)
-       debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
-                     " single-stepping\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("lwp %ld wants to get out of fast tracepoint jump pad single-stepping",
+        lwpid_of (thread));
 
       if (supports_hardware_single_step ())
        step = 1;
       else
        {
-         internal_error (__FILE__, __LINE__,
-                         "moving out of jump pad single-stepping"
+         internal_error ("moving out of jump pad single-stepping"
                          " not implemented on this target");
        }
     }
@@ -4241,9 +4078,9 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
      enhancement.  */
   if (thread->while_stepping != NULL)
     {
-      if (debug_threads)
-       debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("lwp %ld has a while-stepping action -> forcing step.",
+        lwpid_of (thread));
 
       step = single_step (lwp);
     }
@@ -4254,36 +4091,27 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
 
       lwp->stop_pc = low_get_pc (regcache);
 
-      if (debug_threads)
-       {
-         debug_printf ("  %s from pc 0x%lx\n", step ? "step" : "continue",
-                       (long) lwp->stop_pc);
-       }
+      threads_debug_printf ("  %s from pc 0x%lx", step ? "step" : "continue",
+                           (long) lwp->stop_pc);
     }
 
   /* If we have pending signals, consume one if it can be delivered to
      the inferior.  */
-  if (lwp->pending_signals != NULL && lwp_signal_can_be_delivered (lwp))
+  if (!lwp->pending_signals.empty () && lwp_signal_can_be_delivered (lwp))
     {
-      struct pending_signals **p_sig;
+      const pending_signal &p_sig = lwp->pending_signals.front ();
 
-      p_sig = &lwp->pending_signals;
-      while ((*p_sig)->prev != NULL)
-       p_sig = &(*p_sig)->prev;
-
-      signal = (*p_sig)->signal;
-      if ((*p_sig)->info.si_signo != 0)
+      signal = p_sig.signal;
+      if (p_sig.info.si_signo != 0)
        ptrace (PTRACE_SETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-               &(*p_sig)->info);
+               &p_sig.info);
 
-      free (*p_sig);
-      *p_sig = NULL;
+      lwp->pending_signals.pop_front ();
     }
 
-  if (debug_threads)
-    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
-                 lwpid_of (thread), step ? "step" : "continue", signal,
-                 lwp->stop_expected ? "expected" : "not expected");
+  threads_debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)",
+                       lwpid_of (thread), step ? "step" : "continue", signal,
+                       lwp->stop_expected ? "expected" : "not expected");
 
   low_prepare_to_resume (lwp);
 
@@ -4303,9 +4131,16 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
             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");
+    {
+      int saved_errno = errno;
+
+      threads_debug_printf ("ptrace errno = %d (%s)",
+                           saved_errno, strerror (saved_errno));
+
+      errno = saved_errno;
+      perror_with_name ("resuming thread");
+    }
 
   /* Successfully resumed.  Clear state that no longer makes sense,
      and mark the LWP as running.  Must not do this before resuming
@@ -4366,7 +4201,15 @@ linux_process_target::resume_one_lwp (lwp_info *lwp, int step, int signal,
     }
   catch (const gdb_exception_error &ex)
     {
-      if (!check_ptrace_stopped_lwp_gone (lwp))
+      if (check_ptrace_stopped_lwp_gone (lwp))
+       {
+         /* This could because we tried to resume an LWP after its leader
+            exited.  Mark it as resumed, so we can collect an exit event
+            from it.  */
+         lwp->stopped = 0;
+         lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
+       }
+      else
        throw;
     }
 }
@@ -4398,13 +4241,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
          if (resume[ndx].kind == resume_stop
              && thread->last_resume_kind == resume_stop)
            {
-             if (debug_threads)
-               debug_printf ("already %s LWP %ld at GDB's request\n",
-                             (thread->last_status.kind
-                              == TARGET_WAITKIND_STOPPED)
-                             ? "stopped"
-                             : "stopping",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("already %s LWP %ld at GDB's request",
+                (thread->last_status.kind () == TARGET_WAITKIND_STOPPED
+                 ? "stopped" : "stopping"),
+                 lwpid_of (thread));
 
              continue;
            }
@@ -4414,13 +4255,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
          if (resume[ndx].kind != resume_stop
              && thread->last_resume_kind != resume_stop)
            {
-             if (debug_threads)
-               debug_printf ("already %s LWP %ld at GDB's request\n",
-                             (thread->last_resume_kind
-                              == resume_step)
-                             ? "stepping"
-                             : "continuing",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("already %s LWP %ld at GDB's request",
+                (thread->last_resume_kind == resume_step
+                 ? "stepping" : "continuing"),
+                lwpid_of (thread));
              continue;
            }
 
@@ -4431,12 +4270,12 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
              struct lwp_info *rel = lwp->fork_relative;
 
              if (rel->status_pending_p
-                 && (rel->waitstatus.kind == TARGET_WAITKIND_FORKED
-                     || rel->waitstatus.kind == TARGET_WAITKIND_VFORKED))
+                 && (rel->waitstatus.kind () == TARGET_WAITKIND_FORKED
+                     || rel->waitstatus.kind () == TARGET_WAITKIND_VFORKED))
                {
-                 if (debug_threads)
-                   debug_printf ("not resuming LWP %ld: has queued stop reply\n",
-                                 lwpid_of (thread));
+                 threads_debug_printf
+                   ("not resuming LWP %ld: has queued stop reply",
+                    lwpid_of (thread));
                  continue;
                }
            }
@@ -4447,9 +4286,9 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
             (wildcard) resume request.  */
          if (in_queued_stop_replies (thread->id))
            {
-             if (debug_threads)
-               debug_printf ("not resuming LWP %ld: has queued stop reply\n",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("not resuming LWP %ld: has queued stop reply",
+                lwpid_of (thread));
              continue;
            }
 
@@ -4468,11 +4307,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
            {
              lwp->status_pending_p = 1;
 
-             if (debug_threads)
-               debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
-                             "leaving status pending.\n",
-                             WSTOPSIG (lwp->status_pending),
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("Dequeueing deferred signal %d for LWP %ld, "
+                "leaving status pending.",
+                WSTOPSIG (lwp->status_pending),
+                lwpid_of (thread));
            }
 
          return;
@@ -4500,7 +4339,6 @@ bool
 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);
 
@@ -4514,18 +4352,16 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
 
   if (!lwp->stopped)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped",
+                           lwpid_of (thread));
       return false;
     }
 
   if (thread->last_resume_kind == resume_stop)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
-                     " stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, should remain stopped",
+        lwpid_of (thread));
       return false;
     }
 
@@ -4533,18 +4369,16 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
 
   if (lwp->suspended)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("Need step over [LWP %ld]? Ignoring, suspended",
+                           lwpid_of (thread));
       return false;
     }
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
-                     " status.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, has pending status.",
+        lwpid_of (thread));
       return false;
     }
 
@@ -4559,30 +4393,28 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
      command, or poked thread's registers herself.  */
   if (pc != lwp->stop_pc)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
-                     "Old stop_pc was 0x%s, PC is now 0x%s\n",
-                     lwpid_of (thread),
-                     paddress (lwp->stop_pc), paddress (pc));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+        "Old stop_pc was 0x%s, PC is now 0x%s", lwpid_of (thread),
+        paddress (lwp->stop_pc), paddress (pc));
       return false;
     }
 
   /* On software single step target, resume the inferior with signal
      rather than stepping over.  */
   if (supports_software_single_step ()
-      && lwp->pending_signals != NULL
+      && !lwp->pending_signals.empty ()
       && lwp_signal_can_be_delivered (lwp))
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
-                     " signals.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, has pending signals.",
+        lwpid_of (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))
@@ -4594,35 +4426,27 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
          && gdb_condition_true_at_breakpoint (pc)
          && gdb_no_commands_at_breakpoint (pc))
        {
-         if (debug_threads)
-           debug_printf ("Need step over [LWP %ld]? yes, but found"
-                         " GDB breakpoint at 0x%s; skipping step over\n",
-                         lwpid_of (thread), paddress (pc));
+         threads_debug_printf ("Need step over [LWP %ld]? yes, but found"
+                               " GDB breakpoint at 0x%s; skipping step over",
+                               lwpid_of (thread), paddress (pc));
 
-         current_thread = saved_thread;
          return false;
        }
       else
        {
-         if (debug_threads)
-           debug_printf ("Need step over [LWP %ld]? yes, "
-                         "found breakpoint at 0x%s\n",
-                         lwpid_of (thread), paddress (pc));
+         threads_debug_printf ("Need step over [LWP %ld]? yes, "
+                               "found breakpoint at 0x%s",
+                               lwpid_of (thread), paddress (pc));
 
          /* 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",
-                 lwpid_of (thread), paddress (pc));
+  threads_debug_printf
+    ("Need step over [LWP %ld]? No, no breakpoint found at 0x%s",
+     lwpid_of (thread), paddress (pc));
 
   return false;
 }
@@ -4631,25 +4455,20 @@ void
 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",
-                 lwpid_of (thread));
+  threads_debug_printf ("Starting step-over on LWP %ld.  Stopping all threads",
+                       lwpid_of (thread));
 
   stop_all_lwps (1, lwp);
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld suspended=%d\n", lwpid_of (thread),
+      internal_error ("LWP %ld suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 
-  if (debug_threads)
-    debug_printf ("Done stopping all threads for step-over.\n");
+  threads_debug_printf ("Done stopping all threads for step-over.");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -4657,16 +4476,17 @@ linux_process_target::start_step_over (lwp_info *lwp)
      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);
 
@@ -4679,12 +4499,11 @@ linux_process_target::finish_step_over (lwp_info *lwp)
 {
   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");
+      threads_debug_printf ("Finished step over.");
 
-      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.  */
@@ -4705,7 +4524,6 @@ linux_process_target::finish_step_over (lwp_info *lwp)
        }
 
       step_over_bkpt = null_ptid;
-      current_thread = saved_thread;
       return true;
     }
   else
@@ -4721,8 +4539,7 @@ linux_process_target::complete_ongoing_step_over ()
       int wstat;
       int ret;
 
-      if (debug_threads)
-       debug_printf ("detach: step over in progress, finish it first\n");
+      threads_debug_printf ("detach: step over in progress, finish it first");
 
       /* Passing NULL_PTID as filter indicates we want all events to
         be left pending.  Eventually this returns when there are no
@@ -4733,7 +4550,30 @@ linux_process_target::complete_ongoing_step_over ()
 
       lwp = find_lwp_pid (step_over_bkpt);
       if (lwp != NULL)
-       finish_step_over (lwp);
+       {
+         finish_step_over (lwp);
+
+         /* If we got our step SIGTRAP, don't leave it pending,
+            otherwise we would report it to GDB as a spurious
+            SIGTRAP.  */
+         gdb_assert (lwp->status_pending_p);
+         if (WIFSTOPPED (lwp->status_pending)
+             && WSTOPSIG (lwp->status_pending) == SIGTRAP)
+           {
+             thread_info *thread = get_lwp_thread (lwp);
+             if (thread->last_resume_kind != resume_step)
+               {
+                 threads_debug_printf ("detach: discard step-over SIGTRAP");
+
+                 lwp->status_pending_p = 0;
+                 lwp->status_pending = 0;
+                 resume_one_lwp (lwp, lwp->stepping, 0, NULL);
+               }
+             else
+               threads_debug_printf
+                 ("detach: resume_step, not discarding step-over SIGTRAP");
+           }
+       }
       step_over_bkpt = null_ptid;
       unsuspend_all_lwps (lwp);
     }
@@ -4751,13 +4591,12 @@ linux_process_target::resume_one_thread (thread_info *thread,
 
   if (lwp->resume->kind == resume_stop)
     {
-      if (debug_threads)
-       debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (thread));
+      threads_debug_printf ("resume_stop request for LWP %ld",
+                           lwpid_of (thread));
 
       if (!lwp->stopped)
        {
-         if (debug_threads)
-           debug_printf ("stopping LWP %ld\n", lwpid_of (thread));
+         threads_debug_printf ("stopping LWP %ld", lwpid_of (thread));
 
          /* Stop the thread, and wait for the event asynchronously,
             through the event loop.  */
@@ -4765,9 +4604,7 @@ linux_process_target::resume_one_thread (thread_info *thread,
        }
       else
        {
-         if (debug_threads)
-           debug_printf ("already stopped LWP %ld\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("already stopped LWP %ld", lwpid_of (thread));
 
          /* The LWP may have been stopped in an internal event that
             was not meant to be notified back to GDB (e.g., gdbserver
@@ -4787,13 +4624,13 @@ linux_process_target::resume_one_thread (thread_info *thread,
             midway through moving the LWP out of the jumppad, and we
             will report the pending signal as soon as that is
             finished.  */
-         if (lwp->pending_signals_to_report == NULL)
+         if (lwp->pending_signals_to_report.empty ())
            send_sigstop (lwp);
        }
 
       /* For stop requests, we're done.  */
       lwp->resume = NULL;
-      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      thread->last_status.set_ignore ();
       return;
     }
 
@@ -4829,18 +4666,14 @@ linux_process_target::resume_one_thread (thread_info *thread,
 
   if (!leave_pending)
     {
-      if (debug_threads)
-       debug_printf ("resuming LWP %ld\n", lwpid_of (thread));
+      threads_debug_printf ("resuming LWP %ld", lwpid_of (thread));
 
       proceed_one_lwp (thread, NULL);
     }
   else
-    {
-      if (debug_threads)
-       debug_printf ("leaving LWP %ld stopped\n", lwpid_of (thread));
-    }
+    threads_debug_printf ("leaving LWP %ld stopped", lwpid_of (thread));
 
-  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  thread->last_status.set_ignore ();
   lwp->resume = NULL;
 }
 
@@ -4849,11 +4682,7 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
 {
   struct thread_info *need_step_over = NULL;
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("linux_resume:\n");
-    }
+ THREADS_SCOPED_DEBUG_ENTER_EXIT;
 
   for_each_thread ([&] (thread_info *thread)
     {
@@ -4887,16 +4716,13 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
 
   bool leave_all_stopped = (need_step_over != NULL || any_pending);
 
-  if (debug_threads)
-    {
-      if (need_step_over != NULL)
-       debug_printf ("Not resuming all, need step over\n");
-      else if (any_pending)
-       debug_printf ("Not resuming, all-stop and found "
-                     "an LWP with pending status\n");
-      else
-       debug_printf ("Resuming, no pending status or step over needed\n");
-    }
+  if (need_step_over != NULL)
+    threads_debug_printf ("Not resuming all, need step over");
+  else if (any_pending)
+    threads_debug_printf ("Not resuming, all-stop and found "
+                         "an LWP with pending status");
+  else
+    threads_debug_printf ("Resuming, no pending status or step over needed");
 
   /* Even if we're leaving threads stopped, queue all signals we'd
      otherwise deliver.  */
@@ -4908,12 +4734,6 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
   if (need_step_over)
     start_step_over (get_thread_lwp (need_step_over));
 
-  if (debug_threads)
-    {
-      debug_printf ("linux_resume done\n");
-      debug_exit ();
-    }
-
   /* We may have events that were pending that can/should be sent to
      the client now.  Trigger a linux_wait call.  */
   if (target_is_async_p ())
@@ -4929,30 +4749,26 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
   if (lwp == except)
     return;
 
-  if (debug_threads)
-    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (thread));
+  threads_debug_printf ("lwp %ld", lwpid_of (thread));
 
   if (!lwp->stopped)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld already running\n", lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld already running", lwpid_of (thread));
       return;
     }
 
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () != TARGET_WAITKIND_IGNORE)
     {
-      if (debug_threads)
-       debug_printf ("   client wants LWP to remain %ld stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   client wants LWP to remain %ld stopped",
+                           lwpid_of (thread));
       return;
     }
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld has pending status, leaving stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld has pending status, leaving stopped",
+                           lwpid_of (thread));
       return;
     }
 
@@ -4960,13 +4776,12 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
 
   if (lwp->suspended)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld is suspended\n", lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld is suspended", lwpid_of (thread));
       return;
     }
 
   if (thread->last_resume_kind == resume_stop
-      && lwp->pending_signals_to_report == NULL
+      && lwp->pending_signals_to_report.empty ()
       && (lwp->collecting_fast_tracepoint
          == fast_tpoint_collect_result::not_collecting))
     {
@@ -4980,19 +4795,17 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
         another one here.  Note that if the LWP already has a SIGSTOP
         pending, this is a no-op.  */
 
-      if (debug_threads)
-       debug_printf ("Client wants LWP %ld to stop. "
-                     "Making sure it has a SIGSTOP pending\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Client wants LWP %ld to stop.  Making sure it has a SIGSTOP pending",
+        lwpid_of (thread));
 
       send_sigstop (lwp);
     }
 
   if (thread->last_resume_kind == resume_step)
     {
-      if (debug_threads)
-       debug_printf ("   stepping LWP %ld, client wants it stepping\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   stepping LWP %ld, client wants it stepping",
+                           lwpid_of (thread));
 
       /* If resume_step is requested by GDB, install single-step
         breakpoints when the thread is about to be actually resumed if
@@ -5005,9 +4818,8 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
     }
   else if (lwp->bp_reinsert != 0)
     {
-      if (debug_threads)
-       debug_printf ("   stepping LWP %ld, reinsert set\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   stepping LWP %ld, reinsert set",
+                           lwpid_of (thread));
 
       step = maybe_hw_step (thread);
     }
@@ -5050,18 +4862,15 @@ linux_process_target::proceed_all_lwps ()
 
       if (need_step_over != NULL)
        {
-         if (debug_threads)
-           debug_printf ("proceed_all_lwps: found "
-                         "thread %ld needing a step-over\n",
-                         lwpid_of (need_step_over));
+         threads_debug_printf ("found thread %ld needing a step-over",
+                               lwpid_of (need_step_over));
 
          start_step_over (get_thread_lwp (need_step_over));
          return;
        }
     }
 
-  if (debug_threads)
-    debug_printf ("Proceeding, no step-over needed\n");
+  threads_debug_printf ("Proceeding, no step-over needed");
 
   for_each_thread ([this] (thread_info *thread)
     {
@@ -5072,15 +4881,13 @@ linux_process_target::proceed_all_lwps ()
 void
 linux_process_target::unstop_all_lwps (int unsuspend, lwp_info *except)
 {
-  if (debug_threads)
-    {
-      debug_enter ();
-      if (except)
-       debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
-                     lwpid_of (get_lwp_thread (except)));
-      else
-       debug_printf ("unstopping all lwps\n");
-    }
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
+  if (except)
+    threads_debug_printf ("except=(LWP %ld)",
+                 lwpid_of (get_lwp_thread (except)));
+  else
+    threads_debug_printf ("except=nullptr");
 
   if (unsuspend)
     for_each_thread ([&] (thread_info *thread)
@@ -5092,12 +4899,6 @@ linux_process_target::unstop_all_lwps (int unsuspend, lwp_info *except)
       {
        proceed_one_lwp (thread, except);
       });
-
-  if (debug_threads)
-    {
-      debug_printf ("unstop_all_lwps done\n");
-      debug_exit ();
-    }
 }
 
 
@@ -5552,93 +5353,71 @@ linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
   return the_target->read_memory (memaddr, myaddr, len);
 }
 
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
-   to debugger memory starting at MYADDR.  */
 
-int
-linux_process_target::read_memory (CORE_ADDR memaddr,
-                                  unsigned char *myaddr, int len)
+/* Helper for read_memory/write_memory using /proc/PID/mem.  Because
+   we can use a single read/write call, this can be much more
+   efficient than banging away at PTRACE_PEEKTEXT.  Also, unlike
+   PTRACE_PEEKTEXT/PTRACE_POKETEXT, this works with running threads.
+   One an only one of READBUF and WRITEBUF is non-null.  If READBUF is
+   not null, then we're reading, otherwise we're writing.  */
+
+static int
+proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,
+                 const gdb_byte *writebuf, int len)
 {
-  int pid = lwpid_of (current_thread);
-  PTRACE_XFER_TYPE *buffer;
-  CORE_ADDR addr;
-  int count;
-  char filename[64];
-  int i;
-  int ret;
-  int fd;
+  gdb_assert ((readbuf == nullptr) != (writebuf == nullptr));
+
+  process_info *proc = current_process ();
 
-  /* Try using /proc.  Don't bother for one word.  */
-  if (len >= 3 * sizeof (long))
+  int fd = proc->priv->mem_fd;
+  if (fd == -1)
+    return EIO;
+
+  while (len > 0)
     {
       int bytes;
 
-      /* We could keep this file open and cache it - possibly one per
-        thread.  That requires some juggling, but is even faster.  */
-      sprintf (filename, "/proc/%d/mem", pid);
-      fd = open (filename, O_RDONLY | O_LARGEFILE);
-      if (fd == -1)
-       goto no_proc;
-
       /* If pread64 is available, use it.  It's faster if the kernel
         supports it (only one syscall), and it's 64-bit safe even on
         32-bit platforms (for instance, SPARC debugging a SPARC64
         application).  */
 #ifdef HAVE_PREAD64
-      bytes = pread64 (fd, myaddr, len, memaddr);
+      bytes = (readbuf != nullptr
+              ? pread64 (fd, readbuf, len, memaddr)
+              : pwrite64 (fd, writebuf, len, memaddr));
 #else
       bytes = -1;
       if (lseek (fd, memaddr, SEEK_SET) != -1)
-       bytes = read (fd, myaddr, len);
+       bytes = (readbuf != nullptr
+                ? read (fd, readbuf, len)
+                : write (fd, writebuf, len));
 #endif
 
-      close (fd);
-      if (bytes == len)
-       return 0;
-
-      /* Some data was read, we'll try to get the rest with ptrace.  */
-      if (bytes > 0)
+      if (bytes < 0)
+       return errno;
+      else if (bytes == 0)
        {
-         memaddr += bytes;
-         myaddr += bytes;
-         len -= bytes;
+         /* EOF means the address space is gone, the whole process
+            exited or execed.  */
+         return EIO;
        }
-    }
-
- no_proc:
-  /* Round starting address down to longword boundary.  */
-  addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
-          / sizeof (PTRACE_XFER_TYPE));
-  /* Allocate buffer of that many longwords.  */
-  buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
 
-  /* Read all the longwords */
-  errno = 0;
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
-    {
-      /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
-        about coercing an 8 byte integer to a 4 byte pointer.  */
-      buffer[i] = ptrace (PTRACE_PEEKTEXT, pid,
-                         (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-                         (PTRACE_TYPE_ARG4) 0);
-      if (errno)
-       break;
+      memaddr += bytes;
+      if (readbuf != nullptr)
+       readbuf += bytes;
+      else
+       writebuf += bytes;
+      len -= bytes;
     }
-  ret = errno;
 
-  /* Copy appropriate bytes out of the buffer.  */
-  if (i > 0)
-    {
-      i *= sizeof (PTRACE_XFER_TYPE);
-      i -= memaddr & (sizeof (PTRACE_XFER_TYPE) - 1);
-      memcpy (myaddr,
-             (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
-             i < len ? i : len);
-    }
+  return 0;
+}
 
-  return ret;
+int
+linux_process_target::read_memory (CORE_ADDR memaddr,
+                                  unsigned char *myaddr, int len)
+{
+  return proc_xfer_memory (memaddr, myaddr, nullptr, len);
 }
 
 /* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
@@ -5649,25 +5428,6 @@ int
 linux_process_target::write_memory (CORE_ADDR memaddr,
                                    const unsigned char *myaddr, int len)
 {
-  int i;
-  /* Round starting address down to longword boundary.  */
-  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  int count
-    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
-    / sizeof (PTRACE_XFER_TYPE);
-
-  /* Allocate buffer of that many longwords.  */
-  PTRACE_XFER_TYPE *buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
-
-  int pid = lwpid_of (current_thread);
-
-  if (len == 0)
-    {
-      /* Zero length write always succeeds.  */
-      return 0;
-    }
-
   if (debug_threads)
     {
       /* Dump up to four bytes.  */
@@ -5675,62 +5435,18 @@ linux_process_target::write_memory (CORE_ADDR memaddr,
       char *p = str;
       int dump = len < 4 ? len : 4;
 
-      for (i = 0; i < dump; i++)
+      for (int i = 0; i < dump; i++)
        {
          sprintf (p, "%02x", myaddr[i]);
          p += 2;
        }
       *p = '\0';
 
-      debug_printf ("Writing %s to 0x%08lx in process %d\n",
-                   str, (long) memaddr, pid);
-    }
-
-  /* Fill start and end extra bytes of buffer with existing memory data.  */
-
-  errno = 0;
-  /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
-     about coercing an 8 byte integer to a 4 byte pointer.  */
-  buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
-                     (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-                     (PTRACE_TYPE_ARG4) 0);
-  if (errno)
-    return errno;
-
-  if (count > 1)
-    {
-      errno = 0;
-      buffer[count - 1]
-       = ptrace (PTRACE_PEEKTEXT, pid,
-                 /* Coerce to a uintptr_t first to avoid potential gcc warning
-                    about coercing an 8 byte integer to a 4 byte pointer.  */
-                 (PTRACE_TYPE_ARG3) (uintptr_t) (addr + (count - 1)
-                                                 * sizeof (PTRACE_XFER_TYPE)),
-                 (PTRACE_TYPE_ARG4) 0);
-      if (errno)
-       return errno;
-    }
-
-  /* Copy data to be written over corresponding part of buffer.  */
-
-  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
-         myaddr, len);
-
-  /* Write the entire buffer.  */
-
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
-    {
-      errno = 0;
-      ptrace (PTRACE_POKETEXT, pid,
-             /* Coerce to a uintptr_t first to avoid potential gcc warning
-                about coercing an 8 byte integer to a 4 byte pointer.  */
-             (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-             (PTRACE_TYPE_ARG4) buffer[i]);
-      if (errno)
-       return errno;
+      threads_debug_printf ("Writing %s to 0x%08lx in process %d",
+                           str, (long) memaddr, current_process ()->pid);
     }
 
-  return 0;
+  return proc_xfer_memory (memaddr, nullptr, myaddr, len);
 }
 
 void
@@ -5751,7 +5467,10 @@ linux_process_target::request_interrupt ()
 {
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  */
-  ::kill (-signal_pid, SIGINT);
+  int res = ::kill (-signal_pid, SIGINT);
+  if (res == -1)
+    warning (_("Sending SIGINT to process group of pid %ld failed: %s"),
+            signal_pid, safe_strerror (errno));
 }
 
 bool
@@ -5764,12 +5483,11 @@ linux_process_target::supports_read_auxv ()
    to debugger memory starting at MYADDR.  */
 
 int
-linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
-                                unsigned int len)
+linux_process_target::read_auxv (int pid, CORE_ADDR offset,
+                                unsigned char *myaddr, unsigned int len)
 {
   char filename[PATH_MAX];
   int fd, n;
-  int pid = lwpid_of (current_thread);
 
   xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
 
@@ -6027,10 +5745,9 @@ linux_process_target::qxfer_siginfo (const char *annex,
 
   pid = lwpid_of (current_thread);
 
-  if (debug_threads)
-    debug_printf ("%s siginfo for lwp %d.\n",
-                 readbuf != NULL ? "Reading" : "Writing",
-                 pid);
+  threads_debug_printf ("%s siginfo for lwp %d.",
+                       readbuf != NULL ? "Reading" : "Writing",
+                       pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -6100,9 +5817,8 @@ linux_process_target::async (bool enable)
 {
   bool previous = target_is_async_p ();
 
-  if (debug_threads)
-    debug_printf ("linux_async (%d), previous=%d\n",
-                 enable, previous);
+  threads_debug_printf ("async (%d), previous=%d",
+                       enable, previous);
 
   if (previous != enable)
     {
@@ -6114,34 +5830,27 @@ linux_process_target::async (bool enable)
 
       if (enable)
        {
-         if (pipe (linux_event_pipe) == -1)
+         if (!linux_event_pipe.open_pipe ())
            {
-             linux_event_pipe[0] = -1;
-             linux_event_pipe[1] = -1;
              gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
 
              warning ("creating event pipe failed.");
              return previous;
            }
 
-         fcntl (linux_event_pipe[0], F_SETFL, O_NONBLOCK);
-         fcntl (linux_event_pipe[1], F_SETFL, O_NONBLOCK);
-
          /* Register the event loop handler.  */
-         add_file_handler (linux_event_pipe[0],
-                           handle_target_event, NULL);
+         add_file_handler (linux_event_pipe.event_fd (),
+                           handle_target_event, NULL,
+                           "linux-low");
 
          /* Always trigger a linux_wait.  */
          async_file_mark ();
        }
       else
        {
-         delete_file_handler (linux_event_pipe[0]);
+         delete_file_handler (linux_event_pipe.event_fd ());
 
-         close (linux_event_pipe[0]);
-         close (linux_event_pipe[1]);
-         linux_event_pipe[0] = -1;
-         linux_event_pipe[1] = -1;
+         linux_event_pipe.close_pipe ();
        }
 
       gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
@@ -6173,7 +5882,7 @@ linux_process_target::supports_multi_process ()
 bool
 linux_process_target::supports_fork_events ()
 {
-  return linux_supports_tracefork ();
+  return true;
 }
 
 /* Check if vfork events are supported.  */
@@ -6181,7 +5890,7 @@ linux_process_target::supports_fork_events ()
 bool
 linux_process_target::supports_vfork_events ()
 {
-  return linux_supports_tracefork ();
+  return true;
 }
 
 /* Check if exec events are supported.  */
@@ -6189,7 +5898,7 @@ linux_process_target::supports_vfork_events ()
 bool
 linux_process_target::supports_exec_events ()
 {
-  return linux_supports_traceexec ();
+  return true;
 }
 
 /* Target hook for 'handle_new_gdb_connection'.  Causes a reset of the
@@ -6241,11 +5950,7 @@ linux_process_target::core_of_thread (ptid_t ptid)
 bool
 linux_process_target::supports_disable_randomization ()
 {
-#ifdef HAVE_PERSONALITY
   return true;
-#else
-  return false;
-#endif
 }
 
 bool
@@ -6275,7 +5980,7 @@ linux_process_target::supports_pid_to_exec_file ()
   return true;
 }
 
-char *
+const char *
 linux_process_target::pid_to_exec_file (int pid)
 {
   return linux_proc_pid_to_exec_file (pid);
@@ -6392,8 +6097,7 @@ linux_process_target::read_loadmap (const char *annex, CORE_ADDR offset,
 bool
 linux_process_target::supports_catch_syscall ()
 {
-  return (low_supports_catch_syscall ()
-         && linux_supports_tracesysgood ());
+  return low_supports_catch_syscall ();
 }
 
 bool
@@ -6448,25 +6152,6 @@ linux_process_target::unpause_all (bool unfreeze)
   unstop_all_lwps (unfreeze, NULL);
 }
 
-int
-linux_process_target::prepare_to_access_memory ()
-{
-  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
-     running LWP.  */
-  if (non_stop)
-    target_pause_all (true);
-  return 0;
-}
-
-void
-linux_process_target::done_accessing_memory ()
-{
-  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
-     running LWP.  */
-  if (non_stop)
-    target_unpause_all (true);
-}
-
 /* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */
 
 static int
@@ -6754,6 +6439,9 @@ struct link_map_offsets
     /* Offset and size of r_debug.r_map.  */
     int r_map_offset;
 
+    /* Offset of r_debug_extended.r_next.  */
+    int r_next_offset;
+
     /* Offset to l_addr field in struct link_map.  */
     int l_addr_offset;
 
@@ -6770,6 +6458,79 @@ struct link_map_offsets
     int l_prev_offset;
   };
 
+static const link_map_offsets lmo_32bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    4,     /* r_debug.r_map offset.  */
+    20,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    4,     /* l_name offset in link_map.  */
+    8,     /* l_ld offset in link_map.  */
+    12,    /* l_next offset in link_map.  */
+    16     /* l_prev offset in link_map.  */
+  };
+
+static const link_map_offsets lmo_64bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    8,     /* r_debug.r_map offset.  */
+    40,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    8,     /* l_name offset in link_map.  */
+    16,    /* l_ld offset in link_map.  */
+    24,    /* l_next offset in link_map.  */
+    32     /* l_prev offset in link_map.  */
+  };
+
+/* Get the loaded shared libraries from one namespace.  */
+
+static void
+read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr,
+              CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo)
+{
+  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
+
+  while (lm_addr
+        && read_one_ptr (lm_addr + lmo->l_name_offset,
+                         &l_name, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_addr_offset,
+                         &l_addr, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_ld_offset,
+                         &l_ld, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_prev_offset,
+                         &l_prev, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_next_offset,
+                         &l_next, ptr_size) == 0)
+    {
+      unsigned char libname[PATH_MAX];
+
+      if (lm_prev != l_prev)
+       {
+         warning ("Corrupted shared library list: 0x%s != 0x%s",
+                  paddress (lm_prev), paddress (l_prev));
+         break;
+       }
+
+      /* Not checking for error because reading may stop before we've got
+        PATH_MAX worth of characters.  */
+      libname[0] = '\0';
+      linux_read_memory (l_name, libname, sizeof (libname) - 1);
+      libname[sizeof (libname) - 1] = '\0';
+      if (libname[0] != '\0')
+       {
+         string_appendf (document, "<library name=\"");
+         xml_escape_text_append (document, (char *) libname);
+         string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+                         "l_ld=\"0x%s\" lmid=\"0x%s\"/>",
+                         paddress (lm_addr), paddress (l_addr),
+                         paddress (l_ld), paddress (lmid));
+       }
+
+      lm_prev = lm_addr;
+      lm_addr = l_next;
+    }
+}
+
 /* Construct qXfer:libraries-svr4:read reply.  */
 
 int
@@ -6781,34 +6542,8 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   struct process_info_private *const priv = current_process ()->priv;
   char filename[PATH_MAX];
   int pid, is_elf64;
-
-  static const struct link_map_offsets lmo_32bit_offsets =
-    {
-      0,     /* r_version offset. */
-      4,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      4,     /* l_name offset in link_map.  */
-      8,     /* l_ld offset in link_map.  */
-      12,    /* l_next offset in link_map.  */
-      16     /* l_prev offset in link_map.  */
-    };
-
-  static const struct link_map_offsets lmo_64bit_offsets =
-    {
-      0,     /* r_version offset. */
-      8,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      8,     /* l_name offset in link_map.  */
-      16,    /* l_ld offset in link_map.  */
-      24,    /* l_next offset in link_map.  */
-      32     /* l_prev offset in link_map.  */
-    };
-  const struct link_map_offsets *lmo;
   unsigned int machine;
-  int ptr_size;
-  CORE_ADDR lm_addr = 0, lm_prev = 0;
-  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
-  int header_done = 0;
+  CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0;
 
   if (writebuf != NULL)
     return -2;
@@ -6818,8 +6553,18 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   pid = lwpid_of (current_thread);
   xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
   is_elf64 = elf_64_file_p (filename, &machine);
-  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
-  ptr_size = is_elf64 ? 8 : 4;
+  const link_map_offsets *lmo;
+  int ptr_size;
+  if (is_elf64)
+    {
+      lmo = &lmo_64bit_offsets;
+      ptr_size = 8;
+    }
+  else
+    {
+      lmo = &lmo_32bit_offsets;
+      ptr_size = 4;
+    }
 
   while (annex[0] != '\0')
     {
@@ -6832,7 +6577,9 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
        break;
 
       name_len = sep - annex;
-      if (name_len == 5 && startswith (annex, "start"))
+      if (name_len == 4 && startswith (annex, "lmid"))
+       addrp = &lmid;
+      else if (name_len == 5 && startswith (annex, "start"))
        addrp = &lm_addr;
       else if (name_len == 4 && startswith (annex, "prev"))
        addrp = &lm_prev;
@@ -6848,104 +6595,109 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
       annex = decode_address_to_semicolon (addrp, sep + 1);
     }
 
-  if (lm_addr == 0)
+  std::string document = "<library-list-svr4 version=\"1.0\"";
+
+  /* When the starting LM_ADDR is passed in the annex, only traverse that
+     namespace, which is assumed to be identified by LMID.
+
+     Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
+  if (lm_addr != 0)
     {
-      int r_version = 0;
+      document += ">";
+      read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo);
+    }
+  else
+    {
+      if (lm_prev != 0)
+       warning ("ignoring prev=0x%s without start", paddress (lm_prev));
 
-      if (priv->r_debug == 0)
-       priv->r_debug = get_r_debug (pid, is_elf64);
+      /* We could interpret LMID as 'provide only the libraries for this
+        namespace' but GDB is currently only providing lmid, start, and
+        prev, or nothing.  */
+      if (lmid != 0)
+       warning ("ignoring lmid=0x%s without start", paddress (lmid));
+
+      CORE_ADDR r_debug = priv->r_debug;
+      if (r_debug == 0)
+       r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
 
       /* We failed to find DT_DEBUG.  Such situation will not change
         for this inferior - do not retry it.  Report it to GDB as
         E01, see for the reasons at the GDB solib-svr4.c side.  */
-      if (priv->r_debug == (CORE_ADDR) -1)
+      if (r_debug == (CORE_ADDR) -1)
        return -1;
 
-      if (priv->r_debug != 0)
+      /* Terminate the header if we end up with an empty list.  */
+      if (r_debug == 0)
+       document += ">";
+
+      while (r_debug != 0)
        {
-         if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+         int r_version = 0;
+         if (linux_read_memory (r_debug + lmo->r_version_offset,
                                 (unsigned char *) &r_version,
-                                sizeof (r_version)) != 0
-             || r_version != 1)
+                                sizeof (r_version)) != 0)
            {
-             warning ("unexpected r_debug version %d", r_version);
+             warning ("unable to read r_version from 0x%s",
+                      paddress (r_debug + lmo->r_version_offset));
+             break;
            }
-         else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
-                                &lm_addr, ptr_size) != 0)
+
+         if (r_version < 1)
            {
-             warning ("unable to read r_map from 0x%lx",
-                      (long) priv->r_debug + lmo->r_map_offset);
+             warning ("unexpected r_debug version %d", r_version);
+             break;
            }
-       }
-    }
-
-  std::string document = "<library-list-svr4 version=\"1.0\"";
 
-  while (lm_addr
-        && read_one_ptr (lm_addr + lmo->l_name_offset,
-                         &l_name, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_addr_offset,
-                         &l_addr, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_ld_offset,
-                         &l_ld, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_prev_offset,
-                         &l_prev, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_next_offset,
-                         &l_next, ptr_size) == 0)
-    {
-      unsigned char libname[PATH_MAX];
+         if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_map from 0x%s",
+                      paddress (r_debug + lmo->r_map_offset));
+             break;
+           }
 
-      if (lm_prev != l_prev)
-       {
-         warning ("Corrupted shared library list: 0x%lx != 0x%lx",
-                  (long) lm_prev, (long) l_prev);
-         break;
-       }
+         /* We read the entire namespace.  */
+         lm_prev = 0;
 
-      /* Ignore the first entry even if it has valid name as the first entry
-        corresponds to the main executable.  The first entry should not be
-        skipped if the dynamic loader was loaded late by a static executable
-        (see solib-svr4.c parameter ignore_first).  But in such case the main
-        executable does not have PT_DYNAMIC present and this function already
-        exited above due to failed get_r_debug.  */
-      if (lm_prev == 0)
-       string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
-      else
-       {
-         /* Not checking for error because reading may stop before
-            we've got PATH_MAX worth of characters.  */
-         libname[0] = '\0';
-         linux_read_memory (l_name, libname, sizeof (libname) - 1);
-         libname[sizeof (libname) - 1] = '\0';
-         if (libname[0] != '\0')
+         /* The first entry corresponds to the main executable unless the
+            dynamic loader was loaded late by a static executable.  But
+            in such case the main executable does not have PT_DYNAMIC
+            present and we would not have gotten here.  */
+         if (r_debug == priv->r_debug)
            {
-             if (!header_done)
+             if (lm_addr != 0)
+               string_appendf (document, " main-lm=\"0x%s\">",
+                               paddress (lm_addr));
+             else
+               document += ">";
+
+             lm_prev = lm_addr;
+             if (read_one_ptr (lm_addr + lmo->l_next_offset,
+                               &lm_addr, ptr_size) != 0)
                {
-                 /* Terminate `<library-list-svr4'.  */
-                 document += '>';
-                 header_done = 1;
+                 warning ("unable to read l_next from 0x%s",
+                          paddress (lm_addr + lmo->l_next_offset));
+                 break;
                }
+           }
+
+         read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo);
+
+         if (r_version < 2)
+           break;
 
-             string_appendf (document, "<library name=\"");
-             xml_escape_text_append (&document, (char *) libname);
-             string_appendf (document, "\" lm=\"0x%lx\" "
-                             "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
-                             (unsigned long) lm_addr, (unsigned long) l_addr,
-                             (unsigned long) l_ld);
+         if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_next from 0x%s",
+                      paddress (r_debug + lmo->r_next_offset));
+             break;
            }
        }
-
-      lm_prev = lm_addr;
-      lm_addr = l_next;
     }
 
-  if (!header_done)
-    {
-      /* Empty list; terminate `<library-list-svr4'.  */
-      document += "/>";
-    }
-  else
-    document += "</library-list-svr4>";
+  document += "</library-list-svr4>";
 
   int document_len = document.length ();
   if (offset < document_len)
@@ -6962,11 +6714,17 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 
 #ifdef HAVE_LINUX_BTRACE
 
+bool
+linux_process_target::supports_btrace ()
+{
+  return true;
+}
+
 btrace_target_info *
-linux_process_target::enable_btrace (ptid_t ptid,
+linux_process_target::enable_btrace (thread_info *tp,
                                     const btrace_config *conf)
 {
-  return linux_enable_btrace (ptid, conf);
+  return linux_enable_btrace (tp->id, conf);
 }
 
 /* See to_disable_btrace target method.  */
@@ -6983,38 +6741,38 @@ linux_process_target::disable_btrace (btrace_target_info *tinfo)
 /* Encode an Intel Processor Trace configuration.  */
 
 static void
-linux_low_encode_pt_config (struct buffer *buffer,
+linux_low_encode_pt_config (std::string *buffer,
                            const struct btrace_data_pt_config *config)
 {
-  buffer_grow_str (buffer, "<pt-config>\n");
+  *buffer += "<pt-config>\n";
 
   switch (config->cpu.vendor)
     {
     case CV_INTEL:
-      buffer_xml_printf (buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
-                        "model=\"%u\" stepping=\"%u\"/>\n",
-                        config->cpu.family, config->cpu.model,
-                        config->cpu.stepping);
+      string_xml_appendf (*buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
+                         "model=\"%u\" stepping=\"%u\"/>\n",
+                         config->cpu.family, config->cpu.model,
+                         config->cpu.stepping);
       break;
 
     default:
       break;
     }
 
-  buffer_grow_str (buffer, "</pt-config>\n");
+  *buffer += "</pt-config>\n";
 }
 
 /* Encode a raw buffer.  */
 
 static void
-linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
+linux_low_encode_raw (std::string *buffer, const gdb_byte *data,
                      unsigned int size)
 {
   if (size == 0)
     return;
 
   /* We use hex encoding - see gdbsupport/rsp-low.h.  */
-  buffer_grow_str (buffer, "<raw>\n");
+  *buffer += "<raw>\n";
 
   while (size-- > 0)
     {
@@ -7023,17 +6781,17 @@ linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
       elem[0] = tohex ((*data >> 4) & 0xf);
       elem[1] = tohex (*data++ & 0xf);
 
-      buffer_grow (buffer, elem, 2);
+      buffer->append (elem, 2);
     }
 
-  buffer_grow_str (buffer, "</raw>\n");
+  *buffer += "</raw>\n";
 }
 
 /* See to_read_btrace target method.  */
 
 int
 linux_process_target::read_btrace (btrace_target_info *tinfo,
-                                  buffer *buffer,
+                                  std::string *buffer,
                                   enum btrace_read_type type)
 {
   struct btrace_data btrace;
@@ -7043,9 +6801,9 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   if (err != BTRACE_ERR_NONE)
     {
       if (err == BTRACE_ERR_OVERFLOW)
-       buffer_grow_str0 (buffer, "E.Overflow.");
+       *buffer += "E.Overflow.";
       else
-       buffer_grow_str0 (buffer, "E.Generic Error.");
+       *buffer += "E.Generic Error.";
 
       return -1;
     }
@@ -7053,36 +6811,36 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   switch (btrace.format)
     {
     case BTRACE_FORMAT_NONE:
-      buffer_grow_str0 (buffer, "E.No Trace.");
+      *buffer += "E.No Trace.";
       return -1;
 
     case BTRACE_FORMAT_BTS:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
 
       for (const btrace_block &block : *btrace.variant.bts.blocks)
-       buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
-                          paddress (block.begin), paddress (block.end));
+       string_xml_appendf (*buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+                           paddress (block.begin), paddress (block.end));
 
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</btrace>\n";
       break;
 
     case BTRACE_FORMAT_PT:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
-      buffer_grow_str (buffer, "<pt>\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
+      *buffer += "<pt>\n";
 
       linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);
 
       linux_low_encode_raw (buffer, btrace.variant.pt.data,
                            btrace.variant.pt.size);
 
-      buffer_grow_str (buffer, "</pt>\n");
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</pt>\n";
+      *buffer += "</btrace>\n";
       break;
 
     default:
-      buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
+      *buffer += "E.Unsupported Trace Format.";
       return -1;
     }
 
@@ -7093,12 +6851,12 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
 
 int
 linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
-                                       buffer *buffer)
+                                       std::string *buffer)
 {
   const struct btrace_config *conf;
 
-  buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
-  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
+  *buffer += "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n";
+  *buffer += "<btrace-conf version=\"1.0\">\n";
 
   conf = linux_btrace_conf (tinfo);
   if (conf != NULL)
@@ -7109,20 +6867,20 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
          break;
 
        case BTRACE_FORMAT_BTS:
-         buffer_xml_printf (buffer, "<bts");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->bts.size);
-         buffer_xml_printf (buffer, " />\n");
+         string_xml_appendf (*buffer, "<bts");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->bts.size);
+         string_xml_appendf (*buffer, " />\n");
          break;
 
        case BTRACE_FORMAT_PT:
-         buffer_xml_printf (buffer, "<pt");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->pt.size);
-         buffer_xml_printf (buffer, "/>\n");
+         string_xml_appendf (*buffer, "<pt");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->pt.size);
+         string_xml_appendf (*buffer, "/>\n");
          break;
        }
     }
 
-  buffer_grow_str0 (buffer, "</btrace-conf>\n");
+  *buffer += "</btrace-conf>\n";
   return 0;
 }
 #endif /* HAVE_LINUX_BTRACE */
@@ -7150,6 +6908,28 @@ linux_process_target::thread_handle (ptid_t ptid, gdb_byte **handle,
 }
 #endif
 
+thread_info *
+linux_process_target::thread_pending_parent (thread_info *thread)
+{
+  lwp_info *parent = get_thread_lwp (thread)->pending_parent ();
+
+  if (parent == nullptr)
+    return nullptr;
+
+  return get_lwp_thread (parent);
+}
+
+thread_info *
+linux_process_target::thread_pending_child (thread_info *thread)
+{
+  lwp_info *child = get_thread_lwp (thread)->pending_child ();
+
+  if (child == nullptr)
+    return nullptr;
+
+  return get_lwp_thread (child);
+}
+
 /* Default implementation of linux_target_ops method "set_pc" for
    32-bit pc register which is literally named "pc".  */
 
@@ -7170,8 +6950,7 @@ linux_get_pc_32bit (struct regcache *regcache)
   uint32_t pc;
 
   collect_register_by_name (regcache, "pc", &pc);
-  if (debug_threads)
-    debug_printf ("stop pc is 0x%" PRIx32 "\n", pc);
+  threads_debug_printf ("stop pc is 0x%" PRIx32, pc);
   return pc;
 }
 
@@ -7195,22 +6974,22 @@ linux_get_pc_64bit (struct regcache *regcache)
   uint64_t pc;
 
   collect_register_by_name (regcache, "pc", &pc);
-  if (debug_threads)
-    debug_printf ("stop pc is 0x%" PRIx64 "\n", pc);
+  threads_debug_printf ("stop pc is 0x%" PRIx64, pc);
   return pc;
 }
 
 /* See linux-low.h.  */
 
 int
-linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
+linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 {
   gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
   int offset = 0;
 
   gdb_assert (wordsize == 4 || wordsize == 8);
 
-  while (the_target->read_auxv (offset, data, 2 * wordsize) == 2 * wordsize)
+  while (the_target->read_auxv (pid, offset, data, 2 * wordsize)
+        == 2 * wordsize)
     {
       if (wordsize == 4)
        {
@@ -7240,20 +7019,20 @@ linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap (int wordsize)
+linux_get_hwcap (int pid, int wordsize)
 {
   CORE_ADDR hwcap = 0;
-  linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+  linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap);
   return hwcap;
 }
 
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap2 (int wordsize)
+linux_get_hwcap2 (int pid, int wordsize)
 {
   CORE_ADDR hwcap2 = 0;
-  linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+  linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2);
   return hwcap2;
 }