gdb+gdbserver/Linux: avoid reading registers while going through shell
[binutils-gdb.git] / gdb / linux-nat.c
index 133b87ca742cf00f3481673a20e8b80f41aaf746..0a93ab5c6ae534125d161eb59859be1fc2c48df1 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001-2020 Free Software Foundation, Inc.
+   Copyright (C) 2001-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -47,7 +47,7 @@
 #include <sys/stat.h>          /* for struct stat */
 #include <fcntl.h>             /* for O_RDONLY */
 #include "inf-loop.h"
-#include "event-loop.h"
+#include "gdbsupport/event-loop.h"
 #include "event-top.h"
 #include <pwd.h>
 #include <sys/types.h>
 #include "gdbsupport/filestuff.h"
 #include "objfiles.h"
 #include "nat/linux-namespaces.h"
+#include "gdbsupport/block-signals.h"
 #include "gdbsupport/fileio.h"
 #include "gdbsupport/scope-exit.h"
 #include "gdbsupport/gdb-sigmask.h"
+#include "gdbsupport/common-debug.h"
+#include <unordered_map>
 
 /* This comment documents high-level logic of this file.
 
@@ -109,11 +112,11 @@ and target events, so neither blocking waitpid nor sigsuspend are
 viable options.  Instead, we should asynchronously notify the GDB main
 event loop whenever there's an unprocessed event from the target.  We
 detect asynchronous target events by handling SIGCHLD signals.  To
-notify the event loop about target events, the self-pipe trick is used
---- a pipe is registered as waitable event source in the event loop,
+notify the event loop about target events, an event pipe is used
+--- the pipe is registered as waitable event source in the event loop,
 the event loop select/poll's on the read end of this pipe (as well on
-other event sources, e.g., stdin), and the SIGCHLD handler writes a
-byte to this pipe.  This is more portable than relying on
+other event sources, e.g., stdin), and the SIGCHLD handler marks the
+event pipe to raise an event.  This is more portable than relying on
 pselect/ppoll, since on kernels that lack those syscalls, libc
 emulates them with select/poll+sigprocmask, and that is racy
 (a.k.a. plain broken).
@@ -189,74 +192,41 @@ struct linux_nat_target *linux_target;
 /* Does the current host support PTRACE_GETREGSET?  */
 enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
 
-static unsigned int debug_linux_nat;
+/* When true, print debug messages relating to the linux native target.  */
+
+static bool debug_linux_nat;
+
+/* Implement 'show debug linux-nat'.  */
+
 static void
 show_debug_linux_nat (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Debugging of GNU/Linux lwp module is %s.\n"),
-                   value);
+  gdb_printf (file, _("Debugging of GNU/Linux native targets is %s.\n"),
+             value);
 }
 
+/* Print a linux-nat debug statement.  */
+
+#define linux_nat_debug_printf(fmt, ...) \
+  debug_prefixed_printf_cond (debug_linux_nat, "linux-nat", fmt, ##__VA_ARGS__)
+
+/* Print "linux-nat" enter/exit debug statements.  */
+
+#define LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT \
+  scoped_debug_enter_exit (debug_linux_nat, "linux-nat")
+
 struct simple_pid_list
 {
   int pid;
   int status;
   struct simple_pid_list *next;
 };
-struct simple_pid_list *stopped_pids;
+static struct simple_pid_list *stopped_pids;
 
 /* Whether target_thread_events is in effect.  */
 static int report_thread_events;
 
-/* Async mode support.  */
-
-/* The read/write ends of the pipe registered as waitable file in the
-   event loop.  */
-static int linux_nat_event_pipe[2] = { -1, -1 };
-
-/* True if we're currently in async mode.  */
-#define linux_is_async_p() (linux_nat_event_pipe[0] != -1)
-
-/* Flush the event pipe.  */
-
-static void
-async_file_flush (void)
-{
-  int ret;
-  char buf;
-
-  do
-    {
-      ret = read (linux_nat_event_pipe[0], &buf, 1);
-    }
-  while (ret >= 0 || (ret == -1 && errno == EINTR));
-}
-
-/* Put something (anything, doesn't matter what, or how much) in event
-   pipe, so that the select/poll in the event-loop realizes we have
-   something to process.  */
-
-static void
-async_file_mark (void)
-{
-  int ret;
-
-  /* It doesn't really matter what the pipe contains, as long we end
-     up with something in it.  Might as well flush the previous
-     left-overs.  */
-  async_file_flush ();
-
-  do
-    {
-      ret = write (linux_nat_event_pipe[1], "+", 1);
-    }
-  while (ret == -1 && errno == EINTR);
-
-  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
-     be awakened anyway.  */
-}
-
 static int kill_lwp (int lwpid, int signo);
 
 static int stop_callback (struct lwp_info *lp);
@@ -274,6 +244,17 @@ static int lwp_status_pending_p (struct lwp_info *lp);
 
 static void save_stop_reason (struct lwp_info *lp);
 
+static void close_proc_mem_file (pid_t pid);
+static void open_proc_mem_file (ptid_t ptid);
+
+/* Return TRUE if LWP is the leader thread of the process.  */
+
+static bool
+is_leader (lwp_info *lp)
+{
+  return lp->ptid.pid () == lp->ptid.lwp ();
+}
+
 \f
 /* LWP accessors.  */
 
@@ -401,6 +382,8 @@ linux_nat_target::post_attach (int pid)
   linux_init_ptrace_procfs (pid, 1);
 }
 
+/* Implement the virtual inf_ptrace_target::post_startup_inferior method.  */
+
 void
 linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
@@ -413,9 +396,8 @@ static int
 num_lwps (int pid)
 {
   int count = 0;
-  struct lwp_info *lp;
 
-  for (lp = lwp_list; lp; lp = lp->next)
+  for (const lwp_info *lp ATTRIBUTE_UNUSED : all_lwps ())
     if (lp->ptid.pid () == pid)
       count++;
 
@@ -436,29 +418,25 @@ struct lwp_deleter
 
 typedef std::unique_ptr<struct lwp_info, lwp_deleter> lwp_info_up;
 
-/* Target hook for follow_fork.  On entry inferior_ptid must be the
-   ptid of the followed inferior.  At return, inferior_ptid will be
-   unchanged.  */
+/* Target hook for follow_fork.  */
 
-bool
-linux_nat_target::follow_fork (bool follow_child, bool detach_fork)
+void
+linux_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
+                              target_waitkind fork_kind, bool follow_child,
+                              bool detach_fork)
 {
+  inf_ptrace_target::follow_fork (child_inf, child_ptid, fork_kind,
+                                 follow_child, detach_fork);
+
   if (!follow_child)
     {
-      struct lwp_info *child_lp = NULL;
-      int has_vforked;
-      ptid_t parent_ptid, child_ptid;
-      int parent_pid, child_pid;
-
-      has_vforked = (inferior_thread ()->pending_follow.kind
-                    == TARGET_WAITKIND_VFORKED);
-      parent_ptid = inferior_ptid;
-      child_ptid = inferior_thread ()->pending_follow.value.related_pid;
-      parent_pid = parent_ptid.lwp ();
-      child_pid = child_ptid.lwp ();
+      bool has_vforked = fork_kind == TARGET_WAITKIND_VFORKED;
+      ptid_t parent_ptid = inferior_ptid;
+      int parent_pid = parent_ptid.lwp ();
+      int child_pid = child_ptid.lwp ();
 
       /* We're already attached to the parent, by default.  */
-      child_lp = add_lwp (child_ptid);
+      lwp_info *child_lp = add_lwp (child_ptid);
       child_lp->stopped = 1;
       child_lp->last_resume_kind = resume_stop;
 
@@ -511,114 +489,36 @@ linux_nat_target::follow_fork (bool follow_child, bool detach_fork)
                  && !signal_pass_state (gdb_signal_from_host (signo)))
                signo = 0;
              ptrace (PTRACE_DETACH, child_pid, 0, signo);
+
+             close_proc_mem_file (child_pid);
            }
        }
-      else
-       {
-         /* Switching inferior_ptid is not enough, because then
-            inferior_thread () would crash by not finding the thread
-            in the current inferior.  */
-         scoped_restore_current_thread restore_current_thread;
-         thread_info *child = find_thread_ptid (this, child_ptid);
-         switch_to_thread (child);
-
-         /* Let the thread_db layer learn about this new process.  */
-         check_for_thread_db ();
-       }
 
       if (has_vforked)
        {
-         struct lwp_info *parent_lp;
+         lwp_info *parent_lp = find_lwp_pid (parent_ptid);
+         linux_nat_debug_printf ("waiting for VFORK_DONE on %d", parent_pid);
+         parent_lp->stopped = 1;
 
-         parent_lp = find_lwp_pid (parent_ptid);
-         gdb_assert (linux_supports_tracefork () >= 0);
-
-         if (linux_supports_tracevforkdone ())
-           {
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "LCFF: waiting for VFORK_DONE on %d\n",
-                                   parent_pid);
-             parent_lp->stopped = 1;
-
-             /* We'll handle the VFORK_DONE event like any other
-                event, in target_wait.  */
-           }
-         else
-           {
-             /* We can't insert breakpoints until the child has
-                finished with the shared memory region.  We need to
-                wait until that happens.  Ideal would be to just
-                call:
-                - ptrace (PTRACE_SYSCALL, parent_pid, 0, 0);
-                - waitpid (parent_pid, &status, __WALL);
-                However, most architectures can't handle a syscall
-                being traced on the way out if it wasn't traced on
-                the way in.
-
-                We might also think to loop, continuing the child
-                until it exits or gets a SIGTRAP.  One problem is
-                that the child might call ptrace with PTRACE_TRACEME.
-
-                There's no simple and reliable way to figure out when
-                the vforked child will be done with its copy of the
-                shared memory.  We could step it out of the syscall,
-                two instructions, let it go, and then single-step the
-                parent once.  When we have hardware single-step, this
-                would work; with software single-step it could still
-                be made to work but we'd have to be able to insert
-                single-step breakpoints in the child, and we'd have
-                to insert -just- the single-step breakpoint in the
-                parent.  Very awkward.
-
-                In the end, the best we can do is to make sure it
-                runs for a little while.  Hopefully it will be out of
-                range of any breakpoints we reinsert.  Usually this
-                is only the single-step breakpoint at vfork's return
-                point.  */
-
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "LCFF: no VFORK_DONE "
-                                   "support, sleeping a bit\n");
-
-             usleep (10000);
-
-             /* Pretend we've seen a PTRACE_EVENT_VFORK_DONE event,
-                and leave it pending.  The next linux_nat_resume call
-                will notice a pending event, and bypasses actually
-                resuming the inferior.  */
-             parent_lp->status = 0;
-             parent_lp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
-             parent_lp->stopped = 1;
-
-             /* If we're in async mode, need to tell the event loop
-                there's something here to process.  */
-             if (target_is_async_p ())
-               async_file_mark ();
-           }
+         /* We'll handle the VFORK_DONE event like any other
+            event, in target_wait.  */
        }
     }
   else
     {
       struct lwp_info *child_lp;
 
-      child_lp = add_lwp (inferior_ptid);
+      child_lp = add_lwp (child_ptid);
       child_lp->stopped = 1;
       child_lp->last_resume_kind = resume_stop;
-
-      /* Let the thread_db layer learn about this new process.  */
-      check_for_thread_db ();
     }
-
-  return false;
 }
 
 \f
 int
 linux_nat_target::insert_fork_catchpoint (int pid)
 {
-  return !linux_supports_tracefork ();
+  return 0;
 }
 
 int
@@ -630,7 +530,7 @@ linux_nat_target::remove_fork_catchpoint (int pid)
 int
 linux_nat_target::insert_vfork_catchpoint (int pid)
 {
-  return !linux_supports_tracefork ();
+  return 0;
 }
 
 int
@@ -642,7 +542,7 @@ linux_nat_target::remove_vfork_catchpoint (int pid)
 int
 linux_nat_target::insert_exec_catchpoint (int pid)
 {
-  return !linux_supports_tracefork ();
+  return 0;
 }
 
 int
