From 90758db4341e2f19a1af05a09124ec7a5676304d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 18 Mar 2003 21:13:42 +0000 Subject: 2003-03-18 Roland McGrath * td_thr_event_getmsg.c (td_thr_event_getmsg): Splice the thread out of the ->nextevent linkage. --- nptl_db/td_thr_event_getmsg.c | 51 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'nptl_db/td_thr_event_getmsg.c') diff --git a/nptl_db/td_thr_event_getmsg.c b/nptl_db/td_thr_event_getmsg.c index ffd0baadc5..9008633289 100644 --- a/nptl_db/td_thr_event_getmsg.c +++ b/nptl_db/td_thr_event_getmsg.c @@ -1,5 +1,5 @@ /* Retrieve event. - Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1999. @@ -31,7 +31,7 @@ td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg) LOG ("td_thr_event_getmsg"); - /* Read the even structure from the target. */ + /* Read the event structure from the target. */ if (ps_pdread (th->th_ta_p->ph, ((char *) th->th_unique + offsetof (struct pthread, eventbuf)), @@ -56,5 +56,50 @@ td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg) &event, sizeof (td_eventbuf_t)) != PS_OK) return TD_ERR; /* XXX Other error value? */ - return TD_OK; + /* Get the pointer to the thread descriptor with the last event. + If it doesn't match TH, then walk down the list until we find it. + We must splice it out of the list so that there is no dangling + pointer to it later when it dies. */ + psaddr_t thp, prevp = th->th_ta_p->pthread_last_event; + if (ps_pdread (th->th_ta_p->ph, + prevp, &thp, sizeof (struct pthread *)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + psaddr_t next; + while (thp != 0) + { + if (ps_pdread (th->th_ta_p->ph, + (char *) thp + offsetof (struct pthread, nextevent), + &next, sizeof (struct pthread *)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (next == thp) + return TD_DBERR; + + if (thp == th->th_unique) + { + /* PREVP points at this thread, splice it out. */ + if (prevp == (char *) next + offsetof (struct pthread, nextevent)) + return TD_DBERR; + + if (ps_pdwrite (th->th_ta_p->ph, prevp, &next, sizeof next) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now clear this thread's own next pointer so it's not dangling + when the thread resumes and then chains on for its next event. */ + next = NULL; + if (ps_pdwrite (th->th_ta_p->ph, + (char *) thp + offsetof (struct pthread, nextevent), + &next, sizeof next) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; + } + + prevp = (char *) thp + offsetof (struct pthread, nextevent); + thp = next; + } + + /* Ack! This should not happen. */ + return TD_DBERR; } -- cgit v1.2.1