Multi-target support
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index cd5cf1830d3fdc1ed4f48b7571f30538cb35dc4e..45b71ea8627fbf372a7af854a703dd22ad5aa138 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001-2019 Free Software Foundation, Inc.
+   Copyright (C) 2001-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -67,6 +67,7 @@
 #include "nat/linux-namespaces.h"
 #include "gdbsupport/fileio.h"
 #include "gdbsupport/scope-exit.h"
+#include "gdbsupport/gdb-sigmask.h"
 
 /* This comment documents high-level logic of this file.
 
@@ -514,9 +515,12 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
        }
       else
        {
-         scoped_restore save_inferior_ptid
-           = make_scoped_restore (&inferior_ptid);
-         inferior_ptid = child_ptid;
+         /* 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 ();
@@ -764,7 +768,7 @@ block_child_signals (sigset_t *prev_mask)
   if (!sigismember (&blocked_mask, SIGCHLD))
     sigaddset (&blocked_mask, SIGCHLD);
 
-  sigprocmask (SIG_BLOCK, &blocked_mask, prev_mask);
+  gdb_sigmask (SIG_BLOCK, &blocked_mask, prev_mask);
 }
 
 /* Restore child signals mask, previously returned by
@@ -773,7 +777,7 @@ block_child_signals (sigset_t *prev_mask)
 static void
 restore_child_signals_mask (sigset_t *prev_mask)
 {
-  sigprocmask (SIG_SETMASK, prev_mask, NULL);
+  gdb_sigmask (SIG_SETMASK, prev_mask, NULL);
 }
 
 /* Mask of signals to pass directly to the inferior.  */
@@ -988,7 +992,7 @@ linux_nat_switch_fork (ptid_t new_ptid)
   /* This changes the thread's ptid while preserving the gdb thread
      num.  Also changes the inferior pid, while preserving the
      inferior num.  */
-  thread_change_ptid (inferior_ptid, new_ptid);
+  thread_change_ptid (linux_target, inferior_ptid, new_ptid);
 
   /* We've just told GDB core that the thread changed target id, but,
      in fact, it really is a different thread, with different register
@@ -1001,7 +1005,7 @@ linux_nat_switch_fork (ptid_t new_ptid)
 static void
 exit_lwp (struct lwp_info *lp)
 {
-  struct thread_info *th = find_thread_ptid (lp->ptid);
+  struct thread_info *th = find_thread_ptid (linux_target, lp->ptid);
 
   if (th)
     {
@@ -1161,9 +1165,9 @@ attach_proc_task_lwp_callback (ptid_t ptid)
          /* Also add the LWP to gdb's thread list, in case a
             matching libthread_db is not found (or the process uses
             raw clone).  */
-         add_thread (lp->ptid);
-         set_running (lp->ptid, 1);
-         set_executing (lp->ptid, 1);
+         add_thread (linux_target, lp->ptid);
+         set_running (linux_target, lp->ptid, 1);
+         set_executing (linux_target, lp->ptid, 1);
        }
 
       return 1;
@@ -1202,7 +1206,7 @@ linux_nat_target::attach (const char *args, int from_tty)
   ptid = ptid_t (inferior_ptid.pid (),
                 inferior_ptid.pid (),
                 0);
-  thread_change_ptid (inferior_ptid, ptid);
+  thread_change_ptid (linux_target, inferior_ptid, ptid);
 
   /* Add the initial process as the first LWP to the list.  */
   lp = add_initial_lwp (ptid);
@@ -1303,7 +1307,7 @@ get_detach_signal (struct lwp_info *lp)
     signo = gdb_signal_from_host (WSTOPSIG (lp->status));
   else
     {
-      struct thread_info *tp = find_thread_ptid (lp->ptid);
+      struct thread_info *tp = find_thread_ptid (linux_target, lp->ptid);
 
       if (target_is_non_stop_p () && !tp->executing)
        {
@@ -1314,12 +1318,13 @@ get_detach_signal (struct lwp_info *lp)
        }
       else if (!target_is_non_stop_p ())
        {
-         struct target_waitstatus last;
          ptid_t last_ptid;
+         process_stratum_target *last_target;
 
-         get_last_target_status (&last_ptid, &last);
+         get_last_target_status (&last_target, &last_ptid, nullptr);
 
-         if (lp->ptid.lwp () == last_ptid.lwp ())
+         if (last_target == linux_target
+             && lp->ptid.lwp () == last_ptid.lwp ())
            signo = tp->suspend.stop_signal;
        }
     }
