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

Ivan Maidanski ivmai at mail.ru
Thu Jan 20 13:17:59 PST 2011


Hi,

Some notes about the patch:
1. LINUX macro should be tested instead if linux;
2. IFAIK this requires -lm linker option (alternatively we could load it dynamically to avoid possible changes of makefiles of the client applications) ;
3. These functions are available only starting from some Glib version (the corresponding macro should be tested).
4. Should we define _GNU_SOURCE before include fenv.h or not?
5. It's better to test GETCONTEXT_FPU_EXCMASK_BUG in mach_dep.c and set it in gcconfig.h (please also let me when the bug in glib will be fixed to adjust gcconfig.h then).

Regards.

Wed, 19 Jan 2011 21:52:14 -0500 Jean-Claude Beaudoin <jean.claude.beaudoin at gmail.com>:

> 
> 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/
> 
> 
> jean-claude at mars> diff mach_dep.c mach_dep.c.orig
> 191,194d190
> < #if linux && __x86_64__
> < #include <fenv.h>
> < #endif
> < 
> 211,218d206
> < #if linux && __x86_64__
> <       int except_mask = fegetexcept();
> < 
> <       if (getcontext(&ctxt) < 0)
> <         ABORT ("Getcontext failed: Use another register retrieval method?");
> <       if (feenableexcept(except_mask) < 0)
> < 	ABORT ("Feenableexcept failed: Use another register retrieval method?");
> < #else
> 221d208
> < #endif
> 
> _______________________________________________
> Gc mailing list
> Gc at linux.hpl.hp.com
> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/



More information about the Gc mailing list