This is the mail archive of the libstdc++@sources.redhat.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gen-num-limits.cc & signal handling


I believe the current way gen-num-limits.cc uses signals to find out
whether division by zero and overflow are trapped is inherenty
unportable.  The behaviour of signal() is not entirely specified by
the relevant standards, and allows for SIGFPE to be blocked during the
execution of the signal handler, which happens for a BSD-like signal()
implementation.  The behaviour of longjmp() isn't entirely specified
either.  In particular, it doesn't have to restore the signal mask.
So it is very well possible that after the first trap, SIGFPE ends up
being blocked.  AFAICT synchronously generating another SIGFPE while
it is being blocked invokes undefined behaviour.

On most systems this isn't a problem:

* On BSD systems longjmp() restores the signal mask.

* On System V systems SIGFPE won't be blocked during the execution of
  the signal handler.

* On Linux systems SIGFPE cannot be blocked.

However on the Hurd, generating a SIGFPE while it is being blocked
hangs the program.  And the #ifdef __CYGWIN__ suggests that cygwin
suffers from a similar problem.  The BeOS problems might be related
too.

Instead of special-casing these systems I'd like to propose to use
sigsetjmp/siglongjmp instead of setjmp/longjmp.  I've verified that
that works for the Hurd.  Since those functions might be absent on
non-POSIX systems, there should probably be an autoconf check for
those functions, and setjmp/longjmp could be used as a fall-back.

If people agree that is the way to go, I'm willing to provide the
necessary patch.

Mark

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]