[Gc] Re: Problem: FPE mask reset by GC. Versions 7.X on x86_64 Linux.

Jean-Claude Beaudoin jean.claude.beaudoin at gmail.com
Wed Jan 19 18:52:14 PST 2011


Hello Ivan,

I could trace the problem to the call to getcontext() that can
be found in GC_with_callee_saves_pushed(). getcontext() is buggy
on linux x86_64 as it clears the FPU exception mask.

I filed a bug report with the Glibc people but in the meantime
I suggest that the getcontext() call be wrapped more or less in
the way shown in the small patch here attached.

Cheers.

Ivan Maidanski wrote:
> Hi Jean-Claude,
> 
> AFAIK, some linux versions restores FPU CW value (to some default one) on [sig]longjmp(). The latter is called during GC_init to find static data roots and/or main stack bottom. Probably, we should outline this behavior in the docs. Probably, some fix is possible.
> 
> You might just reorder feenableexcept and GC_INIT to have the latter first.
> 
> Regards.
> 
> Sat, 15 Jan 2011 17:45:28 -0500 Jean-Claude Beaudoin <jean.claude.beaudoin at gmail.com>:
> 
>> Hello BDWGC Gurus,
>>
>> Here is a serious problem I encounter on all my x86_64 Linux
>> machines (Fedora 12, Fedora 14, Ubuntu 10.10).
>> The attached program demonstrates that the floating-point exception
>> mask is being reset to 0 (effectively cleared) by the GC on those machines.
>>
>> This behavior shows up with 7.0, 7.1, 7.2a4 and CVS (current as of yesterday).
>> Interestingly enough, it does not show up with 6.8!
>>
>> Here is the output of the test on x86_64:
>> ---------------------------------------------------------------------
>> jean-claude at mars> ./fpe_bug
>>
>> Done with GC_init()!
>>
>> After GC_init(): fegetexcept returned: 0, expected: 29.
>> ---------------------------------------------------------------------
>>
>> Here is the output of the test on i386 (or x86_64 with gc6.8):
>> ---------------------------------------------------------------------
>> jeancb at maximus> ./fpe_bug
>>
>> Done with GC_init()!
>>
>> At end fegetexcept() returned 29, expected: 29.
>> ---------------------------------------------------------------------
>>
>> More elaborate tests show that the problem is not limited to GC_init() but
>> happens
>> on every GC pass (stop world, collect, start world sequence).
>>
>> Thanks,
>>
>> Jean-Claude Beaudoin
>>
>>
>>
>> #define _GNU_SOURCE
>>
>> #include <fenv.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <pthread.h>
>> #include <time.h>
>>
>> #include "../include/gc.h"
>>
>> int main(int argc, char * argv[])
>> {
>> int except_mask =  FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW /* |
>> FE_INEXACT  */;
>> int status = feenableexcept(except_mask);
>>
>> {
>> int mask = fegetexcept();
>>
>> if ( mask != except_mask )
>> {
>> printf("\nBefore GC_init(): fegetexcept returned: %d, expected: %d.\n", mask,
>> except_mask);
>> return 1;
>> }
>>
>> }
>>
>> GC_init();
>>
>> printf("\nDone with GC_init()!\n"); fflush(NULL);
>>
>> {
>> int mask = fegetexcept();
>>
>> if ( mask != except_mask )
>> {
>> printf("\nAfter GC_init(): fegetexcept returned: %d, expected: %d.\n", mask,
>> except_mask);
>> return 1;
>> }
>>
>> }
>> printf("\nAt end fegetexcept() returned %d, expected: %d.\n", fegetexcept(),
>> except_mask);
>> return 0;
>> }
>>
>> CFLAGS=-pthread
>>
>> fpe_bug: fpe_bug.o ../.libs/libgc.a
>> gcc -o fpe_bug fpe_bug.o ../.libs/libgc.a -pthread -lm $(LDFLAGS)
>>
>> clean:
>> rm -f fpe_bug *.o *~
>>
>>
>> _______________________________________________
>> Gc mailing list
>> Gc at linux.hpl.hp.com
>> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: mach_dep.c.diff
Type: text/x-patch
Size: 462 bytes
Desc: not available
Url : http://napali.hpl.hp.com/pipermail/gc/attachments/20110119/beb2a6a7/mach_dep.c.bin


More information about the Gc mailing list