I'm currently porting an interactive software package to Linux that
requires the ability to handle math exceptions as follows:
- When traps are enabled, the program catches SIGFPE and or
SIGTRAP, decodes the type of exception that occurred, and then
allows execution to continue. The result of the computation is
undefined, although it would be nice if fixups were performed
to yield the standard IEEE special values (Nan, Inf) for the result.
- When traps are disabled, no exceptions are reported, and the
hardware/kernel arrange for the special IEEE values to
result as necessary. Afterwards, it should be possible to
query the hardware to find out which exceptions occurred (usually
from a status word inside the FPU) and reset the status.
This is an area in which Unix systems differ. Typically one enables traps
by calling a library routine (ieee_handler() on a Sun for example) and
registering a signal handler to catch SIGFPE (and sometimes SIGTRAP) and
do the required decoding. Sometimes the signal handler must also advance
the program counter and/or perform fixups of the resulting value to the
IEEE special values.
As an experiment, I used sigaction() to set up a SIGFPE signal handler.
I'm using kernel version 1.1.59 from slackware version 2.1.
Linux calls my handler when exceptions occur, but I see the following
- Integer exceptions don't automatically advance the PC past the
offending computation, so the handler gets called repeatedly in
an infinite loop.
- Results don't get the special IEEE values (This is true even
if no signal handler is set).
- I'm not sure what extra information is passed to the handler
by Linux, and am therefore not sure how to decode the reason for
I'm having trouble finding any documentation on the proper way to do
this sort of thing under Linux. In general I have the following questions,
which boil down to "Where can I find out how exceptions work under Linux?":
 What is the proper method to use to establish an exception
handler for math exceptions. Is it as simple as calling sigaction(),
or is there a library function that should be used?
 Once a math exception is detected, what extra information is passed
to the signal handler and how does one decode it to determine what
type of exception occurred. (ie divide by 0, underflow...etc)?
 If exception handling is off, is there a way to query the system
to determine the accumulated math errors and then clear them?
** Does this have something to do with the __fpu_control word
and the __setfpucw() functions in libc.a?
 How does one arrange for the results to be fixed up to the
IEEE special values such as Nan and Inf?
 Which exceptions require the signal handler to increment
the program counter, and what is the proper method to do it?
(For example, under Solaris, integer exceptions must be manually
bumped. This is done by setting fields in the context structure
that is passed to the handler).
Any help would be greatly appreciated.