From f4b8f9702fcb5d5ec57bdccb828e8df64fa76f1b Mon Sep 17 00:00:00 2001 From: kevinb Date: Thu, 10 Nov 2005 21:32:15 +0000 Subject: [PATCH] Handle LWPs that have died without leaving a status. --- rda/unix/ChangeLog | 9 +++++++++ rda/unix/lwp-pool.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/rda/unix/ChangeLog b/rda/unix/ChangeLog index 3b067600d3..0f90771fae 100644 --- a/rda/unix/ChangeLog +++ b/rda/unix/ChangeLog @@ -1,3 +1,12 @@ +2005-11-10 Kevin Buettner + + * lwp-pool.c (mark_lwp_as_dead_but_interesting): New function. + (wait_and_handle): Replace lines of code implementing guts of + new function mark_lwp_as_dead_but_interesting() with call to + that function. Make a new call to this function after it + has been determined that an lwp has exited without leaving a + status. + 2005-11-08 Kevin Buettner * lwp-pool.c (struct lwp): Add new member `do_step'. diff --git a/rda/unix/lwp-pool.c b/rda/unix/lwp-pool.c index 83aef78013..4b26cc3e37 100644 --- a/rda/unix/lwp-pool.c +++ b/rda/unix/lwp-pool.c @@ -796,6 +796,17 @@ debug_report_state_change (struct gdbserv *serv, } } +/* Remove (dead) LWP from the hash table and put it on the `interesting' + queue. */ +static void +mark_lwp_as_dead_but_interesting (struct lwp *l) +{ + hash_delete (l); + l->state = lwp_state_dead_interesting; + if (l->next) + queue_delete (l); + queue_enqueue (&interesting_queue, l); +} /* Wait for a status from the LWP L (or any LWP, if L is NULL), passing FLAGS to waitpid, and record the resulting wait status in @@ -868,15 +879,7 @@ wait_and_handle (struct gdbserv *serv, struct lwp *l, int flags) l->status = status; if (WIFEXITED (status) || WIFSIGNALED (status)) - { - /* Remove dead LWP's from the hash table, and put them in the - interesting queue. */ - hash_delete (l); - l->state = lwp_state_dead_interesting; - if (l->next) - queue_delete (l); - queue_enqueue (&interesting_queue, l); - } + mark_lwp_as_dead_but_interesting (l); else { int stopsig; @@ -1143,9 +1146,24 @@ lwp_pool_stop_all (struct gdbserv *serv) case lwp_state_running: /* A 'no such process' error here indicates an NPTL thread that has exited. */ - kill_lwp (l->pid, SIGSTOP); - l->state = lwp_state_running_stop_pending; - queue_enqueue (&stopping_queue, l); + if (kill_lwp (l->pid, SIGSTOP) < 0) + { + /* Thread has exited. See if a status is available. */ + if (wait_and_handle (serv, l, WNOHANG) < 0) + { + /* Nope, it's truly gone without providing a status. + Put it on the interesting queue so that GDB is + notified that it's gone. */ + l->status = 0; + mark_lwp_as_dead_but_interesting (l); + } + } + else + { + l->state = lwp_state_running_stop_pending; + queue_enqueue (&stopping_queue, l); + } + break; case lwp_state_stopped: -- 2.11.0