@@ -1420,7 +1425,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
          if (ret == -1)
            {
              warning (_("Couldn't reap LWP %d while detaching: %s"),
-                      lwpid, strerror (errno));
+                      lwpid, safe_strerror (errno));
            }
          else if (!WIFEXITED (status) && !WIFSIGNALED (status))
            {
@@ -1468,7 +1473,7 @@ linux_nat_target::detach (inferior *inf, int from_tty)
      inferiors running. */
 
   /* Stop all threads before detaching.  ptrace requires that the
-     thread is stopped to sucessfully detach.  */
+     thread is stopped to successfully detach.  */
   iterate_over_lwps (ptid_t (pid), stop_callback);
   /* ... and wait until all of them have reported back that
      they're no longer running.  */
@@ -1516,7 +1521,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step,
      handle the case of stepping a breakpoint instruction).  */
   if (step)
     {
-      struct regcache *regcache = get_thread_regcache (lp->ptid);
+      struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
 
       lp->stop_pc = regcache_read_pc (regcache);
     }
@@ -1535,7 +1540,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step,
   lp->stopped = 0;
   lp->core = -1;
   lp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
-  registers_changed_ptid (lp->ptid);
+  registers_changed_ptid (linux_target, lp->ptid);
 }
 
 /* Called when we try to resume a stopped LWP and that errors out.  If
@@ -1594,7 +1599,7 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
 {
   if (lp->stopped)
     {
-      struct inferior *inf = find_inferior_ptid (lp->ptid);
+      struct inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
 
       if (inf->vfork_child != NULL)
        {
@@ -1648,7 +1653,7 @@ linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
     {
       struct thread_info *thread;
 
-      thread = find_thread_ptid (lp->ptid);
+      thread = find_thread_ptid (linux_target, lp->ptid);
       if (thread != NULL)
        {
          signo = thread->suspend.stop_signal;
@@ -1805,7 +1810,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
 {
   struct target_waitstatus *ourstatus = &lp->waitstatus;
   struct gdbarch *gdbarch = target_thread_architecture (lp->ptid);
-  thread_info *thread = find_thread_ptid (lp->ptid);
+  thread_info *thread = find_thread_ptid (linux_target, lp->ptid);
   int syscall_number = (int) gdbarch_get_syscall_number (gdbarch, thread);
 
   if (stopping)
@@ -2025,15 +2030,15 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
              /* The process is not using thread_db.  Add the LWP to
                 GDB's list.  */
              target_post_attach (new_lp->ptid.lwp ());
-             add_thread (new_lp->ptid);
+             add_thread (linux_target, new_lp->ptid);
            }
 
          /* Even if we're stopping the thread for some reason
             internal to this module, from the perspective of infrun
             and the user/frontend, this new thread is running until
             it next reports a stop.  */
