Hi Rene, Fons, Rooters, As you may know, SIGFPE (floating point exception signals) are not emitted by default on GCC/GLIBC GNU/Linux platforms. They must be turned on (see below) to catch things like overflows, divide by zero, invalid FP number, etc. We recently turned this on in our own code and it is catching many problems, some merely anoying, but some real. It also is catching some (so far) trivial problems in ROOT proper (eg, creating a TGDoubleSlider with fVmin == fVmax causes SIGFPE in TGDoubleVSlider::DoRedraw). To help find these problems and make ROOT better I would like to suggest that the code below get added to ROOT and turned on by the developers when testing. I think that it should be turned off by default in production code as it is almost guaranteed that folks have lurking SIGFPEs in their code and they probably won't appreciate the rude awakening (although they should!). However, it would be nice to have its use triggered w/out having to re-compile, eg via setting an environment variable. The code is designed for GNU/Linux systems and I don't know how portable it is, but since this platform is one of, if not the, dominant platform it should be useful for many. Thanks, -Brett. --------------------------------------------- // sigfpe.h - turn on SIGFPE emission. // To use create a static instance: // // static sigfpe allow_sigfpe(true); // #ifndef SIGFPE_H #define SIGFPE_H #if defined(linux) // Implicit g++ definition #include <fpu_control.h> #include <fenv.h> #endif struct sigfpe { sigfpe(bool activate); ~sigfpe(); #if defined(linux) #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1) fenv_t old_setting; #else fpu_control_t old_setting; #endif #endif bool activate_; static bool validate(); }; #endif // SIGFPE_H --------------------------------------------- // sigfpe.cxx #include "sigfpe.h" sigfpe::sigfpe(bool a) : activate_(a) { if(activate_==true) { #if defined(linux) #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1) fenv_t newval; fegetenv(&old_setting); fegetenv(&newval); newval.__control_word &= ~(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); fesetenv(&newval); #else old_setting = __fpu_control; fpu_control_t newval = old_setting & ~( _FPU_MASK_IM |_FPU_MASK_ZM |_FPU_MASK_OM ); _FPU_SETCW(newval); #endif #endif } } sigfpe::~sigfpe() { #if defined(linux) if(activate_==true) #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1) fesetenv(&old_setting); #else _FPU_SETCW(old_setting); #endif #endif } // end sigfpe.cxx ---------------------------------------------
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:11 MET