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>