@@ -655,9 +555,6 @@ int
 linux_nat_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
                                          gdb::array_view<const int> syscall_counts)
 {
-  if (!linux_supports_tracesysgood ())
-    return 1;
-
   /* On GNU/Linux, we ignore the arguments.  It means that we only
      enable the syscall catchpoints, but do not disable them.
 
@@ -718,17 +615,31 @@ lwp_lwpid_htab_add_lwp (struct lwp_info *lp)
    creation order.  This order is assumed in some cases.  E.g.,
    reaping status after killing alls lwps of a process: the leader LWP
    must be reaped last.  */
-struct lwp_info *lwp_list;
+
+static intrusive_list<lwp_info> lwp_list;
+
+/* See linux-nat.h.  */
+
+lwp_info_range
+all_lwps ()
+{
+  return lwp_info_range (lwp_list.begin ());
+}
+
+/* See linux-nat.h.  */
+
+lwp_info_safe_range
+all_lwps_safe ()
+{
+  return lwp_info_safe_range (lwp_list.begin ());
+}
 
 /* Add LP to sorted-by-reverse-creation-order doubly-linked list.  */
 
 static void
 lwp_list_add (struct lwp_info *lp)
 {
-  lp->next = lwp_list;
-  if (lwp_list != NULL)
-    lwp_list->prev = lp;
-  lwp_list = lp;
+  lwp_list.push_front (*lp);
 }
 
 /* Remove LP from sorted-by-reverse-creation-order doubly-linked
@@ -738,12 +649,7 @@ static void
 lwp_list_remove (struct lwp_info *lp)
 {
   /* Remove from sorted-by-creation-order list.  */
-  if (lp->next != NULL)
-    lp->next->prev = lp->prev;
-  if (lp->prev != NULL)
-    lp->prev->next = lp->next;
-  if (lp == lwp_list)
-    lwp_list = lp->next;
+  lwp_list.erase (lwp_list.iterator_to (*lp));
 }
 
 \f
@@ -756,7 +662,7 @@ static sigset_t suspend_mask;
 static sigset_t blocked_mask;
 
 /* SIGCHLD action.  */
-struct sigaction sigchld_action;
+static struct sigaction sigchld_action;
 
 /* Block child signals (SIGCHLD and linux threads signals), and store
    the previous mask in PREV_MASK.  */
@@ -796,7 +702,7 @@ linux_nat_target::pass_signals
     {
       int target_signo = gdb_signal_from_host (signo);
       if (target_signo < pass_signals.size () && pass_signals[target_signo])
-        sigaddset (&pass_mask, signo);
+       sigaddset (&pass_mask, signo);
     }
 }
 
@@ -811,13 +717,10 @@ static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 
 /* Destroy and free LP.  */
 
-static void
-lwp_free (struct lwp_info *lp)
+lwp_info::~lwp_info ()
 {
   /* Let the arch specific bits release arch_lwp_info.  */
-  linux_target->low_delete_thread (lp->arch_private);
-
-  xfree (lp);
+  linux_target->low_delete_thread (this->arch_private);
 }
 
 /* Traversal function for purge_lwp_list.  */
@@ -832,7 +735,7 @@ lwp_lwpid_htab_remove_pid (void **slot, void *info)
     {
       htab_clear_slot (lwp_lwpid_htab, slot);
       lwp_list_remove (lp);
-      lwp_free (lp);
+      delete lp;
     }
 
   return 1;
@@ -863,19 +766,10 @@ purge_lwp_list (int pid)
 static struct lwp_info *
 add_initial_lwp (ptid_t ptid)
 {
-  struct lwp_info *lp;
-
   gdb_assert (ptid.lwp_p ());
 
-  lp = XNEW (struct lwp_info);
-
-  memset (lp, 0, sizeof (struct lwp_info));
+  lwp_info *lp = new lwp_info (ptid);
 
-  lp->last_resume_kind = resume_continue;
-  lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
-
-  lp->ptid = ptid;
-  lp->core = -1;
 
   /* Add to sorted-by-reverse-creation-order list.  */
   lwp_list_add (lp);
@@ -911,16 +805,13 @@ add_lwp (ptid_t ptid)
 static void
 delete_lwp (ptid_t ptid)
 {
-  struct lwp_info *lp;
-  void **slot;
-  struct lwp_info dummy;
+  lwp_info dummy (ptid);
 
-  dummy.ptid = ptid;
-  slot = htab_find_slot (lwp_lwpid_htab, &dummy, NO_INSERT);
+  void **slot = htab_find_slot (lwp_lwpid_htab, &dummy, NO_INSERT);
   if (slot == NULL)
     return;
 
-  lp = *(struct lwp_info **) slot;
+  lwp_info *lp = *(struct lwp_info **) slot;
   gdb_assert (lp != NULL);
 
   htab_clear_slot (lwp_lwpid_htab, slot);
@@ -929,7 +820,7 @@ delete_lwp (ptid_t ptid)
   lwp_list_remove (lp);
 
   /* Release.  */
-  lwp_free (lp);
+  delete lp;
 }
 
 /* Return a pointer to the structure describing the LWP corresponding
@@ -938,18 +829,15 @@ delete_lwp (ptid_t ptid)
 static struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  struct lwp_info *lp;
   int lwp;
-  struct lwp_info dummy;
 
   if (ptid.lwp_p ())
     lwp = ptid.lwp ();
   else
     lwp = ptid.pid ();
 
-  dummy.ptid = ptid_t (0, lwp, 0);
-  lp = (struct lwp_info *) htab_find (lwp_lwpid_htab, &dummy);
-  return lp;
+  lwp_info dummy (ptid_t (0, lwp));
+  return (struct lwp_info *) htab_find (lwp_lwpid_htab, &dummy);
 }
 
 /* See nat/linux-nat.h.  */
@@ -958,12 +846,8 @@ struct lwp_info *
 iterate_over_lwps (ptid_t filter,
                   gdb::function_view<iterate_over_lwps_ftype> callback)
 {
-  struct lwp_info *lp, *lpnext;
-
-  for (lp = lwp_list; lp; lp = lpnext)
+  for (lwp_info *lp : all_lwps_safe ())
     {
-      lpnext = lp->next;
-
       if (lp->ptid.matches (filter))
        {
          if (callback (lp) != 0)
@@ -1010,8 +894,8 @@ exit_lwp (struct lwp_info *lp)
   if (th)
     {
       if (print_thread_events)
-       printf_unfiltered (_("[%s exited]\n"),
-                          target_pid_to_str (lp->ptid).c_str ());
+       gdb_printf (_("[%s exited]\n"),
+                   target_pid_to_str (lp->ptid).c_str ());
 
       delete_thread (th);
     }
@@ -1030,9 +914,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
 
   if (linux_proc_pid_is_stopped (pid))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LNPAW: Attaching to a stopped process\n");
+      linux_nat_debug_printf ("Attaching to a stopped process");
 
       /* The process is definitely stopped.  It is in a job control
         stop, unless the kernel predates the TASK_STOPPED /
@@ -1040,7 +922,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
         ptrace stop.  Make sure it is in a ptrace stop; from there we
         can kill it, signal it, et cetera.
 
-         First make sure there is a pending SIGSTOP.  Since we are
+        First make sure there is a pending SIGSTOP.  Since we are
         already attached, the process can not transition from stopped
         to running without a PTRACE_CONT; so we know this signal will
         go into the queue.  The SIGSTOP generated by PTRACE_ATTACH is
@@ -1063,19 +945,16 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
   if (!WIFSTOPPED (status))
     {
       /* The pid we tried to attach has apparently just exited.  */
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog, "LNPAW: Failed to stop %d: %s",
-                           pid, status_to_str (status));
+      linux_nat_debug_printf ("Failed to stop %d: %s", pid,
+                             status_to_str (status).c_str ());
       return status;
     }
 
   if (WSTOPSIG (status) != SIGSTOP)
     {
       *signalled = 1;
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LNPAW: Received %s after attaching\n",
-                           status_to_str (status));
+      linux_nat_debug_printf ("Received %s after attaching",
+                             status_to_str (status).c_str ());
     }
 
   return status;
@@ -1096,6 +975,8 @@ linux_nat_target::create_inferior (const char *exec_file,
   pass_signals ({});
 
   inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
+
+  open_proc_mem_file (inferior_ptid);
 }
 
 /* Callback for linux_proc_attach_tgid_threads.  Attach to PTID if not
@@ -1125,13 +1006,10 @@ attach_proc_task_lwp_callback (ptid_t ptid)
          if (err == ESRCH
              || (err == EPERM && linux_proc_pid_is_gone (lwpid)))
            {
-             if (debug_linux_nat)
-               {
-                 fprintf_unfiltered (gdb_stdlog,
-                                     "Cannot attach to lwp %d: "
-                                     "thread is gone (%d: %s)\n",
-                                     lwpid, err, safe_strerror (err));
-               }
+             linux_nat_debug_printf
+               ("Cannot attach to lwp %d: thread is gone (%d: %s)",
+                lwpid, err, safe_strerror (err));
+
            }
          else
            {
@@ -1144,10 +1022,8 @@ attach_proc_task_lwp_callback (ptid_t ptid)
        }
       else
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "PTRACE_ATTACH %s, 0, 0 (OK)\n",
-                               target_pid_to_str (ptid).c_str ());
+         linux_nat_debug_printf ("PTRACE_ATTACH %s, 0, 0 (OK)",
+                                 ptid.to_string ().c_str ());
 
          lp = add_lwp (ptid);
 
@@ -1204,8 +1080,7 @@ linux_nat_target::attach (const char *args, int from_tty)
   /* The ptrace base target adds the main thread with (pid,0,0)
      format.  Decorate it with lwp info.  */
   ptid = ptid_t (inferior_ptid.pid (),
-                inferior_ptid.pid (),
-                0);
+                inferior_ptid.pid ());
   thread_change_ptid (linux_target, inferior_ptid, ptid);
 
   /* Add the initial process as the first LWP to the list.  */
@@ -1247,12 +1122,13 @@ linux_nat_target::attach (const char *args, int from_tty)
 
   lp->stopped = 1;
 
+  open_proc_mem_file (lp->ptid);
+
   /* Save the wait status to report later.  */
   lp->resumed = 1;
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog,
-                       "LNA: waitpid %ld, saving status %s\n",
-                       (long) lp->ptid.pid (), status_to_str (status));
+  linux_nat_debug_printf ("waitpid %ld, saving status %s",
+                         (long) lp->ptid.pid (),
+                         status_to_str (status).c_str ());
 
   lp->status = status;
 
@@ -1265,9 +1141,45 @@ linux_nat_target::attach (const char *args, int from_tty)
      threads and associate pthread info with each LWP.  */
   linux_proc_attach_tgid_threads (lp->ptid.pid (),
                                  attach_proc_task_lwp_callback);
+}
+
+/* Ptrace-detach the thread with pid PID.  */
 
-  if (target_can_async_p ())
-    target_async (1);
+static void
+detach_one_pid (int pid, int signo)
+{
+  if (ptrace (PTRACE_DETACH, pid, 0, signo) < 0)
+    {
+      int save_errno = errno;
+
+      /* We know the thread exists, so ESRCH must mean the lwp is
+        zombie.  This can happen if one of the already-detached
+        threads exits the whole thread group.  In that case we're
+        still attached, and must reap the lwp.  */
+      if (save_errno == ESRCH)
+       {
+         int ret, status;
+
+         ret = my_waitpid (pid, &status, __WALL);
+         if (ret == -1)
+           {
+             warning (_("Couldn't reap LWP %d while detaching: %s"),
+                      pid, safe_strerror (errno));
+           }
+         else if (!WIFEXITED (status) && !WIFSIGNALED (status))
+           {
+             warning (_("Reaping LWP %d while detaching "
+                        "returned unexpected status 0x%x"),
+                      pid, status);
+           }
+       }
+      else
+       error (_("Can't detach %d: %s"),
+              pid, safe_strerror (save_errno));
+    }
+  else
+    linux_nat_debug_printf ("PTRACE_DETACH (%d, %s, 0) (OK)",
+                           pid, strsignal (signo));
 }
 
 /* Get pending signal of THREAD as a host signal number, for detaching
@@ -1301,7 +1213,7 @@ get_detach_signal (struct lwp_info *lp)
      signal pass state).  Normally SIGTRAP isn't set to pass state, so
      this is really a corner case.  */
 