-         set_running (new_lp->ptid, 1);
-         set_executing (new_lp->ptid, 1);
+         set_running (linux_target, new_lp->ptid, 1);
+         set_executing (linux_target, new_lp->ptid, 1);
 
          if (WSTOPSIG (status) != SIGSTOP)
            {
@@ -2256,7 +2261,7 @@ wait_lwp (struct lwp_info *lp)
 
   if (lp->must_set_ptrace_flags)
     {
-      struct inferior *inf = find_inferior_pid (lp->ptid.pid ());
+      inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ());
       int options = linux_nat_ptrace_options (inf->attach_flag);
 
       linux_enable_event_reporting (lp->ptid.lwp (), options);
@@ -2483,7 +2488,7 @@ linux_nat_target::low_status_is_event (int status)
 static int
 stop_wait_callback (struct lwp_info *lp)
 {
-  struct inferior *inf = find_inferior_ptid (lp->ptid);
+  inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
 
   /* If this is a vfork parent, bail out, it is not going to report
      any SIGSTOP until the vfork is done with.  */
@@ -2576,7 +2581,7 @@ status_callback (struct lwp_info *lp)
   if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
       || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
     {
-      struct regcache *regcache = get_thread_regcache (lp->ptid);
+      struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
       CORE_ADDR pc;
       int discard = 0;
 
@@ -2697,7 +2702,7 @@ save_stop_reason (struct lwp_info *lp)
   if (!linux_target->low_status_is_event (lp->status))
     return;
 
-  regcache = get_thread_regcache (lp->ptid);
+  regcache = get_thread_regcache (linux_target, lp->ptid);
   gdbarch = regcache->arch ();
 
   pc = regcache_read_pc (regcache);
@@ -2959,7 +2964,7 @@ linux_nat_filter_event (int lwpid, int status)
       lp = add_lwp (ptid_t (lwpid, lwpid, 0));
       lp->stopped = 1;
       lp->resumed = 1;
-      add_thread (lp->ptid);
+      add_thread (linux_target, lp->ptid);
     }
 
   if (WIFSTOPPED (status) && !lp)
@@ -2985,7 +2990,7 @@ linux_nat_filter_event (int lwpid, int status)
 
   if (WIFSTOPPED (status) && lp->must_set_ptrace_flags)
     {
-      struct inferior *inf = find_inferior_pid (lp->ptid.pid ());
+      inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ());
       int options = linux_nat_ptrace_options (inf->attach_flag);
 
       linux_enable_event_reporting (lp->ptid.lwp (), options);
@@ -3146,9 +3151,12 @@ linux_nat_filter_event (int lwpid, int status)
 
       /* When using hardware single-step, we need to report every signal.
         Otherwise, signals in pass_mask may be short-circuited
-        except signals that might be caused by a breakpoint.  */
+        except signals that might be caused by a breakpoint, or SIGSTOP
+        if we sent the SIGSTOP and are waiting for it to arrive.  */
       if (!lp->step
          && WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status))
+         && (WSTOPSIG (status) != SIGSTOP
+             || !find_thread_ptid (linux_target, lp->ptid)->stop_requested)
          && !linux_wstatus_maybe_breakpoint (status))
        {
          linux_resume_one_lwp (lp, lp->step, signo);
@@ -3267,7 +3275,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
   if (inferior_ptid.is_pid ())
     {
       /* Upgrade the main thread's ptid.  */
-      thread_change_ptid (inferior_ptid,
+      thread_change_ptid (linux_target, inferior_ptid,
                          ptid_t (inferior_ptid.pid (),
                                  inferior_ptid.pid (), 0));
 
@@ -3303,7 +3311,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
         - If the thread group leader exits while other threads in the
           thread group still exist, waitpid(TGID, ...) hangs.  That
           waitpid won't return an exit status until the other threads
-          in the group are reapped.
+          in the group are reaped.
 
         - When a non-leader thread execs, that thread just vanishes
           without reporting an exit (so we'd hang if we waited for it
@@ -3412,7 +3420,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
   if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
       && !USE_SIGTRAP_SIGINFO)
     {
-      struct regcache *regcache = get_thread_regcache (lp->ptid);
+      struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
       struct gdbarch *gdbarch = regcache->arch ();
       int decr_pc = gdbarch_decr_pc_after_break (gdbarch);
 
@@ -3513,7 +3521,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
     }
   else
     {
-      struct regcache *regcache = get_thread_regcache (lp->ptid);
+      struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
       struct gdbarch *gdbarch = regcache->arch ();
 
       try
@@ -3723,7 +3731,7 @@ linux_nat_target::kill ()
       ptid_t ptid = ptid_t (inferior_ptid.pid ());
 
       /* Stop all threads before killing them, since ptrace requires
-        that the thread is stopped to sucessfully PTRACE_KILL.  */
+        that the thread is stopped to successfully PTRACE_KILL.  */
       iterate_over_lwps (ptid, stop_callback);
       /* ... and wait until all of them have reported back that
         they're no longer running.  */
@@ -4261,6 +4269,12 @@ linux_async_pipe (int enable)
   return previous;
 }
 
+int
+linux_nat_target::async_wait_fd ()
+{
+  return linux_nat_event_pipe[0];
+}
+
 /* target_async implementation.  */
 
 void
@@ -4318,7 +4332,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp)
 
       if (debug_linux_nat)
        {
-         if (find_thread_ptid (lwp->ptid)->stop_requested)
+         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 ());
@@ -4375,7 +4389,7 @@ linux_nat_target::thread_address_space (ptid_t ptid)
       pid = ptid.pid ();
     }
 
-  inf = find_inferior_pid (pid);
+  inf = find_inferior_pid (this, pid);
   gdb_assert (inf != NULL);
   return inf->aspace;
 }
@@ -4561,7 +4575,7 @@ Enables printf debugging output."),
   sigaction (SIGCHLD, &sigchld_action, NULL);
 
   /* Make sure we don't block SIGCHLD during a sigsuspend.  */
-  sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
+  gdb_sigmask (SIG_SETMASK, NULL, &suspend_mask);
   sigdelset (&suspend_mask, SIGCHLD);
 
   sigemptyset (&blocked_mask);
This page took 0.03695 seconds and 4 git commands to generate.