Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Dec 1999 12:49:41 +0100
From:      Martin Cracauer <cracauer@cons.org>
To:        Sheldon Hearn <sheldonh@uunet.co.za>
Cc:        Ben Smithurst <ben@scientia.demon.co.uk>, Bosko Milekic <bmilekic@dsuper.net>, hackers@FreeBSD.ORG
Subject:   Re: SIGFPE on arithmetic overflow
Message-ID:  <19991224124941.A88203@cons.org>
In-Reply-To: <76436.946032683@axl.noc.iafrica.com>; from Sheldon Hearn on Fri, Dec 24, 1999 at 12:51:23PM %2B0200
References:  <19991224103735.A649@strontium.scientia.demon.co.uk> <76436.946032683@axl.noc.iafrica.com>

next in thread | previous in thread | raw e-mail | index | archive | help
In <76436.946032683@axl.noc.iafrica.com>, Sheldon Hearn wrote: 
> 
> 
> On Fri, 24 Dec 1999 10:37:35 GMT, Ben Smithurst wrote:
> 
> > >   Could somebody try this piece of code on a -STABLE machine, just out of
> > >   curiosity...?
> > 
> > I did, it gets SIGFPE too.
> 
> I think this boils down to my lack of understanding of IEEE floating
> point arithmetic standards.
> 
> The following code behaves the same on every box I can find to test it
> on.  Although I'm surprised that the exception is INV instead of OFL, it
> seems to be standard behaviour.

The cast gets compiled into a fistpl instruction (surrounded by
control word manipulation), which is documented to set "invalid
operation", not "overflow".

Not knowing Intels reason (they may be more twisted), I think this
makes sense:
- The "overflow" execption is thrown for real floaing point overflow,
  which - if it was not masked - had a meaningful result - the FPU
  infinity value.
- The "invalid" execption is thrown in this case of "too big for
  target integer type" because the result is undefined and in fact not
  usable in any way. If the FPU would ensure that the result would be
  the integer that approaches the former floating point value best
  (INT_MAX), it could make sense to thow it into the same basket as
  the floating operation (although not really, since that would
  require an integer infinity value). Since it doesn't even attempt
  to, but sets the result to complete nonsense, it choses to signal a
  different kind of error.

This also shows why running such code with execptions enabled is
usually good, not bad. Turn off exceptions only when the code is know
to be aware of the effects. 

If you port and fix such a packet, insett a test for > INT_MAX before
the cast, don't kill the exceptions. That latter would make it
impossible to find the next occurance of this coding error.



More info on digging follows, partly repeating what you found out
already:

#include <stdio.h>
#include <signal.h>

volatile sig_atomic_t code;

void handler_siginfo(int sig, siginfo_t *info, void *nix)
{
  code = info->si_code;
}

int
main(void)
{
  double  x;
  int     i;
  struct sigaction act;

  act.sa_sigaction = handler_siginfo;
  act.sa_flags |= SA_SIGINFO;
  sigemptyset(&act.sa_mask);
  sigaction(SIGFPE, &act, NULL);

  code = -1;

  x = 1e19;
  i = (int)x;
  printf("%d\n", i);

  if (code != -1)
    fprintf(stderr, "Code: %d\n", code);

  return 0;
}

Code 7 = "Subscript out of bounds". While this is not the direct error
value from the CPU (but the portable summary), you can tell that it's
not an overflow.

If you run th code with exceptions disabled, you can get the
statusword afterward the cast, you will find that bit one "Invalid
operation" has been set by the FPU. (You can't get the real status
word in a signal handler because you can't access the normal program
flow's state from inside the signal handler for now).

If you look at the code for the cast, it looks like this:

       fldl -8(%ebp)
       fnstcw -38(%ebp)
       movw -38(%ebp),%ax
       orw $3072,%ax
       movw %ax,-40(%ebp)
       fldcw -40(%ebp)
       fistpl -12(%ebp) ; causes the exception
       fldcw -38(%ebp) ; thowns the delayed exception

Intel documentation implies that fistpl throws "invalid operation",
although the manuals are not clear enough and omit this kind of error
from some tables of exceptions that looked complete.

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org> http://www.cons.org/cracauer/
BSD User Group Hamburg, Germany     http://www.bsdhh.org/


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991224124941.A88203>