Date: Mon, 31 Mar 2003 16:40:05 -0800 (PST) From: Alex Semenyaka <alexs@ratmir.ru> To: freebsd-bugs@FreeBSD.org Subject: bin/48856: Setting SIGCHLD to SIG_IGN still leaves Message-ID: <200304010040.h310e556098225@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/48856; it has been noted by GNATS. From: Alex Semenyaka <alexs@ratmir.ru> To: freebsd-gnats-submit@FreeBSD.org, joelh@piqnet.org Cc: Subject: bin/48856: Setting SIGCHLD to SIG_IGN still leaves Date: Tue, 1 Apr 2003 04:37:02 +0400 Well, the problem is that POSIX does NOT specify that child will not be in zombie-state if you did signal(SIGCHLD, SIG_IGN). According to POSIX you the behaviour will be undefined. That's why, I believe, people does not pay too much attention to the accurate realization of this mechanism. They usually imply that if you need such control you will use sigaction(). But I think that it will be better to fix this behaviour to make it compatible with Linux and SysV way. There are a lot of reasons for this, one of them - some programs even from the base system expect Linux-behaviour from libraries in this place (not in critical section, of course, but...). See: > cd /usr/bin > grep -r SIGCHLD /usr/src/* | grep SIG_IGN | grep signal | cut -d: -f1 | grep '\.c$' | sort -u | wc -l 13 There are two places to fix: - first, it is signal() implementation in the libc, - second, it is uthread_init() in the libc_r. In the first case we need only to check if we deal with signal(SIGCHLD, SIG_IGN), and if so add SA_NOCLDWAIT to flags. That's simple and strightforward. Second case needs some explanations. The user-thread mechanism has some special interaction with the signal delivery mechanism. One part of this interaction is the additional layer between the standard user interface (set of sig... functions) and the kernel. There is special treatment of some signals on that layer. One of those signals is SIGCHLD: the only place uthreads tells what to do with it is initialization ( uthread_init() ). After then user's calls to sigaction() or signal() are NOT passed to the kernel so the flags such as SA_NOCLDWAIT could not be set. So the solution is simple here as well: we need just to set this flag in the procedure of standard uthreads SIGCHLD handler installation in uthread_init(). Complete changes involve only 3 lines (2 in signal.c, 1 in uthread_init.c). I put this changes to the sources and compiled the program from the original PR both with -lc_r and without. In both cases there was no zombie. Here the result of cvs diff -u -U1: Index: libc/gen/signal.c =================================================================== RCS file: /usr/local/FreeBSD/src/lib/libc/gen/signal.c,v retrieving revision 1.3 diff -u -U1 -r1.3 signal.c --- libc/gen/signal.c 1 Feb 2002 00:57:29 -0000 1.3 +++ libc/gen/signal.c 31 Mar 2003 23:55:21 -0000 @@ -61,2 +61,4 @@ sa.sa_flags |= SA_RESTART; + if (s == SIGCHLD && a == SIG_IGN) + sa.sa_flags |= SA_NOCLDWAIT; if (_sigaction(s, &sa, &osa) < 0) Index: libc_r/uthread/uthread_init.c =================================================================== RCS file: /usr/local/FreeBSD/src/lib/libc_r/uthread/uthread_init.c,v retrieving revision 1.45 diff -u -U1 -r1.45 uthread_init.c --- libc_r/uthread/uthread_init.c 11 Jan 2003 00:43:20 -0000 1.45 +++ libc_r/uthread/uthread_init.c 31 Mar 2003 23:54:16 -0000 @@ -438,3 +438,3 @@ act.sa_handler = (void (*) ()) _thread_sig_handler; - act.sa_flags = SA_SIGINFO | SA_RESTART; + act.sa_flags = SA_SIGINFO | SA_RESTART | SA_NOCLDWAIT; Hope it will be easely incorporated into the main repository.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304010040.h310e556098225>