[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: SIGFPE trapping on HPPA



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>

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);


Reply to: