tim@merlin.bhpmrl.oz (Tim Monks) (05/07/90)
Here's an edited summary of the answers I received on how to force floating point exceptions to dump core. Basically for my purposes all I had to do was put a call to set_fpc_csr() with the appropriate argument before I called signal() and the targetted fp exception would make the program barf. There is of course a lot more fancy tricks you could do - what follows are the hints I received. Thanks to Thomas Russo, Ken Lalonde, Chris Wagner and Reuel Nash. --8<------------------------------------------------------------------------ From: russo@chaos.utexas.edu (Thomas Russo) set_fpc_csr(0xe00); This will enable core dumps when a FPE occurs. Wasn't that obvious :-? (If that's too cryptic do a man fpc, which will point you at /usr/include/sys/fpu.h.) Thomas Russo Center for Nonlinear Dynamics, University of Texas at Austin russo@chaos.utexas.edu or phib421@utchpc.bitnet --8<------------------------------------------------------------------------ From: Ken Lalonde <ken%cs.toronto.edu@munnari.oz> We ran into this problem too. Apparently SGI will be supplying a proper way to do what you want, along the lines of Sun's ieee_handler routine. I wrote a version of ieee_handler for our SGI systems which does most of the job. If all you need is a core dump, call this: #include <sys/fpu.h> #include <sys/sbd.h> abort_on_fpe() { union fpc_csr csr; csr.fc_word = get_fpc_csr(); csr.fc_struct.en_divide0 = 1; set_fpc_csr(csr.fc_word); } This will generate a SIGFPE on divide-by-zero. To enable dumps on the various other FPE's, set the appropriate bit from <sys/fpu.h> to 1 above, e.g. csr.fc_struct.en_invalid = 1; Note: if you set a handler for SIGFPE (instead of dumping core by default) and return from the signal handler, you'll get an infinite loop. You must advance the PC before returning -- mail me for details. Ken Lalonde, Department of Computer Science, University of Toronto --8<------------------------------------------------------------------------ From: jwag@moose.sgi.com (Chris Wagner) Try including and calling the following function: #include <asm.h> #include <regdef.h> #include <sys/fpu.h> .globl fpe_enable .ent fpe_enable fpe_enable: cfc1 t0, fpc_csr # grab fpu status register li t1, 0xF10 /*li t1, 0x3f000*/ or t0, t0, t1 # or in enable bits ctc1 t0, fpc_csr # replace fpu status j ra # return .end fpe_enable By default the C runtime startup does not enable floating point exceptions In our next release a complete fp exception package has been added Chris Wagner --8<------------------------------------------------------------------------ From: reuel%khaki%sgi.com@munnari.oz (Reuel Nash) > How do you force floating point exceptions to dump core in C on an SG ? I know Chris Wagner posted a machine language routine that can do this, but their are some routines already available. Here's your program modified to dump core... #include <stdio.h> #include <math.h> #include <signal.h> #include <fp_class.h> #include <sys/fpu.h> main(argc, argv) int argc; char **argv; { void Report_class(double); double x,zero; union fpc_csr fpc; /* enable the exceptions in the fpu's control register */ fpc.fc_word = get_fpc_csr(); fpc.fc_word |= FPCSR_ENABLES; set_fpc_csr(fpc.fc_word); /* set up a signal trap */ signal(SIGFPE, SIG_DFL); /* try to trap Infinity */ zero = 0.0; x = 1.0/zero; /* I wanted the program to dump core on the previous line, but it carried on, so we have a look at what we got. */ Report_class(x); /* Now try to trap NaN */ x = zero/zero; Report_class(x); } void Report_class(double x) { int type; type = fp_class_d(x); if (type == FP_SNAN) fprintf(stderr,"X = %lf is a signalling NaN\n",x); else if (type == FP_QNAN) fprintf(stderr,"X = %lf is a quiet NaN\n",x); else if (type == FP_POS_INF) fprintf(stderr,"X = %lf is positive infinity\n",x); else if (type == FP_NEG_INF) fprintf(stderr,"X = %lf is negative infinity\n",x); else fprintf(stderr,"X = %lf is something quite different !!!\n",x); } --8<------------------------------------------------------------------------ -- Dr. Tim Monks Image Processing & Data Analysis Group | (direct) (+61-3)566-7448 BHP Melbourne Research Laboratories | (switch) (+61-3)560-7066 245 Wellington Rd, Mulgrave, 3170, | (fax) (+61-3)561-6709 AUSTRALIA | (EMAIL) tim@merlin.bhpmrl.oz.au