-  if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  if (lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     signo = GDB_SIGNAL_0; /* a pending ptrace event, not a real signal.  */
   else if (lp->status)
     signo = gdb_signal_from_host (WSTOPSIG (lp->status));
@@ -1309,12 +1221,21 @@ get_detach_signal (struct lwp_info *lp)
     {
       struct thread_info *tp = find_thread_ptid (linux_target, lp->ptid);
 
-      if (target_is_non_stop_p () && !tp->executing)
+      if (target_is_non_stop_p () && !tp->executing ())
        {
-         if (tp->suspend.waitstatus_pending_p)
-           signo = tp->suspend.waitstatus.value.sig;
+         if (tp->has_pending_waitstatus ())
+           {
+             /* If the thread has a pending event, and it was stopped with a
+                signal, use that signal to resume it.  If it has a pending
+                event of another kind, it was not stopped with a signal, so
+                resume it without a signal.  */
+             if (tp->pending_waitstatus ().kind () == TARGET_WAITKIND_STOPPED)
+               signo = tp->pending_waitstatus ().sig ();
+             else
+               signo = GDB_SIGNAL_0;
+           }
          else
-           signo = tp->suspend.stop_signal;
+           signo = tp->stop_signal ();
        }
       else if (!target_is_non_stop_p ())
        {
@@ -1325,33 +1246,26 @@ get_detach_signal (struct lwp_info *lp)
 
          if (last_target == linux_target
              && lp->ptid.lwp () == last_ptid.lwp ())
-           signo = tp->suspend.stop_signal;
+           signo = tp->stop_signal ();
        }
     }
 
   if (signo == GDB_SIGNAL_0)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "GPT: lwp %s has no pending signal\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("lwp %s has no pending signal",
+                             lp->ptid.to_string ().c_str ());
     }
   else if (!signal_pass_state (signo))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "GPT: lwp %s had signal %s, "
-                           "but it is in no pass state\n",
-                           target_pid_to_str (lp->ptid).c_str (),
-                           gdb_signal_to_string (signo));
+      linux_nat_debug_printf
+       ("lwp %s had signal %s but it is in no pass state",
+        lp->ptid.to_string ().c_str (), gdb_signal_to_string (signo));
     }
   else
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "GPT: lwp %s has pending signal %s\n",
-                           target_pid_to_str (lp->ptid).c_str (),
-                           gdb_signal_to_string (signo));
+      linux_nat_debug_printf ("lwp %s has pending signal %s",
+                             lp->ptid.to_string ().c_str (),
+                             gdb_signal_to_string (signo));
 
       return gdb_signal_to_host (signo);
     }
@@ -1371,18 +1285,58 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
 
   gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
 
-  if (debug_linux_nat && lp->status)
-    fprintf_unfiltered (gdb_stdlog, "DC:  Pending %s for %s on detach.\n",
-                       strsignal (WSTOPSIG (lp->status)),
-                       target_pid_to_str (lp->ptid).c_str ());
+  /* If the lwp/thread we are about to detach has a pending fork event,
+     there is a process GDB is attached to that the core of GDB doesn't know
+     about.  Detach from it.  */
+
+  /* Check in lwp_info::status.  */
+  if (WIFSTOPPED (lp->status) && linux_is_extended_waitstatus (lp->status))
+    {
+      int event = linux_ptrace_get_extended_event (lp->status);
+
+      if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK)
+       {
+         unsigned long child_pid;
+         int ret = ptrace (PTRACE_GETEVENTMSG, lp->ptid.lwp (), 0, &child_pid);
+         if (ret == 0)
+           detach_one_pid (child_pid, 0);
+         else
+           perror_warning_with_name (_("Failed to detach fork child"));
+       }
+    }
+
+  /* Check in lwp_info::waitstatus.  */
+  if (lp->waitstatus.kind () == TARGET_WAITKIND_VFORKED
+      || lp->waitstatus.kind () == TARGET_WAITKIND_FORKED)
+    detach_one_pid (lp->waitstatus.child_ptid ().pid (), 0);
+
+
+  /* Check in thread_info::pending_waitstatus.  */
+  thread_info *tp = find_thread_ptid (linux_target, lp->ptid);
+  if (tp->has_pending_waitstatus ())
+    {
+      const target_waitstatus &ws = tp->pending_waitstatus ();
+
+      if (ws.kind () == TARGET_WAITKIND_VFORKED
+         || ws.kind () == TARGET_WAITKIND_FORKED)
+       detach_one_pid (ws.child_ptid ().pid (), 0);
+    }
+
+  /* Check in thread_info::pending_follow.  */
+  if (tp->pending_follow.kind () == TARGET_WAITKIND_VFORKED
+      || tp->pending_follow.kind () == TARGET_WAITKIND_FORKED)
+    detach_one_pid (tp->pending_follow.child_ptid ().pid (), 0);
+
+  if (lp->status != 0)
+    linux_nat_debug_printf ("Pending %s for %s on detach.",
+                           strsignal (WSTOPSIG (lp->status)),
+                           lp->ptid.to_string ().c_str ());
 
   /* If there is a pending SIGSTOP, get rid of it.  */
   if (lp->signalled)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "DC: Sending SIGCONT to %s\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("Sending SIGCONT to %s",
+                             lp->ptid.to_string ().c_str ());
 
       kill_lwp (lwpid, SIGCONT);
       lp->signalled = 0;
@@ -1409,45 +1363,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
        throw;
     }
 
-  if (ptrace (PTRACE_DETACH, lwpid, 0, signo) < 0)
-    {
-      int save_errno = errno;
-
-      /* We know the thread exists, so ESRCH must mean the lwp is
-        zombie.  This can happen if one of the already-detached
-        threads exits the whole thread group.  In that case we're
-        still attached, and must reap the lwp.  */
-      if (save_errno == ESRCH)
-       {
-         int ret, status;
-
-         ret = my_waitpid (lwpid, &status, __WALL);
-         if (ret == -1)
-           {
-             warning (_("Couldn't reap LWP %d while detaching: %s"),
-                      lwpid, safe_strerror (errno));
-           }
-         else if (!WIFEXITED (status) && !WIFSIGNALED (status))
-           {
-             warning (_("Reaping LWP %d while detaching "
-                        "returned unexpected status 0x%x"),
-                      lwpid, status);
-           }
-       }
-      else
-       {
-         error (_("Can't detach %s: %s"),
-                target_pid_to_str (lp->ptid).c_str (),
-                safe_strerror (save_errno));
-       }
-    }
-  else if (debug_linux_nat)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-                         "PTRACE_DETACH (%s, %s, 0) (OK)\n",
-                         target_pid_to_str (lp->ptid).c_str (),
-                         strsignal (signo));
-    }
+  detach_one_pid (lwpid, signo);
 
   delete_lwp (lp->ptid);
 }
@@ -1479,6 +1395,11 @@ linux_nat_target::detach (inferior *inf, int from_tty)
      they're no longer running.  */
   iterate_over_lwps (ptid_t (pid), stop_wait_callback);
 
+  /* We can now safely remove breakpoints.  We don't this in earlier
+     in common code because this target doesn't currently support
+     writing memory while the inferior is running.  */
+  remove_breakpoints_inf (current_inferior ());
+
   iterate_over_lwps (ptid_t (pid), detach_callback);
 
   /* Only the initial process should be left right now.  */
@@ -1505,6 +1426,8 @@ linux_nat_target::detach (inferior *inf, int from_tty)
 
       detach_success (inf);
     }
+
+  close_proc_mem_file (pid);
 }
 
 /* Resume execution of the inferior process.  If STEP is nonzero,
@@ -1569,7 +1492,7 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp)
     {
       lp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
       lp->status = 0;
-      lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      lp->waitstatus.set_ignore ();
       return 1;
     }
   return 0;
@@ -1603,39 +1526,29 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
 
       if (inf->vfork_child != NULL)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "RC: Not resuming %s (vfork parent)\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("Not resuming %s (vfork parent)",
+                                 lp->ptid.to_string ().c_str ());
        }
       else if (!lwp_status_pending_p (lp))
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "RC: Resuming sibling %s, %s, %s\n",
-                               target_pid_to_str (lp->ptid).c_str (),
-                               (signo != GDB_SIGNAL_0
-                                ? strsignal (gdb_signal_to_host (signo))
-                                : "0"),
-                               step ? "step" : "resume");
+         linux_nat_debug_printf ("Resuming sibling %s, %s, %s",
+                                 lp->ptid.to_string ().c_str (),
+                                 (signo != GDB_SIGNAL_0
+                                  ? strsignal (gdb_signal_to_host (signo))
+                                  : "0"),
+                                 step ? "step" : "resume");
 
          linux_resume_one_lwp (lp, step, signo);
        }
       else
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "RC: Not resuming sibling %s (has pending)\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("Not resuming sibling %s (has pending)",
+                                 lp->ptid.to_string ().c_str ());
        }
     }
   else
-    {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "RC: Not resuming sibling %s (not stopped)\n",
-                           target_pid_to_str (lp->ptid).c_str ());
-    }
+    linux_nat_debug_printf ("Not resuming sibling %s (not stopped)",
+                           lp->ptid.to_string ().c_str ());
 }
 
 /* Callback for iterate_over_lwps.  If LWP is EXCEPT, do nothing.
@@ -1656,8 +1569,8 @@ linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
       thread = find_thread_ptid (linux_target, lp->ptid);
       if (thread != NULL)
        {
-         signo = thread->suspend.stop_signal;
-         thread->suspend.stop_signal = GDB_SIGNAL_0;
+         signo = thread->stop_signal ();
+         thread->set_stop_signal (GDB_SIGNAL_0);
        }
     }
 
@@ -1682,34 +1595,22 @@ resume_set_callback (struct lwp_info *lp)
 }
 
 void
-linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
+linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
 {
   struct lwp_info *lp;
-  int resume_many;
 
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog,
-                       "LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
-                       step ? "step" : "resume",
-                       target_pid_to_str (ptid).c_str (),
-                       (signo != GDB_SIGNAL_0
-                        ? strsignal (gdb_signal_to_host (signo)) : "0"),
-                       target_pid_to_str (inferior_ptid).c_str ());
-
-  /* A specific PTID means `step only this process id'.  */
-  resume_many = (minus_one_ptid == ptid
-                || ptid.is_pid ());
+  linux_nat_debug_printf ("Preparing to %s %s, %s, inferior_ptid %s",
+                         step ? "step" : "resume",
+                         scope_ptid.to_string ().c_str (),
+                         (signo != GDB_SIGNAL_0
+                          ? strsignal (gdb_signal_to_host (signo)) : "0"),
+                         inferior_ptid.to_string ().c_str ());
 
   /* Mark the lwps we're resuming as resumed and update their
      last_resume_kind to resume_continue.  */
-  iterate_over_lwps (ptid, resume_set_callback);
+  iterate_over_lwps (scope_ptid, resume_set_callback);
 
-  /* See if it's the current inferior that should be handled
-     specially.  */
-  if (resume_many)
-    lp = find_lwp_pid (inferior_ptid);
-  else
-    lp = find_lwp_pid (ptid);
+  lp = find_lwp_pid (inferior_ptid);
   gdb_assert (lp != NULL);
 
   /* Remember if we're stepping.  */
@@ -1729,10 +1630,8 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
          && WSTOPSIG (lp->status)
          && sigismember (&pass_mask, WSTOPSIG (lp->status)))
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LLR: Not short circuiting for ignored "
-                               "status 0x%x\n", lp->status);
+         linux_nat_debug_printf
+           ("Not short circuiting for ignored status 0x%x", lp->status);
 
          /* FIXME: What should we do if we are supposed to continue
             this thread with a signal?  */
