Skip site navigation (1)Skip section navigation (2)
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>