longjmp() from nested signal handlers

Neal Weidenhofer nw at amdahl.uts.amdahl.com
Fri Apr 15 10:55:57 AEST 1988


In article <3669 at sdcc6.ucsd.EDU>, ix426 at sdcc6.ucsd.EDU (Tom Stockfisch) writes:
> In article <26739 at amdahl.uts.amdahl.com> nw at amdahl.uts.amdahl.com (Neal Weidenhofer) writes:
> >...  Using longjump from a signal handler ALWAYS results in
> >undefined behavior.
> 
> This *greatly* reduces the value of signals.
> I like to longjmp() back to a main processing loop on SIGINT.  If 
> all I do is set a flag and return,
> then I have to check that flag in a million other places to see if a user
> is trying to get my attention.

The point is that this has ALWAYS been true.  If you
(permanently) exit a subroutine in a random place, global
and/or static variables may be left in an inconsistent state so
that future use of routines that depend on those variables may
fail in mysterious ways.

The fact that it hasn't happend to you yet only means that it
works most of the time, not that it's correct.

> The situation is even worse if the behavior is undefined for longjmp()ing
> out of a signal handler for SIGFPE.  If you RETURN from a SIGFPE handler
> the behavior is *badly* undefined -- you could be in an infinite loop.

Yes, this can be a problem on some architectures.  You may have
to choose the lesser of two evils (which, as some friends of
mine are fond of pointing out, is still evil.)

> >My favorite example is to consider the case of the signal being
> >raised while the program is in the middle of malloc(3) (for UN*X
> >types--something equivalent if you're using VMS or some other
> >OS).  There is NO WAY that your program is going to continue to
> >run correctly after control has been forcibly removed from some
> >routine while its internal tables are in an inconsistent state.
> 
> You can avoid this by protecting all sections of code that shouldn't
> be abandoned half-way thru:

[Long example deleted.]

This example will probably work, provided that you identify ALL
instances of vulnerable code.  Note that it works by having the
signal handler just set a flag most of the time anyway.

Consider the problem faced by X3J11 though.  It's our job to
specify the language in such a way that conforming programs will
ALWAYS work on conforming implementations.  There is just no way
that a language standard could specify a scheme such as this and
when it needs to be used.

> >This is why dpANS limits signal handlers to setting a flag and
> >returning.  Most compilers and/or OS's are going to have to do
> >some work even to get this right.
> >...
> >				Neal Weidenhofer
> 
> I thought unix implementers these days use a similar scheme to
> protect sensitive portions of kernel and library function code.
> I suppose it would be asking to much to require all C implementations
> to do this.  I don't mind enclosing malloc() calls with protect()/unprotect(),
> and I usually have some uninterruptable code of my own next to
> these calls, but I wouldn't want to have to surround every getc(), printf(),
> etc.

The kernel is typically protected by the hardware delaying some
or all interrupts until the kernel returns control to the user.

For a library routine though, stop and think for a moment.  How
would you accomplish it?

> ||  Tom Stockfisch, UCSD Chemistry   tps at chem.ucsd.edu

The opinions expressed above are mine (but I'm willing to share.)

			Regards,
				Neal Weidenhofer
Where have all the              ...{hplabs|ihnp4|ames|decwrl}!amdahl!nw
     graveyards gone?           Amdahl Corporation
Gone to flowers every one.      1250 E. Arques Ave. (M/S 316)
				P. O. Box 3470
				Sunnyvale, CA 94088-3470
				(408)737-5007



More information about the Comp.lang.c mailing list