Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Oct 1997 16:24:20 +1000 (EST)
From:      Andrew Reilly <reilly@zeta.org.au>
To:        tlambert@primenet.com
Cc:        gjohnson@nola.srrc.usda.gov, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Floating point exceptions
Message-ID:  <199710110624.QAA05971@gurney.reilly.home>
In-Reply-To: <199710102149.OAA15093@usr08.primenet.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 10 Oct, Terry Lambert wrote:
>> I've got a calculation intensive (simulation) application that I run that 
>> aborts with a Floating Point Exception error under FreeBSD -current. I can run
>> this application just fine under Linux, but of course I want to run it under 
>> FreeBSD (so I can replace Linux). My understanding is that FreeBSD traps 
>> FPE's. Is there a way for me to change the FreeBSD source code to mask FPE's 
>> rather than trap them? Better yet, can I do that for a specific application at
>> compile time? Your assistance is greatly appreciated.

I posted a message, asking a similar question, to freebsd-current a
week or so ago, but saw no response.  Admittedly it was buried under an
old thread (xlock: caught signal 8...).  I'll try again here, since
this is the correct place, and thanks to this list, I have now found a
solution (work around?) that works.

> Fix:		Correct the code to not generate exceptions

This is just plain rude.  There are a bunch of exceptions that are
enabled by default that are simply irrelevant for any signal processing
code that I can think of, and were certainly what was causing the
breakage of a program that was otherwise performing exactly as I
intended.  In particular, trapping on underflow is, to my mind,
counter-intuitive.  No, the code is _correct_ in my case.

> Bad fix:	fpsetmask( 0);

This works for me.  Having found this function, and looked it up in the
manual, I think that the arg of 0 is perhaps a bit harsh.  In my case I
think ~(FP_X_UFL+FP_IMP+FP_X_DNML) would probably do the job.  Is there
a pointer to fpsetmask in any other manual page?  My search that
started in math.3m did not find it.

> Worst fix:	signal( SIGFPE, SIG_IGN);

Very bad fix, because when I tried it, it just didn't work.  I assume
that the trap handler does not correctly restore the floating point
state.  The program ran to completion, but IEEE error values
of some sort propagated from the exception point and ruined the results.

For anyone who cares to help with an attempt at Terry's "Fix:", the
code in my case is part of the HMM code from a speech recogniser.

With the default FreeBSD maths environment (from a build
world on current 2.2 sources on 3rd September), and the C
program compiled in GCC with -g -Wall switches (only).

No compiler warnings.

(gdb) run -S call.lst
Starting program: xxx_ux -S call.lst
Call Setup.
RunUtterance(model:amt4.bin, speech:amt1.lin)

Program received signal SIGFPE, Arithmetic exception.
0x4a8c in CalcU () at state.c:305
305                         if (s > *pMax) *pMax = s;

[ register float s; register float *pMax; ]

(gdb) p s
$1 = 5.46506401e-44
(gdb) p *pMax
$2 = -32.9900398
(gdb) disassemble
Dump of assembler code for function CalcU:
[elided]
0x4a76 <CalcU+518>:     addl   $0x4,%ecx
0x4a79 <CalcU+521>:     movl   (%edi),%esi
0x4a7b <CalcU+523>:     movl   %esi,0xffffffe8(%ebp)
0x4a7e <CalcU+526>:     movl   0xffffffe8(%ebp),%eax
0x4a81 <CalcU+529>:     fsts   (%eax)
0x4a83 <CalcU+531>:     addl   $0x4,(%edi)
0x4a86 <CalcU+534>:     addl   $0x4,%edi
0x4a89 <CalcU+537>:     movl   0xffffffe4(%ebp),%eax
0x4a8c <CalcU+540>:     fcoms  (%eax)
0x4a8e <CalcU+542>:     fnstsw 
0x4a90 <CalcU+544>:     andb   $0x45,%ah
0x4a93 <CalcU+547>:     jne    0x4a9c <CalcU+556>
0x4a95 <CalcU+549>:     movl   0xffffffe4(%ebp),%esi
0x4a98 <CalcU+552>:     fstps  (%esi)
0x4a9a <CalcU+554>:     jmp    0x4a9e <CalcU+558>
0x4a9c <CalcU+556>:     fstp   %st(0)

So: I imagine fcoms is a short floating point compare.  Any
reason that should generate an exception in this case?  On a
system without denorms and with real 32-bit floats, the
comparison would be 0.0>-30.99..., which is hardly going to
be a problem.

(in the earlier post, bde said:)
> Continuing from SIGFPE handlers is much harder than masking FP exceptions,
> at least on i386's.

Yes.  I tried doing a signal(SIGFPE,SIG_IGN) at the top of
main, but that just made it produce totally incorrect results.

-- 
Andrew

"The steady state of disks is full."
				-- Ken Thompson




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