This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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


Attachment: bug287.patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]