Date: Wed, 16 Apr 2003 07:00:34 -0700 (PDT) From: Anton Berezin <tobez@FreeBSD.org> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/49087: Signals lost in programs linked with libc_r Message-ID: <200304161400.h3GE0Yxw023149@freefall.freebsd.org>
index | next in thread | raw e-mail
The following reply was made to PR bin/49087; it has been noted by GNATS.
From: Anton Berezin <tobez@FreeBSD.org>
To: Enache Adrian <enache@rdslink.ro>
Cc: FreeBSD-gnats-submit@FreeBSD.org, fjoe@FreeBSD.org,
deischen@FreeBSD.org, marcel@FreeBSD.org
Subject: Re: bin/49087: Signals lost in programs linked with libc_r
Date: Wed, 16 Apr 2003 15:56:42 +0200
On Mon, Mar 10, 2003 at 11:28:34PM +0200, Enache Adrian wrote:
> FreeBSD seems to lose blocked signals in programs linked
> with libc_r. This bug shows up when running the perl
> test suite with a multithreaded perl ( i.e. linked to
> libc_r.so ), more precisely at test 11 of ext/POSIX/t/posix.t.
> -----< sig.c >---------------------------------------------------
> #include <unistd.h>
> #include <signal.h>
> #include <stdio.h>
>
> void sighup(int dummy)
> {
> kill(getpid(),SIGINT);
> sleep(1);
> printf("sigint delayed ...\n");
> }
>
> void sigint(int dummy)
> {
> printf("SIGINT !\n");
> }
>
> struct sigaction act;
>
> int main()
> {
> act.sa_handler = sighup;
> sigaddset(&act.sa_mask, SIGINT);
> sigaction(SIGHUP, &act, NULL);
> signal(SIGINT,sigint);
> kill(getpid(),SIGHUP);
> sleep(2);
> printf("*\n");
> return 0;
> }
> -----------------------------------------------------------------
> Any pointers appreciated.
Please try the following patch (tested an identical patch on 4.8; not
tested with -current):
Index: uthread_sig.c
===================================================================
RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_sig.c,v
retrieving revision 1.45
diff -u -r1.45 uthread_sig.c
--- uthread_sig.c 5 Mar 2003 04:28:08 -0000 1.45
+++ uthread_sig.c 16 Apr 2003 13:45:36 -0000
@@ -257,6 +257,7 @@
void (*sigfunc)(int, siginfo_t *, void *);
int saved_seqno;
sigset_t saved_sigmask;
+ sigset_t sigset;
/* Invoke the signal handler without going through the scheduler:
*/
@@ -288,8 +289,26 @@
* Only restore the signal mask if it hasn't been changed by the
* application during invocation of the signal handler:
*/
- if (curthread->sigmask_seqno == saved_seqno)
+ if (curthread->sigmask_seqno == saved_seqno) {
curthread->sigmask = saved_sigmask;
+
+ /*
+ * Just like in _pthread_sigmask(), check if
+ * there are pending signals for the running
+ * thread or process that aren't blocked.
+ * This avoids losing signals when sigaction() with
+ * non-empty sa_mask is used.
+ */
+ sigset = curthread->sigpend;
+ SIGSETOR(sigset, _process_sigpending);
+ SIGSETNAND(sigset, curthread->sigmask);
+ if (SIGNOTEMPTY(sigset))
+ /*
+ * Call the kernel scheduler which will safely
+ * install a signal frame for the running thread:
+ */
+ _thread_kern_sched_sig();
+ }
}
/*
I would be *glad* if a person which knows uthreads better than I do
reviews the patch and tells me that I am wrong and where I am wrong.
:-) That's why I am Ccing three random uthread_sig.c committers.
Cheers,
%Anton.
--
Perl is strongly typed, it just has very few types. -- Dan Sugalski
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304161400.h3GE0Yxw023149>
