- - 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.
-
- - When a non-leader thread execs, that thread just vanishes
- without reporting an exit (so we'd hang if we waited for it
- explicitly in that case). The exec event is reported to
- the TGID pid. */
-
- errno = 0;
- lwpid = my_waitpid (-1, &status, __WCLONE | WNOHANG);
- if (lwpid == 0 || (lwpid == -1 && errno == ECHILD))
- lwpid = my_waitpid (-1, &status, WNOHANG);
-
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNW: waitpid(-1, ...) returned %d, %s\n",
- lwpid, errno ? safe_strerror (errno) : "ERRNO-OK");
-
- if (lwpid > 0)
- {
- /* If this is true, then we paused LWPs momentarily, and may
- now have pending events to handle. */
- int new_pending;
-
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "LLW: waitpid %ld received %s\n",
- (long) lwpid, status_to_str (status));
- }
-
- lp = linux_nat_filter_event (lwpid, status, &new_pending);
-
- /* STATUS is now no longer valid, use LP->STATUS instead. */
- status = 0;
-
- if (lp && !ptid_match (lp->ptid, ptid))
- {
- gdb_assert (lp->resumed);
-
- if (debug_linux_nat)
- fprintf (stderr,
- "LWP %ld got an event %06x, leaving pending.\n",
- ptid_get_lwp (lp->ptid), lp->status);
-
- if (WIFSTOPPED (lp->status))
- {
- if (WSTOPSIG (lp->status) != SIGSTOP)
- {
- /* Cancel breakpoint hits. The breakpoint may
- be removed before we fetch events from this
- process to report to the core. It is best
- not to assume the moribund breakpoints
- heuristic always handles these cases --- it
- could be too many events go through to the
- core before this one is handled. All-stop
- always cancels breakpoint hits in all
- threads. */
- if (non_stop
- && linux_nat_lp_status_is_event (lp)
- && cancel_breakpoint (lp))
- {
- /* Throw away the SIGTRAP. */
- lp->status = 0;
-
- if (debug_linux_nat)
- fprintf (stderr,
- "LLW: LWP %ld hit a breakpoint while"
- " waiting for another process;"
- " cancelled it\n",
- ptid_get_lwp (lp->ptid));
- }
- lp->stopped = 1;
- }
- else
- {
- lp->stopped = 1;
- lp->signalled = 0;
- }
- }
- else if (WIFEXITED (lp->status) || WIFSIGNALED (lp->status))
- {
- if (debug_linux_nat)
- fprintf (stderr,
- "Process %ld exited while stopping LWPs\n",
- ptid_get_lwp (lp->ptid));
-
- /* This was the last lwp in the process. Since
- events are serialized to GDB core, and we can't
- report this one right now, but GDB core and the
- other target layers will want to be notified
- about the exit code/signal, leave the status
- pending for the next time we're able to report
- it. */
-
- /* Prevent trying to stop this thread again. We'll
- never try to resume it because it has a pending
- status. */
- lp->stopped = 1;
-
- /* Dead LWP's aren't expected to reported a pending
- sigstop. */
- lp->signalled = 0;
-
- /* Store the pending event in the waitstatus as
- well, because W_EXITCODE(0,0) == 0. */
- store_waitstatus (&lp->waitstatus, lp->status);
- }
-
- /* Keep looking. */
- lp = NULL;
- }