FP signals fubar under Ultrix 4.1

Hascall John Paul john at iastate.edu
Fri Apr 12 02:36:18 AEST 1991


The following program attempts various "undefined" mathematical operations
and attempts to catch the resulting signal.  I compile with:

    cc -O0 bug.c -o bug -lm

(and answer the prompt with, say, 512);
and I get the following results:

    Ultrix 3.1D (Rev. 54)      SIGFPE (8)
    Ultrix 4.1  (Rev. 40)      SIGFPE (8)
    Ultrix 4.1  (Rev. 55)      SIGILL (4)

What's going on here?  I am stumped.  This doesn't seem at all right.

--------------- cut here, file bug.c ------------------------------------------
#include <stdio.h>
#include <signal.h>
#include <mips/fpu.h>
#include <mips/cpu.h>

int main(argc, argv)
	int	argc;
	char **	argv;
{
	int	csr_val;
	void	fpx_handler();
	float	x,y,z;		/* or double, if e+-30 replaced with e+-300 */
	int	i,j,k;

/*       zero or more of (2048  1024  512   256    128)  + (one of 0,1,2,3) */
	(void)printf("csr <INV, DIV0, OVER, UNDER, INEX, <6-0 = near,0,+,-> :");
	(void)scanf("%d", &csr_val);
	do {} while (getchar() != '\n');
	(void)signal(SIGILL,  fpx_handler);		/* sig 4 ?   */
	(void)signal(SIGTRAP,  fpx_handler);		/* sig 5 ??? */
	(void)signal(SIGFPE,  fpx_handler);		/* sig 8     */
	(void)set_fpc_csr(csr_val);

	printf("Try a floating overflow        (1.0e+30 x 1.0e+30)\n");
	x = 1.0e30; y = x * x;
	printf("Result is %f\n\n", y);

	printf("Try a floating underflow       (1.0e-30 x 1.0e-30)\n");
	x = 1.0e-30; y = x * x;
	printf("Result is %f\n\n", y);

	printf("Try a floating divide by zero  (1.0 / 0.0)\n");
	x = 1.0; y = 0.0; z = x / y;
	printf("Result is %f\n\n", z);

	printf("Try a negative square root     (sqrt(-1.0))\n");
	x = -1.0; y = sqrt(x);
	printf("Result is %f\n\n", y);

	printf("Try an integer overflow        (100000 * 100000)\n");
	i = 100000; j = i * i;
	printf("Result is %f\n\n", j);

	printf("Try an integer divide by zero  (1 / 0)\n");
	i = 1; j = 0; k = i / j;
	printf("Result is %f\n\n", k);

	return(0);
}


void fpx_handler(sig, code, scp)
	int			sig;
	int			code;
	struct sigcontext *	scp;
{

        union fpc_csr	csr;

	csr.fc_word = scp->sc_fpc_csr;

	fprintf(stderr,"caught signal %d, code %d\n", sig, code);

	if (csr.fc_struct.ex_invalid) {
	  fprintf(stderr,"floating point error: invalid operation\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}
        if (csr.fc_struct.ex_divide0) {
	  fprintf(stderr,"floating point error: division by zero\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	} 
        if (csr.fc_struct.ex_underflow) {
	  fprintf(stderr,"floating point error: underflow\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}
        if (csr.fc_struct.ex_overflow) {
	  fprintf(stderr,"floating point error: overflow\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}
        if (csr.fc_struct.ex_inexact) {
	  fprintf(stderr,"floating point error: inexact operation\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}
        if (csr.fc_struct.ex_unimplemented) {
	  fprintf(stderr,"floating point error: unimplemented operation\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}

	if (code == BRK_DIVZERO) {
	  fprintf(stderr,"integer error: division by zero\n");
	  fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	  exit(1);
	}

	fprintf(stderr,"floating point error: unknown exception code\n");
	fprintf(stderr,"at or near location %x\n",scp->sc_pc);
	fprintf(stderr,"fp status word %lx\n",csr);
	exit(1);
}



More information about the Comp.unix.ultrix mailing list