about summary refs log tree commit diff
path: root/nptl_db/td_thr_validate.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2008-03-26 08:21:10 +0000
committerRoland McGrath <roland@gnu.org>2008-03-26 08:21:10 +0000
commitd11dc9ecb7c1a759ac3cd4f4c77a9d0cb20fd018 (patch)
treeece3d6ad9788a3b6cc4417198494ed3ebbedce4e /nptl_db/td_thr_validate.c
parent87b9b50f0d4b92248905e95a06a13c513dc45e59 (diff)
downloadglibc-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.c26
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;
 }