FPE's

Robert G. Brown (rgb@phy.duke.edu)
Wed, 18 Apr 2001 19:23:52 -0400 (EDT)


Dear Kernel Experts,

A question recently arose on the beowulf list about determining the
largest possible float or double (or the smallest) that would not
overflow (or underflow) on a general system, which on the beowulf list
is not unreasonably a general linux/gnu system.

I suggested that one should be able to trap the FPE that is supposed to
occur on an overflow and do a binary search to find the boundary value
where it just doesn't in a reasonable amount of time. The standard glib
documentation suggests that I should be able to do this as well.

The following code fragment looks like it "should" force an exception,
and on a BSD or GNU system (according to the glib manual) there should
be an extra argument one can define for the handler that indicates the
type of the exception as well (with a cast required to define the signal
handler without complaint).

However, it doesn't work. Rather, the handler works fine -- if I send
the process kill -FPE PID it dies very nicely after printing out the
message from the handler. However, nothing I have been able to put into
the force_exception program actually forces an exception -- I just print
out d = inf or nan depending on whether I include e.g. the sqrt of -1.

This leads to several questions, which I wouldn't ask here if I could
find answers elsewhere and which do perhaps depend on the kernel.

a) Is there any FPE or otherwise trappable event associated with
overflow, underflow or division by zero? There is a whole list of
entities defined in man sigaction which appear to be particular
exceptions that would be placed into si_code if I used the sa_sigaction
method of installing the signal, but of course this cannot work if
overflow etc. don't cause an FPE to be raised. I did try.

b) If not, is there any related methodology that could be used to
dynamically determine the overflow boundary? I tried setting double
infinity=1.0/0.0; (which is crazy but works) and then testing a loop
that doubles d each pass and compares it to infinity (saving the
previous result) but d goes itself to inf without ever satisfying the
equality or even an inequality -- apparently there are multiple values
of "infinity" or the conditional statement doesn't know how to resolve
"d == infinity" when both print as inf and are generated from overflow
values.

c) Am I being stupid. I'm (as always:-) open minded about this, and
eager to learn...

rgb

-- 
Robert G. Brown	                       http://www.phy.duke.edu/~rgb/
Duke University Dept. of Physics, Box 90305
Durham, N.C. 27708-0305
Phone: 1-919-660-2567  Fax: 919-660-2525     email:rgb@phy.duke.edu

/* * Code fragment which should force a floating point exception and * handle it in a private handler. */

void fpe(int signum,int sigtype){

printf("FPE found of type %d\n",sigtype); exit(0);

}

void force_exception() {

struct sigaction newaction,oldaction; double d;

/* Install a new handler. */ newaction.sa_handler = fpe; sigemptyset(&newaction.sa_mask); newaction.sa_flags = 0;

/* Get the old handler... */ sigaction(SIGFPE,NULL,&oldaction); if(oldaction.sa_handler != SIG_IGN) sigaction(SIGFPE,&newaction,NULL);

/* Force an FPE */ d = sqrt(-1.0); d = sin(sqrt(-1.0)); d = d/0.0; printf("SHOULD have died before it gets here... d = %20.15e\n",d); while(1){}

}

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/