@@ -1748,10 +1647,8 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
         this thread with a signal?  */
       gdb_assert (signo == GDB_SIGNAL_0);
 
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLR: Short circuiting for status 0x%x\n",
-                           lp->status);
+      linux_nat_debug_printf ("Short circuiting for status 0x%x",
+                             lp->status);
 
       if (target_can_async_p ())
        {
@@ -1762,24 +1659,20 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
       return;
     }
 
-  if (resume_many)
-    iterate_over_lwps (ptid, [=] (struct lwp_info *info)
-                            {
-                              return linux_nat_resume_callback (info, lp);
-                            });
+  /* No use iterating unless we're resuming other threads.  */
+  if (scope_ptid != lp->ptid)
+    iterate_over_lwps (scope_ptid, [=] (struct lwp_info *info)
+      {
+       return linux_nat_resume_callback (info, lp);
+      });
 
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog,
-                       "LLR: %s %s, %s (resume event thread)\n",
-                       step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
-                       target_pid_to_str (lp->ptid).c_str (),
-                       (signo != GDB_SIGNAL_0
-                        ? strsignal (gdb_signal_to_host (signo)) : "0"));
+  linux_nat_debug_printf ("%s %s, %s (resume event thread)",
+                         step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+                         lp->ptid.to_string ().c_str (),
+                         (signo != GDB_SIGNAL_0
+                          ? strsignal (gdb_signal_to_host (signo)) : "0"));
 
   linux_resume_one_lwp (lp, step, signo);
-
-  if (target_can_async_p ())
-    target_async (1);
 }
 
 /* Send a signal to an LWP.  */
@@ -1836,13 +1729,9 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
         actually get to execute.  It seems it would be even more
         confusing to the user.  */
 
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHST: ignoring syscall %d "
-                           "for LWP %ld (stopping threads), "
-                           "resuming with PTRACE_CONT for SIGSTOP\n",
-                           syscall_number,
-                           lp->ptid.lwp ());
+      linux_nat_debug_printf
+       ("ignoring syscall %d for LWP %ld (stopping threads), resuming with "
+        "PTRACE_CONT for SIGSTOP", syscall_number, lp->ptid.lwp ());
 
       lp->syscall_state = TARGET_WAITKIND_IGNORE;
       ptrace (PTRACE_CONT, lp->ptid.lwp (), 0, 0);
@@ -1864,29 +1753,25 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
       if (catching_syscall_number (syscall_number))
        {
          /* Alright, an event to report.  */
-         ourstatus->kind = lp->syscall_state;
-         ourstatus->value.syscall_number = syscall_number;
-
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LHST: stopping for %s of syscall %d"
-                               " for LWP %ld\n",
-                               lp->syscall_state
-                               == TARGET_WAITKIND_SYSCALL_ENTRY
-                               ? "entry" : "return",
-                               syscall_number,
-                               lp->ptid.lwp ());
+         if (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+           ourstatus->set_syscall_entry (syscall_number);
+         else if (lp->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN)
+           ourstatus->set_syscall_return (syscall_number);
+         else
+           gdb_assert_not_reached ("unexpected syscall state");
+
+         linux_nat_debug_printf
+           ("stopping for %s of syscall %d for LWP %ld",
+            (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
+             ? "entry" : "return"), syscall_number, lp->ptid.lwp ());
+
          return 0;
        }
 
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHST: ignoring %s of syscall %d "
-                           "for LWP %ld\n",
-                           lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
-                           ? "entry" : "return",
-                           syscall_number,
-                           lp->ptid.lwp ());
+      linux_nat_debug_printf
+       ("ignoring %s of syscall %d for LWP %ld",
+        (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
+         ? "entry" : "return"), syscall_number, lp->ptid.lwp ());
     }
   else
     {
@@ -1906,13 +1791,9 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
 
         The points above mean that the next resume, be it PT_STEP or
         PT_CONTINUE, can not trigger a syscall trace event.  */
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHST: caught syscall event "
-                           "with no syscall catchpoints."
-                           " %d for LWP %ld, ignoring\n",
-                           syscall_number,
-                           lp->ptid.lwp ());
+      linux_nat_debug_printf
+       ("caught syscall event with no syscall catchpoints. %d for LWP %ld, "
+        "ignoring", syscall_number, lp->ptid.lwp ());
       lp->syscall_state = TARGET_WAITKIND_IGNORE;
     }
 
@@ -1969,15 +1850,21 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
                            _("wait returned unexpected status 0x%x"), status);
        }
 
-      ourstatus->value.related_pid = ptid_t (new_pid, new_pid, 0);
+      ptid_t child_ptid (new_pid, new_pid);
 
       if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK)
        {
+         open_proc_mem_file (child_ptid);
+
          /* The arch-specific native code may need to know about new
             forks even if those end up never mapped to an
             inferior.  */
          linux_target->low_new_fork (lp, new_pid);
        }
+      else if (event == PTRACE_EVENT_CLONE)
+       {
+         linux_target->low_new_clone (lp, new_pid);
+       }
 
       if (event == PTRACE_EVENT_FORK
          && linux_fork_checkpointing_p (lp->ptid.pid ()))
@@ -1988,7 +1875,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (ptid_t (new_pid, new_pid, 0));
+         detach_breakpoints (ptid_t (new_pid, new_pid));
 
          /* Retain child fork in ptrace (stopped) state.  */
          if (!find_fork_pid (new_pid))
@@ -1997,29 +1884,26 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
          /* Report as spurious, so that infrun doesn't want to follow
             this fork.  We're actually doing an infcall in
             linux-fork.c.  */
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         ourstatus->set_spurious ();
 
          /* Report the stop to the core.  */
          return 0;
        }
 
       if (event == PTRACE_EVENT_FORK)
-       ourstatus->kind = TARGET_WAITKIND_FORKED;
+       ourstatus->set_forked (child_ptid);
       else if (event == PTRACE_EVENT_VFORK)
-       ourstatus->kind = TARGET_WAITKIND_VFORKED;
+       ourstatus->set_vforked (child_ptid);
       else if (event == PTRACE_EVENT_CLONE)
        {
          struct lwp_info *new_lp;
 
-         ourstatus->kind = TARGET_WAITKIND_IGNORE;
+         ourstatus->set_ignore ();
 
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LHEW: Got clone event "
-                               "from LWP %d, new child is LWP %ld\n",
-                               pid, new_pid);
+         linux_nat_debug_printf
+           ("Got clone event from LWP %d, new child is LWP %ld", pid, new_pid);
 
-         new_lp = add_lwp (ptid_t (lp->ptid.pid (), new_pid, 0));
+         new_lp = add_lwp (ptid_t (lp->ptid.pid (), new_pid));
          new_lp->stopped = 1;
          new_lp->resumed = 1;
 
@@ -2056,17 +1940,14 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
              gdb_assert (new_lp->status == 0);
 
              /* Save the wait status to report later.  */
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "LHEW: waitpid of new LWP %ld, "
-                                   "saving status %s\n",
-                                   (long) new_lp->ptid.lwp (),
-                                   status_to_str (status));
+             linux_nat_debug_printf
+               ("waitpid of new LWP %ld, saving status %s",
+                (long) new_lp->ptid.lwp (), status_to_str (status).c_str ());
              new_lp->status = status;
            }
          else if (report_thread_events)
            {
-             new_lp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+             new_lp->waitstatus.set_thread_created ();
              new_lp->status = status;
            }
 
@@ -2078,14 +1959,18 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 
   if (event == PTRACE_EVENT_EXEC)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHEW: Got exec event from LWP %ld\n",
-                           lp->ptid.lwp ());
+      linux_nat_debug_printf ("Got exec event from LWP %ld", lp->ptid.lwp ());
+
+      /* Close the previous /proc/PID/mem file for this inferior,
+        which was using the address space which is now gone.
+        Reading/writing from this file would return 0/EOF.  */
+      close_proc_mem_file (lp->ptid.pid ());
 
-      ourstatus->kind = TARGET_WAITKIND_EXECD;
-      ourstatus->value.execd_pathname
-       = xstrdup (linux_proc_pid_to_exec_file (pid));
+      /* Open a new file for the new address space.  */
+      open_proc_mem_file (lp->ptid);
+
+      ourstatus->set_execd
+       (make_unique_xstrdup (linux_proc_pid_to_exec_file (pid)));
 
       /* The thread that execed must have been resumed, but, when a
         thread execs, it changes its tid to the tgid, and the old
@@ -2096,24 +1981,11 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 
   if (event == PTRACE_EVENT_VFORK_DONE)
     {
-      if (current_inferior ()->waiting_for_vfork_done)
-       {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LHEW: Got expected PTRACE_EVENT_"
-                               "VFORK_DONE from LWP %ld: stopping\n",
-                               lp->ptid.lwp ());
-
-         ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
-         return 0;
-       }
-
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHEW: Got PTRACE_EVENT_VFORK_DONE "
-                           "from LWP %ld: ignoring\n",
-                           lp->ptid.lwp ());
-      return 1;
+      linux_nat_debug_printf
+       ("Got PTRACE_EVENT_VFORK_DONE from LWP %ld",
+        lp->ptid.lwp ());
+       ourstatus->set_vfork_done ();
+       return 0;
     }
 
   internal_error (__FILE__, __LINE__,
@@ -2126,8 +1998,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 static void
 wait_for_signal ()
 {
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "linux-nat: about to sigsuspend\n");
+  linux_nat_debug_printf ("about to sigsuspend");
   sigsuspend (&suspend_mask);
 
   /* If the quit flag is set, it means that the user pressed Ctrl-C
@@ -2171,9 +2042,8 @@ wait_lwp (struct lwp_info *lp)
             won't get an exit event.  See comments on exec events at
             the top of the file.  */
          thread_dead = 1;
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog, "WL: %s vanished.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("%s vanished.",
+                                 lp->ptid.to_string ().c_str ());
        }
       if (pid != 0)
        break;
@@ -2196,10 +2066,8 @@ wait_lwp (struct lwp_info *lp)
          && linux_proc_pid_is_zombie (lp->ptid.lwp ()))
        {
          thread_dead = 1;
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "WL: Thread group leader %s vanished.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("Thread group leader %s vanished.",
+                                 lp->ptid.to_string ().c_str ());
          break;
        }
 
@@ -2218,13 +2086,9 @@ wait_lwp (struct lwp_info *lp)
     {
       gdb_assert (pid == lp->ptid.lwp ());
 
-      if (debug_linux_nat)
-       {
-         fprintf_unfiltered (gdb_stdlog,
-                             "WL: waitpid %s received %s\n",
-                             target_pid_to_str (lp->ptid).c_str (),
-                             status_to_str (status));
-       }
+      linux_nat_debug_printf ("waitpid %s received %s",
+                             lp->ptid.to_string ().c_str (),
+                             status_to_str (status).c_str ());
 
       /* Check if the thread has exited.  */
       if (WIFEXITED (status) || WIFSIGNALED (status))
@@ -2232,22 +2096,19 @@ wait_lwp (struct lwp_info *lp)
          if (report_thread_events
              || lp->ptid.pid () == lp->ptid.lwp ())
            {
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog, "WL: LWP %d exited.\n",
-                                   lp->ptid.pid ());
+             linux_nat_debug_printf ("LWP %d exited.", lp->ptid.pid ());
 
              /* If this is the leader exiting, it means the whole
                 process is gone.  Store the status to report to the
                 core.  Store it in lp->waitstatus, because lp->status
                 would be ambiguous (W_EXITCODE(0,0) == 0).  */
-             store_waitstatus (&lp->waitstatus, status);
+             lp->waitstatus = host_status_to_waitstatus (status);
              return 0;
            }
 
          thread_dead = 1;
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog, "WL: %s exited.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("%s exited.",
+                                 lp->ptid.to_string ().c_str ());
        }
     }
 
