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

Re: SIGFPE trapping on HPPA



On 05/03/2010 11:42 PM, dann frazier wrote:
> 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.

Hi Dan,

the patch was now applied to Kyle's tree and will be in Linus upstream Kernel 2.6.35:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=550f0d922286556c7ea43974bb7921effb5a5278

Best regards,
Helge






> 
>> 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: