Subject: Re: Signal catching changes broke Matlab
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 09/16/2004 19:58:35
In article <20040916184831.CC04C4922EC@s102-n054.tele2.cz>,
Jaromir Dolecek <jdolecek@NetBSD.org> wrote:
>Hi,
>
>Mark Davies tracked down the problem with Matlab. It's caused
>by change in rev. 1.190 of sys/kern/kern_sig.
>
>Problem is, how would be fix this properly? Just backing
>the change off is an option. Perhaps only do the resetting
>if the signals are not shared (i.e. p->p_sigacts.sa_refcnt == 1) ?

Possibly. Try the following patch.

1. remove sigtrapmask; it is unused.
2. fix the code to behave like the comment says; when we unshare sigacts
   we preserve the state (XXX: Is that what we want in the execsigs() case?)
3. add sigactsunshare() when we set the signal to default.

christos

Index: kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.197
diff -u -u -r1.197 kern_sig.c
--- kern_sig.c	8 Jun 2004 19:35:30 -0000	1.197
+++ kern_sig.c	16 Sep 2004 19:55:43 -0000
@@ -88,7 +88,7 @@
 static ksiginfo_t *ksiginfo_get(struct proc *, int);
 static void	kpsignal2(struct proc *, const ksiginfo_t *, int);
 
-sigset_t	contsigmask, stopsigmask, sigcantmask, sigtrapmask;
+sigset_t	contsigmask, stopsigmask, sigcantmask;
 
 struct pool	sigacts_pool;	/* memory pool for sigacts structures */
 
@@ -238,12 +238,6 @@
 
 	exithook_establish(ksiginfo_exithook, NULL);
 	exechook_establish(ksiginfo_exithook, NULL);
-
-	sigaddset(&sigtrapmask, SIGSEGV);
-	sigaddset(&sigtrapmask, SIGBUS);
-	sigaddset(&sigtrapmask, SIGILL);
-	sigaddset(&sigtrapmask, SIGFPE);
-	sigaddset(&sigtrapmask, SIGTRAP);
 }
 
 /*
@@ -283,7 +277,7 @@
 		return;
 
 	oldps = p->p_sigacts;
-	sigactsinit(p, NULL, 0);
+	sigactsinit(p, p, 0);
 
 	if (--oldps->sa_refcnt == 0)
 		pool_put(&sigacts_pool, oldps);
@@ -1055,6 +1049,7 @@
 				sigdelset(&p->p_sigctx.ps_sigignore, signum);
 				sigdelset(&p->p_sigctx.ps_sigcatch, signum);
 				sigdelset(&p->p_sigctx.ps_sigmask, signum);
+				sigactsunshare(p);
 				SIGACTION(p, signum).sa_handler = SIG_DFL;
 			}
 		} else {