@@ -2291,10 +2152,7 @@ wait_lwp (struct lwp_info *lp)
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP
       && linux_is_extended_waitstatus (status))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "WL: Handling extended status 0x%06x\n",
-                           status);
+      linux_nat_debug_printf ("Handling extended status 0x%06x", status);
       linux_handle_extended_wait (lp, status);
       return 0;
     }
@@ -2311,21 +2169,13 @@ stop_callback (struct lwp_info *lp)
     {
       int ret;
 
-      if (debug_linux_nat)
-       {
-         fprintf_unfiltered (gdb_stdlog,
-                             "SC:  kill %s **<SIGSTOP>**\n",
-                             target_pid_to_str (lp->ptid).c_str ());
-       }
+      linux_nat_debug_printf ("kill %s **<SIGSTOP>**",
+                             lp->ptid.to_string ().c_str ());
+
       errno = 0;
       ret = kill_lwp (lp->ptid.lwp (), SIGSTOP);
-      if (debug_linux_nat)
-       {
-         fprintf_unfiltered (gdb_stdlog,
-                             "SC:  lwp kill %d %s\n",
-                             ret,
+      linux_nat_debug_printf ("lwp kill %d %s", ret,
                              errno ? safe_strerror (errno) : "ERRNO-OK");
-       }
 
       lp->signalled = 1;
       gdb_assert (lp->status == 0);
@@ -2413,10 +2263,8 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
 
   if (!linux_nat_has_pending_sigint (lp->ptid.lwp ()))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "MCIS: Clearing bogus flag for %s\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("Clearing bogus flag for %s",
+                             lp->ptid.to_string ().c_str ());
       lp->ignore_sigint = 0;
     }
 }
@@ -2512,12 +2360,10 @@ stop_wait_callback (struct lwp_info *lp)
          errno = 0;
          ptrace (PTRACE_CONT, lp->ptid.lwp (), 0, 0);
          lp->stopped = 0;
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "PTRACE_CONT %s, 0, 0 (%s) "
-                               "(discarding SIGINT)\n",
-                               target_pid_to_str (lp->ptid).c_str (),
-                               errno ? safe_strerror (errno) : "OK");
+         linux_nat_debug_printf
+           ("PTRACE_CONT %s, 0, 0 (%s) (discarding SIGINT)",
+            lp->ptid.to_string ().c_str (),
+            errno ? safe_strerror (errno) : "OK");
 
          return stop_wait_callback (lp);
        }
@@ -2528,11 +2374,9 @@ stop_wait_callback (struct lwp_info *lp)
        {
          /* The thread was stopped with a signal other than SIGSTOP.  */
 
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SWC: Pending event %s in %s\n",
-                               status_to_str ((int) status),
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("Pending event %s in %s",
+                                 status_to_str ((int) status).c_str (),
+                                 lp->ptid.to_string ().c_str ());
 
          /* Save the sigtrap event.  */
          lp->status = status;
@@ -2543,10 +2387,8 @@ stop_wait_callback (struct lwp_info *lp)
        {
          /* We caught the SIGSTOP that we intended to catch.  */
 
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SWC: Expected SIGSTOP caught for %s.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("Expected SIGSTOP caught for %s.",
+                                 lp->ptid.to_string ().c_str ());
 
          lp->signalled = 0;
 
@@ -2590,23 +2432,19 @@ status_callback (struct lwp_info *lp)
 
       if (pc != lp->stop_pc)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SC: PC of %s changed.  was=%s, now=%s\n",
-                               target_pid_to_str (lp->ptid).c_str (),
-                               paddress (target_gdbarch (), lp->stop_pc),
-                               paddress (target_gdbarch (), pc));
+         linux_nat_debug_printf ("PC of %s changed.  was=%s, now=%s",
+                                 lp->ptid.to_string ().c_str (),
+                                 paddress (target_gdbarch (), lp->stop_pc),
+                                 paddress (target_gdbarch (), pc));
          discard = 1;
        }
 
 #if !USE_SIGTRAP_SIGINFO
       else if (!breakpoint_inserted_here_p (regcache->aspace (), pc))
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SC: previous breakpoint of %s, at %s gone\n",
-                               target_pid_to_str (lp->ptid).c_str (),
-                               paddress (target_gdbarch (), lp->stop_pc));
+         linux_nat_debug_printf ("previous breakpoint of %s, at %s gone",
+                                 lp->ptid.to_string ().c_str (),
+                                 paddress (target_gdbarch (), lp->stop_pc));
 
          discard = 1;
        }
@@ -2614,10 +2452,8 @@ status_callback (struct lwp_info *lp)
 
       if (discard)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SC: pending event of %s cancelled.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("pending event of %s cancelled.",
+                                 lp->ptid.to_string ().c_str ());
 
          lp->status = 0;
          linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
@@ -2662,7 +2498,7 @@ lwp_status_pending_p (struct lwp_info *lp)
   /* We check for lp->waitstatus in addition to lp->status, because we
      can have pending process exits recorded in lp->status and
      W_EXITCODE(0,0) happens to be 0.  */
-  return lp->status != 0 || lp->waitstatus.kind != TARGET_WAITKIND_IGNORE;
+  return lp->status != 0 || lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE;
 }
 
 /* Select the Nth LWP that has had an event.  */
@@ -2703,6 +2539,10 @@ save_stop_reason (struct lwp_info *lp)
   if (!linux_target->low_status_is_event (lp->status))
     return;
 
+  inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
+  if (inf->starting_up)
+    return;
+
   regcache = get_thread_regcache (linux_target, lp->ptid);
   gdbarch = regcache->arch ();
 
@@ -2740,10 +2580,8 @@ save_stop_reason (struct lwp_info *lp)
            }
          else if (siginfo.si_code == TRAP_TRACE)
            {
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "CSBB: %s stopped by trace\n",
-                                   target_pid_to_str (lp->ptid).c_str ());
+             linux_nat_debug_printf ("%s stopped by trace",
+                                     lp->ptid.to_string ().c_str ());
 
              /* We may have single stepped an instruction that
                 triggered a watchpoint.  In that case, on some
@@ -2773,10 +2611,8 @@ save_stop_reason (struct lwp_info *lp)
 
   if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "CSBB: %s stopped by software breakpoint\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("%s stopped by software breakpoint",
+                             lp->ptid.to_string ().c_str ());
 
       /* Back up the PC if necessary.  */
       if (pc != sw_bp_pc)
@@ -2787,17 +2623,13 @@ save_stop_reason (struct lwp_info *lp)
     }
   else if (lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "CSBB: %s stopped by hardware breakpoint\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("%s stopped by hardware breakpoint",
+                             lp->ptid.to_string ().c_str ());
     }
   else if (lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "CSBB: %s stopped by hardware watchpoint\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("%s stopped by hardware watchpoint",
+                             lp->ptid.to_string ().c_str ());
     }
 
   lp->stop_pc = pc;
@@ -2871,10 +2703,8 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
       event_lp = iterate_over_lwps (filter, select_singlestep_lwp_callback);
       if (event_lp != NULL)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "SEL: Select single-step %s\n",
-                               target_pid_to_str (event_lp->ptid).c_str ());
+         linux_nat_debug_printf ("Select single-step %s",
+                                 event_lp->ptid.to_string ().c_str ());
        }
     }
 
@@ -2895,10 +2725,9 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
       random_selector = (int)
        ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
-      if (debug_linux_nat && num_events > 1)
-       fprintf_unfiltered (gdb_stdlog,
-                           "SEL: Found %d events, selecting #%d\n",
-                           num_events, random_selector);
+      if (num_events > 1)
+       linux_nat_debug_printf ("Found %d events, selecting #%d",
+                               num_events, random_selector);
 
       event_lp
        = (iterate_over_lwps
@@ -2930,9 +2759,10 @@ resumed_callback (struct lwp_info *lp)
 }
 
 /* Check if we should go on and pass this event to common code.
-   Return the affected lwp if we should, or NULL otherwise.  */
 
-static struct lwp_info *
+   If so, save the status to the lwp_info structure associated to LWPID.  */
+
+static void
 linux_nat_filter_event (int lwpid, int status)
 {
   struct lwp_info *lp;
@@ -2940,51 +2770,67 @@ linux_nat_filter_event (int lwpid, int status)
 
   lp = 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.  The non-leader
-     thread changes its tid to the tgid.  */
-
-  if (WIFSTOPPED (status) && lp == NULL
-      && (WSTOPSIG (status) == SIGTRAP && event == PTRACE_EVENT_EXEC))
+  /* Check for events reported by anything not in our LWP list.  */
+  if (lp == nullptr)
     {
-      /* A multi-thread exec after we had seen the leader exiting.  */
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: Re-adding thread group leader LWP %d.\n",
-                           lwpid);
+      if (WIFSTOPPED (status))
+       {
+         if (WSTOPSIG (status) == SIGTRAP && event == 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.  */
+             linux_nat_debug_printf
+               ("Re-adding thread group leader LWP %d after exec.",
+                lwpid);
+
+             lp = add_lwp (ptid_t (lwpid, lwpid));
+             lp->stopped = 1;
+             lp->resumed = 1;
+             add_thread (linux_target, lp->ptid);
+           }
+         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.  */
+             linux_nat_debug_printf
+               ("Saving LWP %d status %s in stopped_pids list",
+                lwpid, status_to_str (status).c_str ());
+             add_to_pid_list (&stopped_pids, lwpid, status);
+           }
+       }
+      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.  */
+         for (inferior *inf : all_inferiors (linux_target))
+           {
+             if (inf->pid == lwpid)
+               {
+                 linux_nat_debug_printf
+                   ("Re-adding thread group leader LWP %d after exit.",
+                    lwpid);
+
+                 lp = add_lwp (ptid_t (lwpid, lwpid));
+                 lp->resumed = 1;
+                 add_thread (linux_target, lp->ptid);
+                 break;
+               }
+           }
+       }
 
-      lp = add_lwp (ptid_t (lwpid, lwpid, 0));
-      lp->stopped = 1;
-      lp->resumed = 1;
-      add_thread (linux_target, lp->ptid);
+      if (lp == nullptr)
+       return;
     }
 
-  if (WIFSTOPPED (status) && !lp)
-    {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LHEW: saving LWP %ld status %s in stopped_pids list\n",
-                           (long) lwpid, status_to_str (status));
-      add_to_pid_list (&stopped_pids, lwpid, status);
-      return NULL;
-    }
-
-  /* Make sure we don't report an event for the exit of an LWP not in
-     our list, i.e. not part of the current process.  This can happen
-     if we detach from a program we originally forked and then it
-     exits.  */
-  if (!WIFSTOPPED (status) && !lp)
-    return NULL;
-
   /* This LWP is stopped now.  (And if dead, this prevents it from
      ever being continued.)  */
   lp->stopped = 1;
@@ -3007,7 +2853,7 @@ linux_nat_filter_event (int lwpid, int status)
         on.  */
       status = W_STOPCODE (SIGTRAP);
       if (linux_handle_syscall_trap (lp, 0))
-       return NULL;
+       return;
     }
   else
     {
@@ -3020,48 +2866,41 @@ linux_nat_filter_event (int lwpid, int status)
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP
       && linux_is_extended_waitstatus (status))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: Handling extended status 0x%06x\n",
-                           status);
+      linux_nat_debug_printf ("Handling extended status 0x%06x", status);
+
       if (linux_handle_extended_wait (lp, status))
