Dave Korn writes [why Yes, it was indeed a long time ago]: > > Is there something I need to do to "condition" the Cygwin environment to > > generate FP exceptions? I saw the code in winsup/something/or/other to map > > x86 FP exceptions to SIGFPE but it seems somehow the exceptions aren't being > > generated in the first place. > > Very possibly not. There's probably a bit in the FPUCW you need to set or > something. Ah, yes: see winsup/cygwin/crt0.c: [...good stuff elided for brevity...] > You can copy and paste that hunk into your own main() and change the > constants to anything you like.
I've tried many things but have been unable to get this to work. STC appended below but watch for linewraps. It uses ideas from Cygwin's crt0.c. Although I can trap SIGSEGV just fine, SIGFPE remains elusive even though the control word has zeroed FP exception mask bits. Also odd is that crt0.c claims to be setting the control word to 0x033F but it's actually 0x037F as the program starts. Any further suggestions would be greatly appreciated. Thanks much, ..mark #include <setjmp.h> #include <signal.h> #include <stdio.h> // // The following code is derived from Cygwin's crt0.c // #define FPU_RESERVED 0xF0C0 #define FPU_DEFAULT 0x033F unsigned short getstatusword() { volatile unsigned short sw = 0xFFFF; __asm__ volatile("fnstsw %0" : "=m" (sw) : ); return sw; } unsigned short getcontrolword() { volatile unsigned short cw = 0xFFFF; __asm__ volatile("fnstcw %0" : "=m" (cw) : ); return cw; } void setcontrolword(unsigned short x) { volatile unsigned short cw = getcontrolword(); cw &= FPU_RESERVED; cw |= x; __asm__ volatile("fldcw %0" :: "m" (cw)); } // // end of code derived from Cygwin's crt0.c // volatile int step = 0; // tells which step of demo we're currently in jmp_buf trapoline; // location+status for signal handlers to longjmp to void segv_handler(int x) { printf("step %d: SIGSEGV handled, continuing\n\n", step++); longjmp(trapoline, step); } void fpe_handler(int x) { printf("step %d: SIGFPE handled, continuing\n\n", step++); longjmp(trapoline, step); } int main() { unsigned short cw = 0x0300; // desired control word setting signed int i = 0x7FFFFFFF; // number i such that i*i overflows printf("--- initial FPU state at start of program execution ---\n"); printf("initial cw: %04X\n", getcontrolword()); printf("initial sw: %04X\n", getstatusword()); putchar('\n'); printf("--- now updating FPU control word ---\n"); printf("desired cw: %04X\n", cw); setcontrolword(cw); printf("updated cw: %04X\n", getcontrolword()); putchar('\n'); printf("--- setting up signal handlers for SIGSEGV and SIGFPE ---\n"); signal(SIGSEGV, segv_handler); signal(SIGFPE, fpe_handler); putchar('\n'); printf("--- now executing each step of demo in turn ---\n"); // each exception that's trapped causes step++, missed exception ->fallthru switch(setjmp(trapoline)) { case 0: // force a SIGSEGV printf("step %d should cause a memory fault\n", step); printf("step %d: %X\n", step, *(int *) 42); putchar('\n'); ++step; case 1: // force a floating overflow exception printf("step %d should cause a floating-point overflow\n", step); printf("step %d: %f\n", step, 1E200L * 1E200L); printf("step %d: current sw %04X\n", step, getstatusword()); putchar('\n'); ++step; case 2: // force an integer overflow exception printf("step %d should cause an integer overflow\n", step); printf("step %d: %d\n", step, i * i); printf("step %d: current sw %04X\n", step, getstatusword()); putchar('\n'); ++step; case 3: // all done printf("step %d: all done\n", step); printf("step %d: current sw %04X\n", step, getstatusword()); putchar('\n'); break; } printf("--- done with demo steps, now preparing to exit ---\n"); printf("current cw: %04X\n", getcontrolword()); return 0; } -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple