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