-       return NULL;
+       return;
     }
 
   /* Check if the thread has exited.  */
   if (WIFEXITED (status) || WIFSIGNALED (status))
     {
-      if (!report_thread_events
-         && num_lwps (lp->ptid.pid ()) > 1)
+      if (!report_thread_events && !is_leader (lp))
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LLW: %s exited.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("%s exited.",
+                                 lp->ptid.to_string ().c_str ());
 
-         /* If there is at least one more LWP, then the exit signal
+         /* If this was not the leader exiting, then the exit signal
             was not the end of the debugged application and should be
             ignored.  */
          exit_lwp (lp);
-         return NULL;
+         return;
        }
 
       /* Note that even if the leader was ptrace-stopped, it can still
         exit, if e.g., some other thread brings down the whole
         process (calls `exit').  So don't assert that the lwp is
         resumed.  */
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LWP %ld exited (resumed=%d)\n",
-                           lp->ptid.lwp (), lp->resumed);
+      linux_nat_debug_printf ("LWP %ld exited (resumed=%d)",
+                             lp->ptid.lwp (), lp->resumed);
 
       /* Dead LWP's aren't expected to reported a pending sigstop.  */
       lp->signalled = 0;
 
       /* Store the pending event in the waitstatus, because
         W_EXITCODE(0,0) == 0.  */
-      store_waitstatus (&lp->waitstatus, status);
-      return lp;
+      lp->waitstatus = host_status_to_waitstatus (status);
+      return;
     }
 
   /* Make sure we don't report a SIGSTOP that we sent ourselves in
@@ -3073,25 +2912,21 @@ linux_nat_filter_event (int lwpid, int status)
 
       if (lp->last_resume_kind == resume_stop)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LLW: resume_stop SIGSTOP caught for %s.\n",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf ("resume_stop SIGSTOP caught for %s.",
+                                 lp->ptid.to_string ().c_str ());
        }
       else
        {
          /* This is a delayed SIGSTOP.  Filter out the event.  */
 
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LLW: %s %s, 0, 0 (discard delayed SIGSTOP)\n",
-                               lp->step ?
-                               "PTRACE_SINGLESTEP" : "PTRACE_CONT",
-                               target_pid_to_str (lp->ptid).c_str ());
+         linux_nat_debug_printf
+           ("%s %s, 0, 0 (discard delayed SIGSTOP)",
+            lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+            lp->ptid.to_string ().c_str ());
 
          linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
          gdb_assert (lp->resumed);
-         return NULL;
+         return;
        }
     }
 
@@ -3100,25 +2935,20 @@ linux_nat_filter_event (int lwpid, int status)
   if (lp->ignore_sigint
       && WIFSTOPPED (status) && WSTOPSIG (status) == SIGINT)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: Delayed SIGINT caught for %s.\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("Delayed SIGINT caught for %s.",
+                             lp->ptid.to_string ().c_str ());
 
       /* This is a delayed SIGINT.  */
       lp->ignore_sigint = 0;
 
       linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: %s %s, 0, 0 (discard SIGINT)\n",
-                           lp->step ?
-                           "PTRACE_SINGLESTEP" : "PTRACE_CONT",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("%s %s, 0, 0 (discard SIGINT)",
+                             lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+                             lp->ptid.to_string ().c_str ());
       gdb_assert (lp->resumed);
 
       /* Discard the event.  */
-      return NULL;
+      return;
     }
 
   /* Don't report signals that GDB isn't interested in, such as
@@ -3161,16 +2991,13 @@ linux_nat_filter_event (int lwpid, int status)
          && !linux_wstatus_maybe_breakpoint (status))
        {
          linux_resume_one_lwp (lp, lp->step, signo);
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LLW: %s %s, %s (preempt 'handle')\n",
-                               lp->step ?
-                               "PTRACE_SINGLESTEP" : "PTRACE_CONT",
-                               target_pid_to_str (lp->ptid).c_str (),
-                               (signo != GDB_SIGNAL_0
-                                ? strsignal (gdb_signal_to_host (signo))
-                                : "0"));
-         return NULL;
+         linux_nat_debug_printf
+           ("%s %s, %s (preempt 'handle')",
+            lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+            lp->ptid.to_string ().c_str (),
+            (signo != GDB_SIGNAL_0
+             ? strsignal (gdb_signal_to_host (signo)) : "0"));
+         return;
        }
     }
 
@@ -3178,7 +3005,6 @@ linux_nat_filter_event (int lwpid, int status)
   gdb_assert (lp);
   lp->status = status;
   save_stop_reason (lp);
-  return lp;
 }
 
 /* Detect zombie thread group leaders, and "exit" them.  We can't reap
@@ -3197,38 +3023,63 @@ check_zombie_leaders (void)
       leader_lp = find_lwp_pid (ptid_t (inf->pid));
       if (leader_lp != NULL
          /* Check if there are other threads in the group, as we may
-            have raced with the inferior simply exiting.  */
+            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.  */
          && num_lwps (inf->pid) > 1
          && linux_proc_pid_is_zombie (inf->pid))
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "CZL: Thread group leader %d zombie "
-                               "(it exited, or another thread execd).\n",
-                               inf->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.  See comments on exec
-            events at the top of the file.  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_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "CZL: Thread group leader %d vanished.\n",
-                               inf->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.  */
+         linux_nat_debug_printf ("Thread group leader %d zombie "
+                                 "(it exited, or another thread execd), "
+                                 "deleting it.",
+                                 inf->pid);
          exit_lwp (leader_lp);
        }
     }
@@ -3245,12 +3096,12 @@ filter_exit_event (struct lwp_info *event_child,
 {
   ptid_t ptid = event_child->ptid;
 
-  if (num_lwps (ptid.pid ()) > 1)
+  if (!is_leader (event_child))
     {
       if (report_thread_events)
-       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+       ourstatus->set_thread_exited (0);
       else
-       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+       ourstatus->set_ignore ();
 
       exit_lwp (event_child);
     }
@@ -3260,27 +3111,25 @@ filter_exit_event (struct lwp_info *event_child,
 
 static ptid_t
 linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
-                 int target_options)
+                 target_wait_flags target_options)
 {
   sigset_t prev_mask;
   enum resume_kind last_resume_kind;
   struct lwp_info *lp;
   int status;
 
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "LLW: enter\n");
+  linux_nat_debug_printf ("enter");
 
   /* The first time we get here after starting a new inferior, we may
      not have added it to the LWP list yet - this is the earliest
      moment at which we know its PID.  */
-  if (inferior_ptid.is_pid ())
+  if (ptid.is_pid () && find_lwp_pid (ptid) == nullptr)
     {
-      /* Upgrade the main thread's ptid.  */
-      thread_change_ptid (linux_target, inferior_ptid,
-                         ptid_t (inferior_ptid.pid (),
-                                 inferior_ptid.pid (), 0));
+      ptid_t lwp_ptid (ptid.pid (), ptid.pid ());
 
-      lp = add_initial_lwp (inferior_ptid);
+      /* Upgrade the main thread's ptid.  */
+      thread_change_ptid (linux_target, ptid, lwp_ptid);
+      lp = add_initial_lwp (lwp_ptid);
       lp->resumed = 1;
     }
 
@@ -3291,11 +3140,9 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
   lp = iterate_over_lwps (ptid, status_callback);
   if (lp != NULL)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: Using pending wait status %s for %s.\n",
-                           status_to_str (lp->status),
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("Using pending wait status %s for %s.",
+                             status_to_str (lp->status).c_str (),
+                             lp->ptid.to_string ().c_str ());
     }
 
   /* But if we don't find a pending event, we'll have to wait.  Always
@@ -3322,19 +3169,15 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
       errno = 0;
       lwpid = my_waitpid (-1, &status,  __WALL | WNOHANG);
 
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LNW: waitpid(-1, ...) returned %d, %s\n",
-                           lwpid, errno ? safe_strerror (errno) : "ERRNO-OK");
+      linux_nat_debug_printf ("waitpid(-1, ...) returned %d, %s",
+                             lwpid,
+                             errno ? safe_strerror (errno) : "ERRNO-OK");
 
       if (lwpid > 0)
        {
-         if (debug_linux_nat)
-           {
-             fprintf_unfiltered (gdb_stdlog,
-                                 "LLW: waitpid %ld received %s\n",
-                                 (long) lwpid, status_to_str (status));
-           }
+         linux_nat_debug_printf ("waitpid %ld received %s",
+                                 (long) lwpid,
+                                 status_to_str (status).c_str ());
 
          linux_nat_filter_event (lwpid, status);
          /* Retry until nothing comes out of waitpid.  A single
@@ -3364,10 +3207,9 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
         forever in the sigsuspend call below otherwise.  */
       if (iterate_over_lwps (ptid, resumed_callback) == NULL)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
+         linux_nat_debug_printf ("exit (no resumed LWP)");
 
-         ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
+         ourstatus->set_no_resumed ();
 
          restore_child_signals_mask (&prev_mask);
          return minus_one_ptid;
@@ -3377,10 +3219,9 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 
       if (target_options & TARGET_WNOHANG)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog, "LLW: exit (ignore)\n");
+         linux_nat_debug_printf ("exit (ignore)");
 
-         ourstatus->kind = TARGET_WAITKIND_IGNORE;
+         ourstatus->set_ignore ();
          restore_child_signals_mask (&prev_mask);
          return minus_one_ptid;
        }
@@ -3452,42 +3293,39 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 
   if (linux_target->low_status_is_event (status))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LLW: trap ptid is %s.\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("trap ptid is %s.",
+                             lp->ptid.to_string ().c_str ());
     }
 
-  if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  if (lp->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     {
       *ourstatus = lp->waitstatus;
-      lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      lp->waitstatus.set_ignore ();
     }
   else
-    store_waitstatus (ourstatus, status);
+    *ourstatus = host_status_to_waitstatus (status);
 
-  if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
+  linux_nat_debug_printf ("exit");
 
   restore_child_signals_mask (&prev_mask);
 
   if (last_resume_kind == resume_stop
-      && ourstatus->kind == TARGET_WAITKIND_STOPPED
+      && ourstatus->kind () == TARGET_WAITKIND_STOPPED
       && WSTOPSIG (status) == SIGSTOP)
     {
       /* A thread that has been requested to stop by GDB with
         target_stop, and it stopped cleanly, so report as SIG0.  The
         use of SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = GDB_SIGNAL_0;
+      ourstatus->set_stopped (GDB_SIGNAL_0);
     }
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED
-      || ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED
+      || ourstatus->kind () == TARGET_WAITKIND_SIGNALLED)
     lp->core = -1;
   else
     lp->core = linux_common_core_of_thread (lp->ptid);
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
     return filter_exit_event (lp, ourstatus);
 
   return lp->ptid;
@@ -3501,24 +3339,18 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
 {
   if (!lp->stopped)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "RSRL: NOT resuming LWP %s, not stopped\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("NOT resuming LWP %s, not stopped",
+                             lp->ptid.to_string ().c_str ());
     }
   else if (!lp->resumed)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "RSRL: NOT resuming LWP %s, not resumed\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("NOT resuming LWP %s, not resumed",
+                             lp->ptid.to_string ().c_str ());
     }
   else if (lwp_status_pending_p (lp))
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "RSRL: NOT resuming LWP %s, has pending status\n",
-                           target_pid_to_str (lp->ptid).c_str ());
+      linux_nat_debug_printf ("NOT resuming LWP %s, has pending status",
+                             lp->ptid.to_string ().c_str ());
     }
   else
     {
@@ -3540,13 +3372,10 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
 
          if (!leave_stopped)
            {
-             if (debug_linux_nat)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "RSRL: resuming stopped-resumed LWP %s at "
-                                   "%s: step=%d\n",
-                                   target_pid_to_str (lp->ptid).c_str (),
-                                   paddress (gdbarch, pc),
-                                   lp->step);
+             linux_nat_debug_printf
+               ("resuming stopped-resumed LWP %s at %s: step=%d",
+                lp->ptid.to_string ().c_str (), paddress (gdbarch, pc),
+                lp->step);
 
              linux_resume_one_lwp_throw (lp, lp->step, GDB_SIGNAL_0);
            }
@@ -3563,18 +3392,12 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
 
 ptid_t
 linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
-                       int target_options)
+                       target_wait_flags target_options)
 {
   ptid_t event_ptid;
 
-  if (debug_linux_nat)
-    {
-      std::string options_string = target_options_to_string (target_options);
-      fprintf_unfiltered (gdb_stdlog,
-                         "linux_nat_wait: [%s], [%s]\n",
-                         target_pid_to_str (ptid).c_str (),
-                         options_string.c_str ());
-    }
+  linux_nat_debug_printf ("[%s], [%s]", ptid.to_string ().c_str (),
+                         target_options_to_string (target_options).c_str ());
 
   /* Flush the async file first.  */
   if (target_is_async_p ())
@@ -3600,8 +3423,8 @@ linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
      may be more.  If we requested a specific lwp or process, also
      assume there may be more.  */
   if (target_is_async_p ()
-      && ((ourstatus->kind != TARGET_WAITKIND_IGNORE
-          && ourstatus->kind != TARGET_WAITKIND_NO_RESUMED)
+      && ((ourstatus->kind () != TARGET_WAITKIND_IGNORE
+          && ourstatus->kind () != TARGET_WAITKIND_NO_RESUMED)
          || ptid != minus_one_ptid))
     async_file_mark ();
 
@@ -3617,13 +3440,14 @@ kill_one_lwp (pid_t pid)
 
   errno = 0;
   kill_lwp (pid, SIGKILL);
+
   if (debug_linux_nat)
     {
       int save_errno = errno;
 
-      fprintf_unfiltered (gdb_stdlog,
-                         "KC:  kill (SIGKILL) %ld, 0, 0 (%s)\n", (long) pid,
-                         save_errno ? safe_strerror (save_errno) : "OK");
+      linux_nat_debug_printf
+       ("kill (SIGKILL) %ld, 0, 0 (%s)", (long) pid,
+        save_errno != 0 ? safe_strerror (save_errno) : "OK");
     }
 
   /* Some kernels ignore even SIGKILL for processes under ptrace.  */
@@ -3634,9 +3458,9 @@ kill_one_lwp (pid_t pid)
     {
       int save_errno = errno;
 
-      fprintf_unfiltered (gdb_stdlog,
-                         "KC:  PTRACE_KILL %ld, 0, 0 (%s)\n", (long) pid,
-                         save_errno ? safe_strerror (save_errno) : "OK");
+      linux_nat_debug_printf
+       ("PTRACE_KILL %ld, 0, 0 (%s)", (long) pid,
+        save_errno ? safe_strerror (save_errno) : "OK");
     }
 }
 
@@ -3656,10 +3480,8 @@ kill_wait_one_lwp (pid_t pid)
       res = my_waitpid (pid, NULL, __WALL);
       if (res != (pid_t) -1)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "KWC: wait %ld received unknown.\n",
-                               (long) pid);
+         linux_nat_debug_printf ("wait %ld received unknown.", (long) pid);
+
          /* The Linux kernel sometimes fails to kill a thread
             completely after PTRACE_KILL; that goes from the stop
             point in do_fork out to the one in get_signal_to_deliver
@@ -3700,10 +3522,10 @@ kill_unfollowed_fork_children (struct inferior *inf)
     {
       struct target_waitstatus *ws = &thread->pending_follow;
 
-      if (ws->kind == TARGET_WAITKIND_FORKED
-         || ws->kind == TARGET_WAITKIND_VFORKED)
+      if (ws->kind () == TARGET_WAITKIND_FORKED
+         || ws->kind () == TARGET_WAITKIND_VFORKED)
        {
-         ptid_t child_ptid = ws->value.related_pid;
+         ptid_t child_ptid = ws->child_ptid ();
          int child_pid = child_ptid.pid ();
          int child_lwp = child_ptid.lwp ();
 
@@ -3755,6 +3577,8 @@ linux_nat_target::mourn_inferior ()
 
   purge_lwp_list (pid);
 
+  close_proc_mem_file (pid);
+
   if (! forks_exist_p ())
     /* Normal case, no other forks available.  */
     inf_ptrace_target::mourn_inferior ();
@@ -3787,7 +3611,7 @@ siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
 
 static enum target_xfer_status
 linux_xfer_siginfo (enum target_object object,
-                    const char *annex, gdb_byte *readbuf,
+                   const char *annex, gdb_byte *readbuf,
                    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
                    ULONGEST *xfered_len)
 {
@@ -3847,10 +3671,8 @@ linux_nat_xfer_osdata (enum target_object object,
                       ULONGEST *xfered_len);
 
 static enum target_xfer_status
-linux_proc_xfer_partial (enum target_object object,
-                        const char *annex, gdb_byte *readbuf,
-                        const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len, ULONGEST *xfered_len);
+linux_proc_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
+                               ULONGEST offset, LONGEST len, ULONGEST *xfered_len);
 
 enum target_xfer_status
 linux_nat_target::xfer_partial (enum target_object object,
@@ -3858,8 +3680,6 @@ linux_nat_target::xfer_partial (enum target_object object,
                                const gdb_byte *writebuf,
                                ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  enum target_xfer_status xfer;
-
   if (object == TARGET_OBJECT_SIGNAL_INFO)
     return linux_xfer_siginfo (object, annex, readbuf, writebuf,
                               offset, len, xfered_len);
@@ -3878,25 +3698,21 @@ linux_nat_target::xfer_partial (enum target_object object,
     return linux_nat_xfer_osdata (object, annex, readbuf, writebuf,
                                  offset, len, xfered_len);
 
-  /* GDB calculates all addresses in the largest possible address
-     width.
-     The address width must be masked before its final use - either by
-     linux_proc_xfer_partial or inf_ptrace_target::xfer_partial.
-
-     Compare ADDR_BIT first to avoid a compiler warning on shift overflow.  */
-
   if (object == TARGET_OBJECT_MEMORY)
     {
+      /* GDB calculates all addresses in the largest possible address
+        width.  The address width must be masked before its final use
+        by linux_proc_xfer_partial.
+
+        Compare ADDR_BIT first to avoid a compiler warning on shift overflow.  */
       int addr_bit = gdbarch_addr_bit (target_gdbarch ());
 
       if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
        offset &= ((ULONGEST) 1 << addr_bit) - 1;
-    }
 
-  xfer = linux_proc_xfer_partial (object, annex, readbuf, writebuf,
-                                 offset, len, xfered_len);
-  if (xfer != TARGET_XFER_EOF)
-    return xfer;
+      return linux_proc_xfer_memory_partial (readbuf, writebuf,
+                                            offset, len, xfered_len);
+    }
 
   return inf_ptrace_target::xfer_partial (object, annex, readbuf, writebuf,
                                          offset, len, xfered_len);
@@ -3915,8 +3731,6 @@ linux_nat_target::thread_alive (ptid_t ptid)
 void
 linux_nat_target::update_thread_list ()
 {
-  struct lwp_info *lwp;
-
   /* We add/delete threads from the list as clone/exit events are
      processed, so just try deleting exited threads still in the
      thread list.  */
@@ -3924,7 +3738,7 @@ linux_nat_target::update_thread_list ()
 
   /* Update the processor core that each lwp/thread was last seen
      running on.  */
-  ALL_LWPS (lwp)
+  for (lwp_info *lwp : all_lwps ())
     {
       /* Avoid accessing /proc if the thread hasn't run since we last
         time we fetched the thread's core.  Accessing /proc becomes
@@ -3954,41 +3768,140 @@ linux_nat_target::thread_name (struct thread_info *thr)
 /* Accepts an integer PID; Returns a string representing a file that
    can be opened to get the symbols for the child process.  */
 
-char *
+const char *
 linux_nat_target::pid_to_exec_file (int pid)
 {
   return linux_proc_pid_to_exec_file (pid);
 }
 
-/* Implement the to_xfer_partial target method using /proc/<pid>/mem.
+/* Object representing an /proc/PID/mem open file.  We keep one such
+   file open per inferior.
+
+   It might be tempting to think about only ever opening one file at
+   most for all inferiors, closing/reopening the file as we access
+   memory of different inferiors, to minimize number of file
+   descriptors open, which can otherwise run into resource limits.
+   However, that does not work correctly -- if the inferior execs and
+   we haven't processed the exec event yet, and, we opened a
+   /proc/PID/mem file, we will get a mem file accessing the post-exec
+   address space, thinking we're opening it for the pre-exec address
+   space.  That is dangerous as we can poke memory (e.g. clearing
+   breakpoints) in the post-exec memory by mistake, corrupting the
+   inferior.  For that reason, we open the mem file as early as
+   possible, right after spawning, forking or attaching to the
+   inferior, when the inferior is stopped and thus before it has a
+   chance of execing.
+
+   Note that after opening the file, even if the thread we opened it
+   for subsequently exits, the open file is still usable for accessing
+   memory.  It's only when the whole process exits or execs that the
+   file becomes invalid, at which point reads/writes return EOF.  */
+
+class proc_mem_file
+{
+public:
+  proc_mem_file (ptid_t ptid, int fd)
+    : m_ptid (ptid), m_fd (fd)
+  {
+    gdb_assert (m_fd != -1);
+  }
+
+  ~proc_mem_file ()
+  {
+    linux_nat_debug_printf ("closing fd %d for /proc/%d/task/%ld/mem",
+                           m_fd, m_ptid.pid (), m_ptid.lwp ());
+    close (m_fd);
+  }
+
+  DISABLE_COPY_AND_ASSIGN (proc_mem_file);
+
+  int fd ()
+  {
+    return m_fd;
+  }
+
+private:
+  /* The LWP this file was opened for.  Just for debugging
+     purposes.  */
+  ptid_t m_ptid;
+
+  /* The file descriptor.  */
+  int m_fd = -1;
+};
+
+/* The map between an inferior process id, and the open /proc/PID/mem
+   file.  This is stored in a map instead of in a per-inferior
+   structure because we need to be able to access memory of processes
+   which don't have a corresponding struct inferior object.  E.g.,
+   with "detach-on-fork on" (the default), and "follow-fork parent"
+   (also default), we don't create an inferior for the fork child, but
+   we still need to remove breakpoints from the fork child's
+   memory.  */
+static std::unordered_map<int, proc_mem_file> proc_mem_file_map;
+
+/* Close the /proc/PID/mem file for PID.  */
+
+static void
+close_proc_mem_file (pid_t pid)
+{
+  proc_mem_file_map.erase (pid);
+}
+
+/* Open the /proc/PID/mem file for the process (thread group) of PTID.
+   We actually open /proc/PID/task/LWP/mem, as that's the LWP we know
+   exists and is stopped right now.  We prefer the
+   /proc/PID/task/LWP/mem form over /proc/LWP/mem to avoid tid-reuse
+   races, just in case this is ever called on an already-waited
+   LWP.  */
+
+static void
+open_proc_mem_file (ptid_t ptid)
+{
+  auto iter = proc_mem_file_map.find (ptid.pid ());
+  gdb_assert (iter == proc_mem_file_map.end ());
+
+  char filename[64];
+  xsnprintf (filename, sizeof filename,
+            "/proc/%d/task/%ld/mem", ptid.pid (), ptid.lwp ());
+
+  int fd = gdb_open_cloexec (filename, O_RDWR | O_LARGEFILE, 0).release ();
+
+  if (fd == -1)
+    {
+      warning (_("opening /proc/PID/mem file for lwp %d.%ld failed: %s (%d)"),
+              ptid.pid (), ptid.lwp (),
+              safe_strerror (errno), errno);
+      return;
+    }
+
+  proc_mem_file_map.emplace (std::piecewise_construct,
+                            std::forward_as_tuple (ptid.pid ()),
+                            std::forward_as_tuple (ptid, fd));
+
+  linux_nat_debug_printf ("opened fd %d for lwp %d.%ld",
+                         fd, ptid.pid (), ptid.lwp ());
+}
+
+/* Implement the to_xfer_partial target method 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.  */
+   efficient than banging away at PTRACE_PEEKTEXT.  Also, unlike
+   PTRACE_PEEKTEXT/PTRACE_POKETEXT, this works with running
+   threads.  */
 
 static enum target_xfer_status
-linux_proc_xfer_partial (enum target_object object,
-                        const char *annex, gdb_byte *readbuf,
-                        const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len, ULONGEST *xfered_len)
+linux_proc_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
+                               ULONGEST offset, LONGEST len,
+                               ULONGEST *xfered_len)
 {
-  LONGEST ret;
-  int fd;
-  char filename[64];
+  ssize_t ret;
 
-  if (object != TARGET_OBJECT_MEMORY)
+  auto iter = proc_mem_file_map.find (inferior_ptid.pid ());
+  if (iter == proc_mem_file_map.end ())
     return TARGET_XFER_EOF;
 
-  /* Don't bother for one word.  */
-  if (len < 3 * sizeof (long))
-    return TARGET_XFER_EOF;
+  int fd = iter->second.fd ();
 
-  /* We could keep this file open and cache it - possibly one per
-     thread.  That requires some juggling, but is even faster.  */
-  xsnprintf (filename, sizeof filename, "/proc/%ld/mem",
-            inferior_ptid.lwp ());
-  fd = gdb_open_cloexec (filename, ((readbuf ? O_RDONLY : O_WRONLY)
-                                   | O_LARGEFILE), 0);
-  if (fd == -1)
-    return TARGET_XFER_EOF;
+  gdb_assert (fd != -1);
 
   /* Use pread64/pwrite64 if available, since they save a syscall and can
      handle 64-bit offsets even on 32-bit platforms (for instance, SPARC
@@ -4003,10 +3916,21 @@ linux_proc_xfer_partial (enum target_object object,
           : write (fd, writebuf, len));
 #endif
 
-  close (fd);
-
-  if (ret == -1 || ret == 0)
-    return TARGET_XFER_EOF;
+  if (ret == -1)
+    {
+      linux_nat_debug_printf ("accessing fd %d for pid %d failed: %s (%d)",
+                             fd, inferior_ptid.pid (),
+                             safe_strerror (errno), errno);
+      return TARGET_XFER_E_IO;
+    }
+  else if (ret == 0)
+    {
+      /* EOF means the address space is gone, the whole process exited
+        or execed.  */
+      linux_nat_debug_printf ("accessing fd %d for pid %d got EOF",
+                             fd, inferior_ptid.pid ());
+      return TARGET_XFER_EOF;
+    }
   else
     {
       *xfered_len = ret;
@@ -4014,7 +3938,6 @@ linux_proc_xfer_partial (enum target_object object,
     }
 }
 
-
 /* Parse LINE as a signal set and add its set bits to SIGS.  */
 
 static void
@@ -4115,7 +4038,7 @@ linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
   int pid = inferior_ptid.pid ();
   std::vector<static_tracepoint_marker> markers;
   const char *p = s;
-  ptid_t ptid = ptid_t (pid, 0, 0);
+  ptid_t ptid = ptid_t (pid, 0);
   static_tracepoint_marker marker;
 
   /* Pause all */
@@ -4149,28 +4072,22 @@ linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
   return markers;
 }
 
-/* target_is_async_p implementation.  */
-
-bool
-linux_nat_target::is_async_p ()
-{
-  return linux_is_async_p ();
-}
-
 /* target_can_async_p implementation.  */
 
 bool
 linux_nat_target::can_async_p ()
 {
-  /* We're always async, unless the user explicitly prevented it with the
-     "maint set target-async" command.  */
-  return target_async_permitted;
+  /* This flag should be checked in the common target.c code.  */
+  gdb_assert (target_async_permitted);
+  
+  /* Otherwise, this targets is always able to support async mode.  */
+  return true;
 }
 
 bool
 linux_nat_target::supports_non_stop ()
 {
-  return 1;
+  return true;
 }
 
 /* to_always_non_stop_p implementation.  */
@@ -4178,28 +4095,19 @@ linux_nat_target::supports_non_stop ()
 bool
 linux_nat_target::always_non_stop_p ()
 {
-  return 1;
+  return true;
 }
 
-/* True if we want to support multi-process.  To be removed when GDB
-   supports multi-exec.  */
-
-int linux_multi_process = 1;
-
 bool
 linux_nat_target::supports_multi_process ()
 {
-  return linux_multi_process;
+  return true;
 }
 
 bool
 linux_nat_target::supports_disable_randomization ()
 {
-#ifdef HAVE_PERSONALITY
-  return 1;
-#else
-  return 0;
-#endif
+  return true;
 }
 
 /* SIGCHLD handler that serves two purposes: In non-stop/async mode,
@@ -4215,10 +4123,11 @@ sigchld_handler (int signo)
   if (debug_linux_nat)
     gdb_stdlog->write_async_safe ("sigchld\n", sizeof ("sigchld\n") - 1);
 
-  if (signo == SIGCHLD
-      && linux_nat_event_pipe[0] != -1)
-    async_file_mark (); /* Let the event loop know that there are
-                          events to handle.  */
+  if (signo == SIGCHLD)
+    {
+      /* Let the event loop know that there are events to handle.  */
+      linux_nat_target::async_file_mark_if_open ();
+    }
 
   errno = old_errno;
 }
@@ -4228,51 +4137,7 @@ sigchld_handler (int signo)
 static void
 handle_target_event (int error, gdb_client_data client_data)
 {
-  inferior_event_handler (INF_REG_EVENT, NULL);
-}
-
-/* Create/destroy the target events pipe.  Returns previous state.  */
-
-static int
-linux_async_pipe (int enable)
-{
-  int previous = linux_is_async_p ();
-
-  if (previous != enable)
-    {
-      sigset_t prev_mask;
-
-      /* Block child signals while we create/destroy the pipe, as
-        their handler writes to it.  */
-      block_child_signals (&prev_mask);
-
-      if (enable)
-       {
-         if (gdb_pipe_cloexec (linux_nat_event_pipe) == -1)
-           internal_error (__FILE__, __LINE__,
-                           "creating event pipe failed.");
-
-         fcntl (linux_nat_event_pipe[0], F_SETFL, O_NONBLOCK);
-         fcntl (linux_nat_event_pipe[1], F_SETFL, O_NONBLOCK);
-       }
-      else
-       {
-         close (linux_nat_event_pipe[0]);
-         close (linux_nat_event_pipe[1]);
-         linux_nat_event_pipe[0] = -1;
-         linux_nat_event_pipe[1] = -1;
-       }
-
-      restore_child_signals_mask (&prev_mask);
-    }
-
-  return previous;
-}
-
-int
-linux_nat_target::async_wait_fd ()
-{
-  return linux_nat_event_pipe[0];
+  inferior_event_handler (INF_REG_EVENT);
 }
 
 /* target_async implementation.  */
@@ -4280,23 +4145,30 @@ linux_nat_target::async_wait_fd ()
 void
 linux_nat_target::async (int enable)
 {
+  if ((enable != 0) == is_async_p ())
+    return;
+
+  /* Block child signals while we create/destroy the pipe, as their
+     handler writes to it.  */
+  gdb::block_signals blocker;
+
   if (enable)
     {
-      if (!linux_async_pipe (1))
-       {
-         add_file_handler (linux_nat_event_pipe[0],
-                           handle_target_event, NULL);
-         /* There may be pending events to handle.  Tell the event loop
-            to poll them.  */
-         async_file_mark ();
-       }
+      if (!async_file_open ())
+       internal_error (__FILE__, __LINE__, "creating event pipe failed.");
+
+      add_file_handler (async_wait_fd (), handle_target_event, NULL,
+                       "linux-nat");
+
+      /* There may be pending events to handle.  Tell the event loop
+        to poll them.  */
+      async_file_mark ();
     }
   else
     {
-      delete_file_handler (linux_nat_event_pipe[0]);
-      linux_async_pipe (0);
+      delete_file_handler (async_wait_fd ());
+      async_file_close ();
     }
-  return;
 }
 
 /* Stop an LWP, and push a GDB_SIGNAL_0 stop status if no other
@@ -4307,19 +4179,14 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
 {
   if (!lwp->stopped)
     {
-      if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog,
-                           "LNSL: running -> suspending %s\n",
-                           target_pid_to_str (lwp->ptid).c_str ());
+      linux_nat_debug_printf ("running -> suspending %s",
+                             lwp->ptid.to_string ().c_str ());
 
 
       if (lwp->last_resume_kind == resume_stop)
        {
-         if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog,
-                               "linux-nat: already stopping LWP %ld at "
-                               "GDB's request\n",
-                               lwp->ptid.lwp ());
+         linux_nat_debug_printf ("already stopping LWP %ld at GDB's request",
+                                 lwp->ptid.lwp ());
          return 0;
        }
 
@@ -4333,14 +4200,11 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
       if (debug_linux_nat)
        {
          if (find_thread_ptid (linux_target, lwp->ptid)->stop_requested)
-           fprintf_unfiltered (gdb_stdlog,
-                               "LNSL: already stopped/stop_requested %s\n",
-                               target_pid_to_str (lwp->ptid).c_str ());
+           linux_nat_debug_printf ("already stopped/stop_requested %s",
+                                   lwp->ptid.to_string ().c_str ());
          else
-           fprintf_unfiltered (gdb_stdlog,
-                               "LNSL: already stopped/no "
-                               "stop_requested yet %s\n",
-                               target_pid_to_str (lwp->ptid).c_str ());
+           linux_nat_debug_printf ("already stopped/no stop_requested yet %s",
+                                   lwp->ptid.to_string ().c_str ());
        }
     }
   return 0;
@@ -4349,19 +4213,10 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
 void
 linux_nat_target::stop (ptid_t ptid)
 {
+  LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT;
   iterate_over_lwps (ptid, linux_nat_stop_lwp);
 }
 
-void
-linux_nat_target::close ()
-{
-  /* Unregister from the event loop.  */
-  if (is_async_p ())
-    async (0);
-
-  inf_ptrace_target::close ();
-}
-
 /* When requests are passed down from the linux-nat layer to the
    single threaded inf-ptrace layer, ptids of (lwpid,0,0) form are
    used.  The address space pointer is stored in the inferior object,
@@ -4549,14 +4404,14 @@ void _initialize_linux_nat ();
 void
 _initialize_linux_nat ()
 {
-  add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance,
-                            &debug_linux_nat, _("\
-Set debugging of GNU/Linux lwp module."), _("\
-Show debugging of GNU/Linux lwp module."), _("\
-Enables printf debugging output."),
-                            NULL,
-                            show_debug_linux_nat,
-                            &setdebuglist, &showdebuglist);
+  add_setshow_boolean_cmd ("linux-nat", class_maintenance,
+                          &debug_linux_nat, _("\
+Set debugging of GNU/Linux native target."), _("       \
+Show debugging of GNU/Linux native target."), _("      \
+When on, print debug messages relating to the GNU/Linux native target."),
+                          nullptr,
+                          show_debug_linux_nat,
+                          &setdebuglist, &showdebuglist);
 
   add_setshow_boolean_cmd ("linux-namespaces", class_maintenance,
                           &debug_linux_namespaces, _("\
@@ -4589,16 +4444,24 @@ Enables printf debugging output."),
    the GNU/Linux Threads library and therefore doesn't really belong
    here.  */
 
-/* Return the set of signals used by the threads library in *SET.  */
+/* NPTL reserves the first two RT signals, but does not provide any
+   way for the debugger to query the signal numbers - fortunately
+   they don't change.  */
+static int lin_thread_signals[] = { __SIGRTMIN, __SIGRTMIN + 1 };
 
-void
-lin_thread_get_thread_signals (sigset_t *set)
+/* See linux-nat.h.  */
+
+unsigned int
+lin_thread_get_thread_signal_num (void)
 {
-  sigemptyset (set);
+  return sizeof (lin_thread_signals) / sizeof (lin_thread_signals[0]);
+}
+
+/* See linux-nat.h.  */
 
-  /* NPTL reserves the first two RT signals, but does not provide any
-     way for the debugger to query the signal numbers - fortunately
-     they don't change.  */
-  sigaddset (set, __SIGRTMIN);
-  sigaddset (set, __SIGRTMIN + 1);
+int
+lin_thread_get_thread_signal (unsigned int i)
+{
+  gdb_assert (i < lin_thread_get_thread_signal_num ());
+  return lin_thread_signals[i];
 }