]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit - gdb/linux-nat.c
linux-nat.c: fix a few lin_lwp_attach_lwp issues
authorPedro Alves <palves@redhat.com>
Fri, 20 Feb 2015 20:21:59 +0000 (20:21 +0000)
committerPedro Alves <palves@redhat.com>
Fri, 20 Feb 2015 20:21:59 +0000 (20:21 +0000)
commit3b27ef472df3b4cdcdd54629281610d594c99c97
tree44545410a0e4f73c60f20845553b1b665473fe9b
parent1cc28231d23d8dd604d3482dd4bd46031d5a4052
linux-nat.c: fix a few lin_lwp_attach_lwp issues

This function has a few latent bugs that are triggered by a non-stop
mode test that will be added in a subsequent patch.

First, as described in the function's intro comment, the function is
supposed to return 1 if we're already auto attached to the thread, but
haven't processed the PTRACE_EVENT_CLONE event of its parent thread
yet.

Then, we may find that we're trying to attach to a clone child that
hasn't yet stopped for its initial stop, and therefore 'waitpid(...,
WNOHANG)' returns 0.  In that case, we're currently adding the LWP to
the stopped_pids list, which results in linux_handle_extended_wait
skipping the waitpid call on the child, and thus confusing things
later on when the child eventually reports the stop.

Then, the tail end of lin_lwp_attach_lwp always sets the
last_resume_kind of the LWP to resume_stop, which is wrong given that
the user may be doing "info threads" while some threads are running.

And then, the else branch of lin_lwp_attach_lwp always sets the
stopped flag of the LWP.  This branch is reached if the LWP is the
main LWP, which may well be running at this point (to it's wrong to
set its 'stopped' flag).

AFAICS, there's no reason anymore for special-casing the main/leader
LWP here:

- For the "attach" case, linux_nat_attach already adds the main LWP to
the lwp list, and sets its 'stopped' flag.

- For the "run" case, after linux_nat_create_inferior, end up in
linux_nat_wait_1 here:

  /* 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 (ptid_is_pid (inferior_ptid))
    {
      /* Upgrade the main thread's ptid.  */
      thread_change_ptid (inferior_ptid,
  ptid_build (ptid_get_pid (inferior_ptid),
      ptid_get_pid (inferior_ptid), 0));

      lp = add_initial_lwp (inferior_ptid);
      lp->resumed = 1;
    }

... which adds the LWP to the LWP list already, before
lin_lwp_attach_lwp can ever be reached.

gdb/ChangeLog:
2015-02-20  Pedro Alves  <palves@redhat.com>

* linux-nat.c (lin_lwp_attach_lwp): No longer special case the
main LWP.  Handle the case of waitpid returning 0 if we're already
attached to the LWP.  Don't set the LWP's last_resume_kind to
resume_stop if we already knew about the LWP.
(linux_nat_filter_event): Add debug logs.
gdb/ChangeLog
gdb/linux-nat.c