diff options
author | Roland McGrath <roland@gnu.org> | 2008-03-26 08:21:10 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2008-03-26 08:21:10 +0000 |
commit | d11dc9ecb7c1a759ac3cd4f4c77a9d0cb20fd018 (patch) | |
tree | ece3d6ad9788a3b6cc4417198494ed3ebbedce4e /nptl_db/td_thr_validate.c | |
parent | 87b9b50f0d4b92248905e95a06a13c513dc45e59 (diff) | |
download | glibc-d11dc9ecb7c1a759ac3cd4f4c77a9d0cb20fd018.tar.gz glibc-d11dc9ecb7c1a759ac3cd4f4c77a9d0cb20fd018.tar.xz glibc-d11dc9ecb7c1a759ac3cd4f4c77a9d0cb20fd018.zip |
2008-03-25 Roland McGrath <roland@redhat.com>
* structs.def: Add pid field of struct pthread. * td_ta_thr_iter.c (iterate_thread_list): Take new arg MATCH_PID. If a thread's pid does not match nor is < 0 while its tid matches nor is < 0 and equal to -MATCH_PID, ignore it. * td_thr_validate.c (td_thr_validate): Validate thread's pid/tid.
Diffstat (limited to 'nptl_db/td_thr_validate.c')
-rw-r--r-- | nptl_db/td_thr_validate.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/nptl_db/td_thr_validate.c b/nptl_db/td_thr_validate.c index 9a77250d48..adcde3c87e 100644 --- a/nptl_db/td_thr_validate.c +++ b/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; } |