Date: Fri, 12 Dec 1997 04:36:09 +1100 From: Bruce Evans <bde@zeta.org.au> To: bde@zeta.org.au, reilly@zeta.org.au Cc: freebsd-current@FreeBSD.ORG, rcarter@consys.com Subject: Re: xlock: caught signal 8 while running galaxy mode. Message-ID: <199712111736.EAA17753@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
In old mail, Andrew wrote: >>>I recently tried to port some speech recognition code that runs fine on >>>two different DSPs, a Dec Alpha, a Sparc and a SCO Pentium box to my >>>FreeBSD machine. The HMM is expected to underflow all the time. In >>>the brief time I had available, I could not figure out how to stop the >>>FreeBSD maths from trapping at that point, and I couldn't write a trap >>>handler that would ignore the error and continue, so I gave up. So I wrote: >> Do you mean overflow? FreeBSD masks underflow, denormal and precision >> exceptions by default. > >I'm pretty sure it wasn't an overflow. I am not all that familiar with >the x87 instruction set, so I don't for sure what was happening. The >breakage was in a comparison (>) between a float in a register variable >with a float loaded from memory. This resulted in a SIGFPE >sometimes. That shouldn't trap unless one of the operands is a NaN. Traps occur on the FP instruction (usually immediately) following the one that set the exception bits, so a comparison may trigger a SIGFPE for a previous exception. >---time lapse--- > >In the interests of exactitude, and since I seem to have the >attention of people who really know about this sort of >thing, here is a bit of detail about this specific "bug". > >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 `p' can't handle variables in x87 registers. It prints the above value after `register float z; z = 1' here. I think it just doesn't know where the variables really are. Use `info float' to get more information. >(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) Not much to go wrong there. `info float' would show the (FPU) pc where the exception occurred (the next FP instruction causes the trap but it doesn't get executed, so the pc still points to the previous FP instruction. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199712111736.EAA17753>