ado@elsie.UUCP (Arthur David Olson) (09/23/86)
Index: /usr/src/lib/libjobs/sigset.c 4.1 Fix N.B.: This bug does *not* exist in 4.[23]BSD. If you're running one of those, and are not obsessively interested in potential pits that code you write may fall into when it's moved to other systems, bail out of this article right now. Description: Programs that use the -ljobs library and call "signal" ("vnews", for example) can dump core mysteriously. Repeat-By: Compile the program #include "signal.h" catcher(){} main() { int pid; switch (pid = fork()) { case 0: /* child */ for ( ; ; ) { signal(SIGTSTP, catcher); signal(SIGTSTP, SIG_HOLD); } default: /* parent */ sleep(1); while (kill(pid, SIGTSTP) == 0) ; } } with the "-ljobs" library and run it. Sit back. Have a jug of coffee. Or, if you're as impatient as I am, compile the above with a version of "sigset.c" where the function "signal" has been modified this way: > ... > cactions[signum] = action; > #ifndef OLDVERSION > if (action == SIG_HOLD) { > register int i; > > for (i = 0; i < 100000; ++i) > ; > } > #endif > if (action != SIG_HOLD && action != SIG_DFL && action != SIG_HOLD) > ... In either event, you should eventually get a core dump. Why? The "signal" function sets cactions[signum] = action; slightly before it does a subsequent action = sigsys(signum, action); call that tells the kernel to change the signal's handling. If a signal catcher has previously been set up, and a signal hits between the cactions[signum] = action; and the action = sigsys(signum, action); it gets processed by the function _sigcatch, which calls the function whose address is stored in cactions[signum]. So if you've just changed cactions[signum] to SIG_HOLD (for example), you end up at a bad place. Fix: There's surely a better fix, but this is no time for a treasure hunt. As usual, the fix is conditioned on OLDVERSION. ... _sigcatch(signum, code, xx, ps, pc) register signum; int code; { register int (*act)() = cactions[signum]; #ifndef OLDVERSION if (act != SIG_IGN && act != SIG_DFL && act != SIG_HOLD) #endif { asm("callg (ap),(r10)"); } #ifndef OLDVERSION /* watch out for asm bug! */ ; #endif if (setflg[signum]) { ... -- Bug/s is a Volkswagen/Warner Brothers trademark. ljobs may be what folks at Next call el presidente. -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!ado@seismo.ARPA DEC, VAX, Elsie & Ado are Digital, Borden & Ampex trademarks.