thread/exit problems with glibc 2.2.5
Thorsten Kukuk
kukuk@suse.de
Sat Feb 16 12:01:00 GMT 2002
Hi,
I have appended a short test program, which fails with glibc 2.2.5,
but works fine with all prior versions.
The program defines one thread as signal handler. With glibc 2.2.4
and prior, I could send this thread a TERM signal and the whole
process exits:
Hilbert:/suse/kukuk # ./thread_test
Pid of sig_handler=2625
Signal (15) for quitting program arrived.
But with glibc 2.2.5, the signal handler thread exits without
printing the message. Another thread is in zombie state and the
main thread still continues to run:
kukuk@allen:~> ./thread_test
Pid of sig_handler=4769
kukuk@allen:~> ps ax|grep thread_test
4766 pts/1 S 0:00 ./thread_test
4768 pts/1 S 0:00 ./thread_test
4769 pts/1 S 0:00 ./thread_test
kukuk@allen:~> kill -TERM 4769
kukuk@allen:~> ps ax|grep thread_test
4766 pts/1 S 0:00 ./thread_test
4768 pts/1 Z 0:00 [thread_test <defunct>]
6125 pts/2 S 0:00 grep thread_test
Any ideas what goes wrong now? Why does I not get the printf, and
why does the exit(0) does not exit the program?
Thorsten
--
Thorsten Kukuk http://www.suse.de/~kukuk/ kukuk@suse.de
SuSE Linux AG Deutschherrenstr. 15-19 D-90429 Nuernberg
--------------------------------------------------------------------
Key fingerprint = A368 676B 5E1B 3E46 CFCE 2D97 F8FD 4E23 56C6 FB4B
-------------- next part --------------
#define _GNU_SOURCE /* for GLIBC */
#define _POSIX_PTHREAD_SEMANTICS /* for Solaris threads */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <signal.h>
#include <locale.h>
#include <libintl.h>
#include <pthread.h>
static int pid_is_written = 0;
static pthread_mutex_t mutex_pid = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond_pid = PTHREAD_COND_INITIALIZER;
/* Thread for handling signals */
static void *
sig_handler (void *v_param)
{
struct flock lock;
sigset_t sigs_to_catch;
int caught;
printf ("Pid of sig_handler=%d\n", getpid ());
/* Signal the main thread that we have the pid printed */
pthread_mutex_lock(&mutex_pid);
pid_is_written = 1;
pthread_cond_broadcast(&cond_pid);
pthread_mutex_unlock(&mutex_pid);
sigemptyset (&sigs_to_catch);
sigaddset (&sigs_to_catch, SIGCHLD);
sigaddset (&sigs_to_catch, SIGTERM);
sigaddset (&sigs_to_catch, SIGINT);
sigaddset (&sigs_to_catch, SIGQUIT);
sigaddset (&sigs_to_catch, SIGSEGV);
sigaddset (&sigs_to_catch, SIGHUP);
while (1)
{
sigwait (&sigs_to_catch, &caught);
switch (caught)
{
case SIGCHLD:
printf ("SIGCHLD arrived, what should I do ?\n");
break;
case SIGTERM:
case SIGINT:
case SIGQUIT:
case SIGSEGV:
/* Clean up if we quit the program. */
printf ("Signal (%d) for quitting program arrived.\n", caught);
exit (0);
break;
case SIGHUP:
/* Reload config file */
printf ("SIGHUP arrived, reloading config file.\n");
break;
default:
printf ("Unknown signal: %d\n", caught);
break;
}
}
}
int
main (int argc, char **argv)
{
sigset_t sigs_to_block;
pthread_t sig_thread;
sigemptyset (&sigs_to_block);
sigaddset (&sigs_to_block, SIGCHLD);
sigaddset (&sigs_to_block, SIGTERM);
sigaddset (&sigs_to_block, SIGINT);
sigaddset (&sigs_to_block, SIGQUIT);
sigaddset (&sigs_to_block, SIGSEGV);
sigaddset (&sigs_to_block, SIGHUP);
if (pthread_sigmask (SIG_BLOCK, &sigs_to_block, NULL) != 0)
{
printf ("Could not block signals.\n");
exit (1);
}
pthread_create (&sig_thread, NULL, &sig_handler, NULL);
/* wait until signal thread has created the pid file */
pthread_mutex_lock(&mutex_pid);
while (pid_is_written < 1)
{
pthread_cond_wait(&cond_pid, &mutex_pid);
}
pthread_mutex_unlock(&mutex_pid);
while (1)
sleep (5);
return 1;
}
More information about the Libc-hacker
mailing list