Re: SIGFPE trapping on HPPA
On Mon, May 03, 2010 at 10:44:21PM +0200, Helge Deller wrote:
> On 12/14/2009 11:08 PM, Thibaut Paumard wrote:
> > Le 14 déc. 09 à 16:06, Carlos O'Donell a écrit :
> > Attached is a rather small testcase.
> >
> > Compile with
> > gcc -lm -o fputest fputest.c
> >
> > Run with
> > ./fputest
> > or with any succession of 'i's and 'f's, e.g.
> > ./fputest iffifi
> >
> > The expected behaviour (checked on i386) is that for each f or i letter,
> > a line is output, for instance
> > $ ./fputest iffi
> > Triggering integer SIGFPE: 1/0=(SIGFPE trapped)0
> > Triggering floating SIGFPE: 1./0.=(SIGFPE trapped)0.000000
> > Triggering floating SIGFPE: 1./0.=(SIGFPE trapped)0.000000
> > Triggering integer SIGFPE: 1/0=(SIGFPE trapped)0
> > $ echo $?
> > 0
> >
> > All the SIGFPEs should be trapped and the program should exit gracefully
> > (check $?).
> >
> > Under HPPA, the integer SIGFPEs are trapped but the floating-point
> > SIGFPEs are not:
> > $ ./fputest iffi
> > Triggering integer SIGFPE: 1/0=(SIGFPE trapped)0
> > Triggering floating SIGFPE: 1./0.=Floating point exception
> > $ echo $?
> > 136
>
>
> The problem in this test case is, that a signal handler is called
> when SIGFPE happens. Then glibc uses a trampoline handler to call the
> signal handler, in which it touches the floating point registers again
> and finally gets another SIGFPE. In this case, the program just ends
> (since the original signal handler already trapped).
> Involved glibc function is _dl_runtime_resolve() at
> ports/sysdeps/hppa/dl-trampoline.S:73
>
> The solution is simple.
> Just clear the exception register in arch/parisc/math-emu/decode_exc.c
> in the linux kernel before sending the SIGFPE signal to user space.
>
> Patch attached.
>
> While at this, I think we need to clear the exception registers for
> the other cases like OVERFLOWEXCEPTION and INEXACTEXCEPTION at least
> as well (see arch/parisc/math-emu/decode_exc.c, line 286 ff).
>
> Helge
>
> Patch:
> -------------------------
> [PATCH] parisc: clear floating point exception flag on SIGFPE signal
>
> Clear the floating point exception flag before returning to
> user space. This is needed, else the libc trampoline handler
> may hit the same SIGFPE again while building up a trampoline
> to a signal handler.
>
> Fixes debian bug #559406.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
Thanks Helge! If you can poke me when this goes into Kyle's tree, I'll
get it added to Debian.
> diff --git a/arch/parisc/math-emu/decode_exc.c b/arch/parisc/math-emu/decode_exc.c
> index 3ca1c61..27a7492 100644
> --- a/arch/parisc/math-emu/decode_exc.c
> +++ b/arch/parisc/math-emu/decode_exc.c
> @@ -342,6 +342,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[])
> return SIGNALCODE(SIGFPE, FPE_FLTINV);
> case DIVISIONBYZEROEXCEPTION:
> update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
> + Clear_excp_register(exception_index);
> return SIGNALCODE(SIGFPE, FPE_FLTDIV);
> case INEXACTEXCEPTION:
> update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
>
>
--
dann frazier
Reply to: