Summary on how to trap floating point exceptions

Tim Monks tim at merlin.bhpmrl.oz
Mon May 7 09:35:31 AEST 1990



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 at 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 at chaos.utexas.edu or phib421 at utchpc.bitnet
--8<------------------------------------------------------------------------
From: Ken Lalonde <ken%cs.toronto.edu at 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 at 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 at 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 at merlin.bhpmrl.oz.au



More information about the Comp.sys.sgi mailing list