summaryrefslogtreecommitdiff
path: root/libc/nptl_db/td_thr_validate.c
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2008-03-27 13:22:15 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2008-03-27 13:22:15 +0000
commitca1bbff0ee443807a36d8c7bf798672589ac37f6 (patch)
tree5c44adf6728cbd3c1c4cf17f106a8c7801206be2 /libc/nptl_db/td_thr_validate.c
parent1bc40ce17eb32360b2e6e8752e0c5a4ef729e375 (diff)
Merge changes between r5247 and r5678 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@5679 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/nptl_db/td_thr_validate.c')
-rw-r--r--libc/nptl_db/td_thr_validate.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/libc/nptl_db/td_thr_validate.c b/libc/nptl_db/td_thr_validate.c
index 9a77250d4..adcde3c87 100644
--- a/libc/nptl_db/td_thr_validate.c
+++ b/libc/nptl_db/td_thr_validate.c
@@ -1,5 +1,6 @@
/* Validate a thread handle.
- Copyright (C) 1999,2001,2002,2003,2004,2007 Free Software Foundation, Inc.
+ Copyright (C) 1999,2001,2002,2003,2004,2007,2008
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
@@ -81,5 +82,28 @@ td_thr_validate (const td_thrhandle_t *th)
err = TD_OK;
}
+ if (err == TD_OK)
+ {
+ /* Verify that this is not a stale element in a fork child. */
+ pid_t match_pid = ps_getpid (th->th_ta_p->ph);
+ psaddr_t pid;
+ err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique, pthread, pid, 0);
+ if (err == TD_OK && (pid_t) (uintptr_t) pid < 0)
+ {
+ /* This was a thread that was about to fork, or it is the new sole
+ thread in a fork child. In the latter case, its tid was stored
+ via CLONE_CHILD_SETTID and so is already the proper child PID. */
+ if (-(pid_t) (uintptr_t) pid == match_pid)
+ /* It is about to do a fork, but is really still the parent PID. */
+ pid = (psaddr_t) (uintptr_t) match_pid;
+ else
+ /* It must be a fork child, whose new PID is in the tid field. */
+ err = DB_GET_FIELD (pid, th->th_ta_p, th->th_unique,
+ pthread, tid, 0);
+ }
+ if (err == TD_OK && (pid_t) (uintptr_t) pid != match_pid)
+ err = TD_NOTHR;
+ }
+
return err;
}