From owner-freebsd-hackers Fri Oct 10 23:29:18 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id XAA03277 for hackers-outgoing; Fri, 10 Oct 1997 23:29:18 -0700 (PDT) (envelope-from owner-freebsd-hackers) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id XAA03269 for ; Fri, 10 Oct 1997 23:29:14 -0700 (PDT) (envelope-from andrew@zeta.org.au) Received: from gurney.reilly.home (d15.syd2.zeta.org.au [203.26.11.15]) by godzilla.zeta.org.au (8.8.5/8.6.9) with ESMTP id QAA13202; Sat, 11 Oct 1997 16:24:34 +1000 Received: (from andrew@localhost) by gurney.reilly.home (8.8.7/8.8.5) id QAA05971; Sat, 11 Oct 1997 16:24:21 +1000 (EST) From: Andrew Reilly Message-Id: <199710110624.QAA05971@gurney.reilly.home> Date: Sat, 11 Oct 1997 16:24:20 +1000 (EST) Subject: Re: Floating point exceptions To: tlambert@primenet.com cc: gjohnson@nola.srrc.usda.gov, freebsd-hackers@FreeBSD.ORG In-Reply-To: <199710102149.OAA15093@usr08.primenet.com> MIME-Version: 1.0 Content-Type: TEXT/plain; CHARSET=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk 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 : addl $0x4,%ecx 0x4a79 : movl (%edi),%esi 0x4a7b : movl %esi,0xffffffe8(%ebp) 0x4a7e : movl 0xffffffe8(%ebp),%eax 0x4a81 : fsts (%eax) 0x4a83 : addl $0x4,(%edi) 0x4a86 : addl $0x4,%edi 0x4a89 : movl 0xffffffe4(%ebp),%eax 0x4a8c : fcoms (%eax) 0x4a8e : fnstsw 0x4a90 : andb $0x45,%ah 0x4a93 : jne 0x4a9c 0x4a95 : movl 0xffffffe4(%ebp),%esi 0x4a98 : fstps (%esi) 0x4a9a : jmp 0x4a9e 0x4a9c : 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