| Summary: | float-to-double core dump on 3.4R | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Randall Hopper <aa8vb> |
| Component: | i386 | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | CC: | aa8vb |
| Priority: | Normal | ||
| Version: | 3.4-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
> #include <float.h>
>
> main()
> {
> float f = FLT_MAX;
> double d;
> f = f * 2;
> d = f;
> }
>
> Delete the "d=f" line and it doesn't core. Put it in and it does
> (floating-point exception).
>
> From this it appears there may be a bug in the float-to-double
> promotion when f is Inf (or, at least I'd expect that f is Inf).
>
> Note that the core dump does not occur when the Inf is generated,
> but only when it is promoted to a double.
>
> I first noticed this by trying to printf the value of f after f=f*2
> and got the same core-dump behavior (due to float-to-double arg
> promotion).
See 'man setfpmask'. The default behavior in 3.4 was to cause a SIGFPE if
you do anything that causes an 'overflow' to be generated from the FPU. I
admit this is weird that it's doing it here, but I don't claim to understand
what happens in a case like this. :)
(4.0 and higher changed their defaults to ignore certain exceptions)
Kevin
On Mon, 10 Apr 2000 aa8vb@ipass.net wrote: > >Description: > > #include <float.h> > > main() > { > float f = FLT_MAX; > double d; > f = f * 2; > d = f; > } > > Delete the "d=f" line and it doesn't core. Put it in and it does > (floating-point exception). > > From this it appears there may be a bug in the float-to-double > promotion when f is Inf (or, at least I'd expect that f is Inf). No. "f * 2" gives undefined behaviour since it overflows. For FreeBSD-3.4 on i386's, the actual behaviour is to leave the operands on the FP stack and cause a SIGFPE on the next FP instruction after the one that overflowed. > Note that the core dump does not occur when the Inf is generated, > but only when it is promoted to a double. Inf is not generated. The operands are left on the FP stack for the SIGFPE handler to fix up. This behaviour is easy to see using gdb ("display/i $pc", "stepi" and "info float"). Bruce State Changed From-To: open->closed Asked and answered. Bruce Evans:
|> float f = FLT_MAX;
|> double d;
|> f = f * 2;
|> d = f;
|>
|> Delete the "d=f" line and it doesn't core. Put it in and it does
|> (floating-point exception).
|>
|> From this it appears there may be a bug in the float-to-double
|> promotion when f is Inf (or, at least I'd expect that f is Inf).
|
|No. "f * 2" gives undefined behaviour since it overflows. For FreeBSD-3.4
|on i386's, the actual behaviour is to leave the operands on the FP stack
|and cause a SIGFPE on the next FP instruction after the one that overflowed.
|
|> Note that the core dump does not occur when the Inf is generated,
|> but only when it is promoted to a double.
|
|Inf is not generated. The operands are left on the FP stack for the SIGFPE
|handler to fix up. This behaviour is easy to see using gdb ("display/i $pc",
|"stepi" and "info float").
Ok, thanks for your clarification. That seems like very odd behavior to
wait until the "next" floating point instruction before signaling the
exception for the prior. That could potentially be pages away in the
instruction stream.
Intuitively it seems like a bug (like waiting for a while before tripping a
divide by zero fault). But I'll trust that you know more about the issues
involved here than I do.
Thanks for the reply,
Randall
Randall Hopper: |Ok, thanks for your clarification. That seems like very odd behavior to |wait until the "next" floating point instruction before signaling the |exception for the prior. That could potentially be pages away in the |instruction stream. Thomas David Rivers: |> Intuitively it seems like a bug (like waiting for a while before |> tripping a divide by zero fault). But I'll trust that you know more |> about the issues involved here than I do. | | It's how the fpu works in the x86 chip; an artifact of when the | FPU was a different chip. | | Some x86 compilers can be told to emit an extra instruction (kinda | like a dummy floating pt. instruction) so that any except can be | caught synchronously; but when you do this, it *really* slows down | floating point operations. Ok, thank you. That makes sense. I understand the behavior now. Randall. |
#include <float.h> main() { float f = FLT_MAX; double d; f = f * 2; d = f; } Delete the "d=f" line and it doesn't core. Put it in and it does (floating-point exception). From this it appears there may be a bug in the float-to-double promotion when f is Inf (or, at least I'd expect that f is Inf). Note that the core dump does not occur when the Inf is generated, but only when it is promoted to a double. I first noticed this by trying to printf the value of f after f=f*2 and got the same core-dump behavior (due to float-to-double arg promotion). Fix: Unknown. How-To-Repeat: Paste the above snippet into a .c file, compile with cc -o tst tst.c, and execute.