Solaris, target_wait(), don't rely on inferior_ptid
authorPedro Alves <palves@redhat.com>
Mon, 22 Jun 2020 09:54:08 +0000 (10:54 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 22 Jun 2020 10:10:49 +0000 (11:10 +0100)
Debugging on Solaris is broken, with the procfs target backend failing
with:

 procfs: couldn't find pid 0 in procinfo list.

as soon as you start a program.

The problem is procfs_target::wait assuming that inferior_ptid is
meaningful on entry, but, since the multi-target series, inferior_ptid
is null_ptid before we call target_wait, in infrun.c:

  static ptid_t
  do_target_wait_1 (inferior *inf, ptid_t ptid,
    target_waitstatus *status, int options)
  {
...
    /* We know that we are looking for an event in the target of inferior
       INF, but we don't know which thread the event might come from.  As
       such we want to make sure that INFERIOR_PTID is reset so that none of
       the wait code relies on it - doing so is always a mistake.  */
    switch_to_inferior_no_thread (inf);

This patch tweaks the backend to remove the assumption that
inferior_ptid points at something.  sol-thread.c (the thread_stratum
that sits on top of procfs.c) also has the same issue.

Some spots in procfs_target::wait were returning
TARGET_WAITKIND_SPURIOUS+inferior_ptid.  This commit replaces those
with waiting again without returning to the core.  This fixes the
relying on inferior_ptid, and also should fix the issue discussed
here:
  https://sourceware.org/pipermail/gdb/2020-May/048616.html
  https://sourceware.org/pipermail/gdb/2020-June/048660.html

gdb/ChangeLog:
2020-06-22  Pedro Alves  <palves@redhat.com>

PR gdb/25939
* procfs.c (procfs_target::wait): Don't reference inferior_ptid.
Use the current inferior instead.  Don't return
TARGET_WAITKIND_SPURIOUS/inferior_ptid -- instead continue and
wait again.
* sol-thread.c (sol_thread_target::wait): Don't reference
inferior_ptid.
(ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs)
(sol_update_thread_list_callback): Use the current inferior's pid
instead of inferior_ptid.

gdb/ChangeLog
gdb/procfs.c
gdb/sol-thread.c

index 565a71a78d8a8096325b9399aeaf11259a98a0b8..b4473f8bd1b422f09eeed084e5206d179a38dd4d 100644 (file)
@@ -1,3 +1,16 @@
+2020-06-22  Pedro Alves  <palves@redhat.com>
+
+       PR gdb/25939
+       * procfs.c (procfs_target::wait): Don't reference inferior_ptid.
+       Use the current inferior instead.  Don't return
+       TARGET_WAITKIND_SPURIOUS/inferior_ptid -- instead continue and
+       wait again.
+       * sol-thread.c (sol_thread_target::wait): Don't reference
+       inferior_ptid.
+       (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs)
+       (sol_update_thread_list_callback): Use the current inferior's pid
+       instead of inferior_ptid.
+
 2020-06-21  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * procfs.c: Cleanup many comments.
index 6360436ce5b573934e2945df48a63aadfd9f0a1a..65243b1e7c584a3f2a70ad5289faadd3a51265c9 100644 (file)
@@ -2052,7 +2052,11 @@ wait_again:
   retval   = ptid_t (-1);
 
   /* Find procinfo for main process.  */
-  pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
+
+  /* procfs_target currently only supports one inferior.  */
+  inferior *inf = current_inferior ();
+
+  pi = find_procinfo_or_die (inf->pid, 0);
   if (pi)
     {
       /* We must assume that the status is stale now...  */
@@ -2079,10 +2083,10 @@ wait_again:
              wait_retval = ::wait (&wstat); /* "wait" for the child's exit.  */
 
              /* Wrong child?  */
-             if (wait_retval != inferior_ptid.pid ())
+             if (wait_retval != inf->pid)
                error (_("procfs: couldn't stop "
                         "process %d: wait returned %d."),
-                      inferior_ptid.pid (), wait_retval);
+                      inf->pid, wait_retval);
              /* FIXME: might I not just use waitpid?
                 Or try find_procinfo to see if I know about this child?  */
              retval = ptid_t (wait_retval);
@@ -2137,13 +2141,11 @@ wait_again:
                      printf_unfiltered (_("[%s exited]\n"),
                                         target_pid_to_str (retval).c_str ());
                    delete_thread (find_thread_ptid (this, retval));
-                   status->kind = TARGET_WAITKIND_SPURIOUS;
-                   return retval;
+                   target_continue_no_signal (ptid);
+                   goto wait_again;
                  }
                else if (what == SYS_exit)
                  {
-                   struct inferior *inf;
-
                    /* Handle SYS_exit call only.  */
                    /* Stopped at entry to SYS_exit.
                       Make it runnable, resume it, then use
@@ -2158,14 +2160,13 @@ wait_again:
                    if (!proc_run_process (pi, 0, 0))
                      proc_error (pi, "target_wait, run_process", __LINE__);
 
-                   inf = find_inferior_pid (this, pi->pid);
                    if (inf->attach_flag)
                      {
                        /* Don't call wait: simulate waiting for exit,
                           return a "success" exit code.  Bogus: what if
                           it returns something else?  */
                        wstat = 0;
-                       retval = inferior_ptid;  /* ? ? ? */
+                       retval = ptid_t (inf->pid);  /* ? ? ? */
                      }
                    else
                      {
@@ -2204,19 +2205,9 @@ wait_again:
                                           i, sysargs[i]);
                      }
 
