[net.unix-wizards] floating point overflows

scott@othervax.UUCP (Scott Pace) (08/29/85)

If I compile and run the following program, it will continue until
a floating point overflow occurs and will then go and proccess
the interrupt routine. However, it seems that the return from the
interrupt routine is returning to the start of the instruction
which caused the overflow in the first place. Therefore, the program
just goes into an infinite loop printing the overflow message.
What exactly is happening here or what am I doing wrong ? Any help
greatly appreciated.

By the way, this is on a VAX11/780 running 4.1BSD


#include <signal.h>

int fpe_flag = 0;

main()
{
    double a = 1.0,b = 2.0;
    int fltover();

    sigset(SIGFPE,fltover);
    for (;;) {
	a *= b;		/* overflow here */
	if (fpe_flag)
	    exit(1);
    }
}

fltover()
{
    printf("Floating point overflow\n");
    fpe_flag = 1;
}


Cheers,
	Scott Pace, ...!philabs!micomvax!othervax!scott

lcc.rich-wiz@locus.ucla.edu (Richard Mathews) (09/05/85)

> If I compile and run the following program, it will continue until
> a floating point overflow occurs and will then go and proccess
> the interrupt routine. However, it seems that the return from the
> interrupt routine is returning to the start of the instruction
> which caused the overflow in the first place. Therefore, the program
> just goes into an infinite loop printing the overflow message.
> What exactly is happening here or what am I doing wrong ? Any help
> greatly appreciated.

> By the way, this is on a VAX11/780 running 4.1BSD

> Cheers,
>	  Scott Pace, ...!philabs!micomvax!othervax!scott

You are not doing anything wrong, DEC is!  I am sure they would claim this
to be a feature (it is documented in the architecture handbook), but it sure
looks like a bug to me.  Anyway, the problem is that floating overflow,
floating underflow, and floating divide by zero do not increment the PC (in
the jargon of DEC, they are "faults" not "traps").  UNIX could correct for
this by incrementing it for you, but no version I have seen does this.	The
only solution is for your signal handler to increment its return address
by the size of the instruction which caused the fault.	YUCCH.	I have a
routine which does just this (for several versions of UNIX).  It is simple
to write, but I would be happy to send it to anyone who is interested.

Richard M. Mathews
Locus Computing Corporation		       lcc.richard@LOCUS.UCLA.EDU
					       lcc.richard@UCLA-CS
				{ucivax,trwrb}!lcc!richard
 {ihnp4,randvax,sdcrdcf,ucbvax,trwspp}!ucla-cs!lcc!richard

preece@ccvaxa.UUCP (09/10/85)

> > If I compile and run the following program, it will continue until
> > a floating point overflow occurs and will then go and proccess
> > the interrupt routine. However, it seems that the return from the
> > interrupt routine is returning to the start of the instruction
> > which caused the overflow in the first place. Therefore, the program
> > just goes into an infinite loop printing the overflow message.
> >	  Scott Pace, ...!philabs!micomvax!othervax!scott

> You are not doing anything wrong, DEC is!  I am sure they would claim
> this to be a feature (it is documented in the architecture handbook),
> but it sure looks like a bug to me.
>	{ucivax,trwrb}!lcc!richard
----------
The idea is probably that your interrupt routine should fix the
condition that caused the error before returning.  There are
situations where this is a perfectly reasonable way to do things,
allowing rational responses to predictable exceptions.  

-- 
scott preece
gould/csd - urbana
ihnp4!uiucdcs!ccvaxa!preece

ark@alice.UucP (Andrew Koenig) (09/13/85)

>> If I compile and run the following program, it will continue until
>> a floating point overflow occurs and will then go and proccess
>> the interrupt routine. However, it seems that the return from the
>> interrupt routine is returning to the start of the instruction
>> which caused the overflow in the first place. Therefore, the program
>> just goes into an infinite loop printing the overflow message.
>>	  Scott Pace, ...!philabs!micomvax!othervax!scott

> You are not doing anything wrong, DEC is!  I am sure they would claim
> this to be a feature (it is documented in the architecture handbook),
> but it sure looks like a bug to me.
>	{ucivax,trwrb}!lcc!richard

The architectural question is: when a floating point overflow
occurs, should the return address from the interrupt routine
be the failing instruction or the one that follows it.
DEC apparently feels it should be the failing instruction.
One good justification for that is that it is only moderately
difficult to write a routine that will find the instruction
following the failing one and modify the PC accordingly (knowing
that the failing instruction had to be a floating-point operation,
I wrote such a routine in about an hour).  If you only have a
pointer to the next instruction, it is impossible to determine
the address of the one that failed with certainty.