Thread exit leaves zombies ...................

Manoj Nayak mnayak@in.ibm.com
Thu Nov 22 06:04:00 GMT 2001


Hi,

                                                 I am working for Linux
Technology Centre , IBM,India.Sometime back we found out a bug in
glibc-2.2.4-13 ( default glibc available in RedHat  7.2  ). I am sending
the patch for that bug , also a brief
summary for that bug.If you need the test case for this bug, please write
to me.

This bug is platform independent.

Here is the summary :

Whenever any of child thread receives a signal & it gets killed in response
to that signal, then manager thread sends the same signal to all other
child threads & main thread. ( comments in line no 828 of manager.c says
that).

After sending signal to child threads & main thread ,manager thread dies
.However main thread is not killed in response to manager thread's signal
as
it has already blocked that signal & at the same time main thread is not
waiting ( in a waitpid() call ) for manager thread to free any system
resource used by manager thread. That's why manager thread becomes zombie.

This is rectified by passing __pthread_sig_cancel as one of flags to clone
()
system call.( clone () used by main thread to spawn manager thread ).so
whenever manager thread dies, it send a __pthread_sig_cancel to main
thread. Then main thread handles that signal through
pthread_handle_sigcancel signal handler. This signal handler calls waitpid
() to release the resource used by manager thread.so manager thread won't
becomes zombie.

--- pthread.c  Tue Nov 13 10:39:12 2001
+++ /root/pthread.c Tue Nov 13 10:39:02 2001
@@ -558,18 +558,18 @@
pid = __clone2(__pthread_manager_event,
(void **) __pthread_manager_thread_bos,
THREAD_MANAGER_STACK_SIZE,
-               CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-               (void *)(long)manager_pipe[0]);
+               CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+               __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
pid = __clone(__pthread_manager_event,
(void **) __pthread_manager_thread_bos,
-              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-              (void *)(long)manager_pipe[0]);
+              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+              __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#else
pid = __clone(__pthread_manager_event,
(void **) __pthread_manager_thread_tos,
-              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-              (void *)(long)manager_pipe[0]);
+              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+              __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#endif

if (pid != -1)
@@ -599,16 +599,16 @@
#ifdef NEED_SEPARATE_REGISTER_STACK
pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
THREAD_MANAGER_STACK_SIZE,
-              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-              (void *)(long)manager_pipe[0]);
+              CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+              __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#elif _STACK_GROWS_UP
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
-             CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-             (void *)(long)manager_pipe[0]);
+             CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+             __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#else
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
-             CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
-             (void *)(long)manager_pipe[0]);
+             CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND|
+             __pthread_sig_cancel,(void *)(long)manager_pipe[0]);
#endif
}
if (__builtin_expect (pid, 0) == -1) {
@@ -847,6 +847,12 @@
waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
_exit(__pthread_exit_code);
}
+  else {
+    if (self == __pthread_main_thread) {
+      waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
+      return;
+    }
+  }
if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0)
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)

(See attached file: bug287.patch)

The patch is applied using following command in directory containing
pthread.c

patch -p0<bug287.patch


Thanks
Manoj Nayak


-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug287.patch
Type: application/octet-stream
Size: 2619 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20011122/f38039c1/attachment.obj>


More information about the Libc-alpha mailing list