39 #ifndef G4FPEDetection_h
40 #define G4FPEDetection_h 1
46 #if (defined(__GNUC__) && !defined(__clang__))
54 struct sigaction termaction, oldaction;
56 static void G4StackBackTrace()
61 int nptrs = backtrace( buffer, BSIZE );
62 char ** strings = backtrace_symbols( buffer, nptrs );
63 if ( strings == NULL )
65 perror(
"backtrace_symbols" );
68 std::cerr << std::endl<<
"Call Stack:" << std::endl;
69 for (
int j = 0; j < nptrs; j++ )
71 std::cerr << nptrs-j-1 <<
": ";
72 char * mangled_start = strchr( strings[j],
'(' ) + 1;
73 if (mangled_start) *(mangled_start-1) =
'\0';
74 char * mangled_end = strchr( mangled_start,
'+' );
75 if ( mangled_end ) *mangled_end =
'\0';
78 if ( mangled_end && strlen(mangled_start) )
79 realname = abi::__cxa_demangle( mangled_start, 0, 0, &status );
82 std::cerr << strings[j]<<
" : " << realname << std::endl;
87 std::cerr << strings[j] << std::endl;
96 static void TerminationSignalHandler(
int sig, siginfo_t*
sinfo,
99 std::cerr <<
"ERROR: " << sig;
100 std::string
message =
"Floating-point exception (FPE).";
104 switch (sinfo->si_code)
110 message =
"Integer divide by zero.";
113 message =
"Integer overflow.";
116 message =
"Floating point divide by zero.";
119 message =
"Floating point overflow.";
122 message =
"Floating point underflow.";
125 message =
"Floating point inexact result.";
128 message =
"Floating point invalid operation.";
131 message =
"Subscript out of range.";
134 message =
"Unknown error.";
138 std::cerr <<
" - " << message << std::endl;
145 std::cout << std::endl
147 <<
"############################################" << std::endl
149 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
151 <<
"############################################" << std::endl;
153 (
void) feenableexcept( FE_DIVBYZERO );
154 (
void) feenableexcept( FE_INVALID );
158 sigfillset(&termaction.sa_mask);
159 sigdelset(&termaction.sa_mask,SIGFPE);
160 termaction.sa_sigaction=TerminationSignalHandler;
161 termaction.sa_flags=SA_SIGINFO;
162 sigaction(SIGFPE, &termaction, &oldaction);
171 #elif defined(__MACH__)
179 #if (defined(__ppc__) || defined(__ppc64__)) // PPC
181 #define FE_EXCEPT_SHIFT 22 // shift flags right to get masks
182 #define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
184 static inline int feenableexcept (
unsigned int excepts)
187 unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT,
190 if ( fegetenv (&fenv) ) {
return -1; }
191 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
192 fenv = (fenv & ~new_excepts) | new_excepts;
194 return ( fesetenv (&fenv) ? -1 : old_excepts );
197 static inline int fedisableexcept (
unsigned int excepts)
200 unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT),
203 if ( fegetenv (&fenv) ) {
return -1; }
204 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
207 return ( fesetenv (&fenv) ? -1 : old_excepts );
210 #elif (defined(__i386__) || defined(__x86_64__)) // INTEL
212 static inline int feenableexcept (
unsigned int excepts)
215 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
218 if ( fegetenv (&fenv) ) {
return -1; }
219 old_excepts = fenv.__control & FE_ALL_EXCEPT;
223 fenv.__control &= ~new_excepts;
224 fenv.__mxcsr &= ~(new_excepts << 7);
226 return ( fesetenv (&fenv) ? -1 : old_excepts );
229 static inline int fedisableexcept (
unsigned int excepts)
232 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
235 if ( fegetenv (&fenv) ) {
return -1; }
236 old_excepts = fenv.__control & FE_ALL_EXCEPT;
240 fenv.__control |= new_excepts;
241 fenv.__mxcsr |= new_excepts << 7;
243 return ( fesetenv (&fenv) ? -1 : old_excepts );
248 static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
void* )
250 std::cerr <<
"ERROR: " << sig;
251 std::string message =
"Floating-point exception (FPE).";
254 switch (sinfo->si_code) {
259 message =
"Integer divide by zero.";
262 message =
"Integer overflow.";
265 message =
"Floating point divide by zero.";
268 message =
"Floating point overflow.";
271 message =
"Floating point underflow.";
274 message =
"Floating point inexact result.";
277 message =
"Floating point invalid operation.";
280 message =
"Subscript out of range.";
283 message =
"Unknown error.";
288 std::cerr <<
" - " << message << std::endl;
295 struct sigaction termaction, oldaction;
297 std::cout << std::endl
299 <<
"############################################" << std::endl
301 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
303 <<
"############################################" << std::endl;
305 feenableexcept ( FE_DIVBYZERO );
306 feenableexcept ( FE_INVALID );
310 sigfillset(&termaction.sa_mask);
311 sigdelset(&termaction.sa_mask,SIGFPE);
312 termaction.sa_sigaction=TerminationSignalHandler;
313 termaction.sa_flags=SA_SIGINFO;
314 sigaction(SIGFPE, &termaction, &oldaction);