-                   if (status)
-                     {
-                       /* How to exit gracefully, returning "unknown
-                          event".  */
-                       status->kind = TARGET_WAITKIND_SPURIOUS;
-                       return inferior_ptid;
-                     }
-                   else
-                     {
-                       /* How to keep going without returning to wfi: */
-                       target_continue_no_signal (ptid);
-                       goto wait_again;
-                     }
+                   /* How to keep going without returning to wfi: */
+                   target_continue_no_signal (ptid);
+                   goto wait_again;
                  }
                break;
              case PR_SYSEXIT:
@@ -2248,9 +2239,8 @@ wait_again:
                    if (!in_thread_list (this, temp_ptid))
                      add_thread (this, temp_ptid);
 
-                   /* Return to WFI, but tell it to immediately resume.  */
-                   status->kind = TARGET_WAITKIND_SPURIOUS;
-                   return inferior_ptid;
+                   target_continue_no_signal (ptid);
+                   goto wait_again;
                  }
                else if (what == SYS_lwp_exit)
                  {
@@ -2281,8 +2271,8 @@ wait_again:
                                           i, sysargs[i]);
                      }
 
-                   status->kind = TARGET_WAITKIND_SPURIOUS;
-                   return inferior_ptid;
+                   target_continue_no_signal (ptid);
+                   goto wait_again;
                  }
                break;
              case PR_REQUESTED:
@@ -2333,7 +2323,6 @@ wait_again:
              /* Got this far without error: If retval isn't in the
                 threads database, add it.  */
              if (retval.pid () > 0
-                 && retval != inferior_ptid
                  && !in_thread_list (this, retval))
                {
                  /* We have a new thread.  We need to add it both to
index 9addf8de3ab54142ed043d225d15336f71411a41..a24d51d1db23d43f5b489760885e7d8838636575 100644 (file)
@@ -427,16 +427,6 @@ ptid_t
 sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
                         int options)
 {
-  ptid_t rtnval;
-  ptid_t save_ptid;
-
-  save_ptid = inferior_ptid;
-  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-
-  inferior_ptid = thread_to_lwp (inferior_ptid, main_ph.ptid.pid ());
-  if (inferior_ptid.pid () == -1)
-    inferior_ptid = procfs_first_available ();
-
   if (ptid.pid () != -1)
     {
       ptid_t ptid_for_warning = ptid;
@@ -449,17 +439,17 @@ sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
                 ptid_for_warning.tid ());
     }
 
-  rtnval = beneath ()->wait (ptid, ourstatus, options);
+  ptid_t rtnval = beneath ()->wait (ptid, ourstatus, options);
 
   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
     {
       /* Map the LWP of interest back to the appropriate thread ID.  */
-      rtnval = lwp_to_thread (rtnval);
-      if (rtnval.pid () == -1)
-       rtnval = save_ptid;
+      ptid_t thr_ptid = lwp_to_thread (rtnval);
+      if (thr_ptid.pid () != -1)
+       rtnval = thr_ptid;
 
       /* See if we have a new thread.  */
-      if (rtnval.tid_p () && rtnval != save_ptid)
+      if (rtnval.tid_p ())
        {
          thread_info *thr = find_thread_ptid (current_inferior (), rtnval);
          if (thr == NULL || thr->state == THREAD_EXITED)
@@ -855,7 +845,7 @@ ps_ptwrite (struct ps_prochandle *ph, psaddr_t addr,
 ps_err_e
 ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
 {
-  ptid_t ptid = ptid_t (inferior_ptid.pid (), lwpid, 0);
+  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
   struct regcache *regcache
     = get_thread_arch_regcache (current_inferior ()->process_target (),
                                ptid, target_gdbarch ());
@@ -872,7 +862,7 @@ ps_err_e
 ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid,
             const prgregset_t gregset)
 {
-  ptid_t ptid = ptid_t (inferior_ptid.pid (), lwpid, 0);
+  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
   struct regcache *regcache
     = get_thread_arch_regcache (current_inferior ()->process_target (),
                                ptid, target_gdbarch ());
@@ -925,7 +915,7 @@ ps_err_e
 ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
               prfpregset_t *fpregset)
 {
-  ptid_t ptid = ptid_t (inferior_ptid.pid (), lwpid, 0);
+  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
   struct regcache *regcache
     = get_thread_arch_regcache (current_inferior ()->process_target (),
                                ptid, target_gdbarch ());
@@ -942,7 +932,7 @@ ps_err_e
 ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
               const prfpregset_t * fpregset)
 {
-  ptid_t ptid = ptid_t (inferior_ptid.pid (), lwpid, 0);
+  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
   struct regcache *regcache
     = get_thread_arch_regcache (current_inferior ()->process_target (),
                                ptid, target_gdbarch ());
@@ -1012,7 +1002,7 @@ sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
   if (retval != TD_OK)
     return -1;
 
-  ptid_t ptid = ptid_t (inferior_ptid.pid (), 0, ti.ti_tid);
+  ptid_t ptid = ptid_t (current_inferior ()->pid, 0, ti.ti_tid);
   thread_info *thr = find_thread_ptid (current_inferior (), ptid);
   if (thr == NULL || thr->state == THREAD_EXITED)
     {