Re: catching floating point exception on OS X Intel
Re: catching floating point exception on OS X Intel
- Subject: Re: catching floating point exception on OS X Intel
- From: Kristoffer Eriksen <email@hidden>
- Date: Thu, 10 May 2007 16:44:30 -0700
Thanks for all your responses. Specific replies below:
Jonas (thank you!) posted some code involving assembly instructions
to directly change the control words for both the 387 FPU and SSE. I
think this is generally the right way to go, though I think I've
found a more concise solution. I'm not using long doubles, so for
simplicity I've disabled 387 instruction generation with the -
mfpmath=sse compiler switch, and therefore only have to deal with the
SSE XMCSR. There are library functions in the Accelerate framework to
deal with SSE intrinsics. The following code crashes before the print
statement, and gives a floating exception, which is the desired
behavior:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Accelerate/Accelerate.h>
#include <xmmintrin.h>
int main(int argc, char *argv[]){
double x;
_mm_setcsr( _MM_MASK_MASK &~
(_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO) );
x = -1.0/0.0;
printf("%f\n",x);
exit(0);
}
Similarly, if I try something like sqrt(-1.0), that crashes as well.
(good!)
When I run it in gdb I get:
Program received signal EXC_ARITHMETIC, Arithmetic exception.
0x00001f2f in main (argc=1, argv=0xbfffe708) at fpasm.c:14
14 x = -1.0/0.0;
It's not a SIGFPE, which is a little puzzling, and I don't know what
an EXC_ARITHMETIC, is but it's effective.
Thanks also to Axel for explaining why the example code from my
original post didn't crash and suggested something like:
/* This will set the FE_INVALID flag */
x = sqrt(-x);
retval = fetestexcept(FE_ALL_EXCEPT);
if (retval != 0)
raise(SIGFPE);
I'm doing a ton of floating point operations, so it's not practical
for me check the feflags after each operation.
I went back through the Mac OS X Numerics guide that Axel referred me
to, and was puzzled by this paragraph:
"By enabling (setting) bits in the Floating Point Status and Control
Register (FPSCR), the application can cause the PowerPC
microprocessor to generate hardware interupt signals when a floating-
point exception occurs. These bits are set through the use of the
fesetenvd [sic] call. The Mac OS X will deliver that interrupt to
your application by raising the UNIX signal SIGFPE"
So clearly there is at least supposed to be an interface above the
assembly instructions to convince the OS to generate a SIGFPE on a fp
exception. At least there was for PPC. In the PPC fenv.h the fenv_t
type is just an unsigned int, so it's easy to do the right bitwise OR
and pass fesetenv() the correct flags. However, on i386, fenv_t is a
struct (i.e. it can't be OR'd), and OR'ing the apparently appropriate
struct member has no effect. It seems like fenv.h is missing a
necessary macro or the like to manipulate the floating point
environment.
To make a very long story short, thanks to the help here I found a
solution to my problem, I think. However, some examples from Apple on
how to generate SIGFPE's on floating exception traps would be most
appreciated.
thanks,
Kris
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden