38#ifndef G4FPEDetection_hh
39#define G4FPEDetection_hh 1
45# if(defined(__GNUC__) && !defined(__clang__))
53struct sigaction termaction, oldaction;
55static void G4StackBackTrace()
60 int nptrs = backtrace(buffer, BSIZE);
61 char** strings = backtrace_symbols(buffer, nptrs);
64 perror(
"backtrace_symbols");
67 std::cerr << std::endl <<
"Call Stack:" << std::endl;
68 for(
int j = 0; j < nptrs; j++)
70 std::cerr << nptrs - j - 1 <<
": ";
71 char* mangled_start = strchr(strings[j],
'(') + 1;
73 *(mangled_start - 1) =
'\0';
74 char* mangled_end = strchr(mangled_start,
'+');
79 if(mangled_end && strlen(mangled_start))
80 realname = abi::__cxa_demangle(mangled_start, 0, 0, &status);
83 std::cerr << strings[j] <<
" : " << realname << std::endl;
88 std::cerr << strings[j] << std::endl;
97static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
100 std::cerr <<
"ERROR: " << sig;
101 std::string message =
"Floating-point exception (FPE).";
105 switch(sinfo->si_code)
111 message =
"Integer divide by zero.";
114 message =
"Integer overflow.";
117 message =
"Floating point divide by zero.";
120 message =
"Floating point overflow.";
123 message =
"Floating point underflow.";
126 message =
"Floating point inexact result.";
129 message =
"Floating point invalid operation.";
132 message =
"Subscript out of range.";
135 message =
"Unknown error.";
139 std::cerr <<
" - " << message << std::endl;
144static void InvalidOperationDetection()
146 std::cout << std::endl
148 <<
"############################################" << std::endl
150 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
152 <<
"############################################" << std::endl;
154 (void) feenableexcept(FE_DIVBYZERO);
155 (void) feenableexcept(FE_INVALID);
159 sigfillset(&termaction.sa_mask);
160 sigdelset(&termaction.sa_mask, SIGFPE);
161 termaction.sa_sigaction = TerminationSignalHandler;
162 termaction.sa_flags = SA_SIGINFO;
163 sigaction(SIGFPE, &termaction, &oldaction);
168static void InvalidOperationDetection() { ; }
172#elif defined(__MACH__)
180# if(defined(__ppc__) || defined(__ppc64__))
182# define FE_EXCEPT_SHIFT 22
183# define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
185static inline int feenableexcept(
unsigned int excepts)
188 unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT,
195 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
196 fenv = (fenv & ~new_excepts) | new_excepts;
198 return (fesetenv(&fenv) ? -1 : old_excepts);
201static inline int fedisableexcept(
unsigned int excepts)
204 unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT),
211 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
214 return (fesetenv(&fenv) ? -1 : old_excepts);
217# elif(defined(__i386__) || defined(__x86_64__))
219static inline int feenableexcept(
unsigned int excepts)
222 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
229 old_excepts = fenv.__control & FE_ALL_EXCEPT;
233 fenv.__control &= ~new_excepts;
234 fenv.__mxcsr &= ~(new_excepts << 7);
236 return (fesetenv(&fenv) ? -1 : old_excepts);
239static inline int fedisableexcept(
unsigned int excepts)
242 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
249 old_excepts = fenv.__control & FE_ALL_EXCEPT;
253 fenv.__control |= new_excepts;
254 fenv.__mxcsr |= new_excepts << 7;
256 return (fesetenv(&fenv) ? -1 : old_excepts);
261static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
264 std::cerr <<
"ERROR: " << sig;
265 std::string message =
"Floating-point exception (FPE).";
269 switch(sinfo->si_code)
275 message =
"Integer divide by zero.";
278 message =
"Integer overflow.";
281 message =
"Floating point divide by zero.";
284 message =
"Floating point overflow.";
287 message =
"Floating point underflow.";
290 message =
"Floating point inexact result.";
293 message =
"Floating point invalid operation.";
296 message =
"Subscript out of range.";
299 message =
"Unknown error.";
304 std::cerr <<
" - " << message << std::endl;
309static void InvalidOperationDetection()
311 struct sigaction termaction, oldaction;
313 std::cout << std::endl
315 <<
"############################################" << std::endl
317 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
319 <<
"############################################" << std::endl;
321 feenableexcept(FE_DIVBYZERO);
322 feenableexcept(FE_INVALID);
326 sigfillset(&termaction.sa_mask);
327 sigdelset(&termaction.sa_mask, SIGFPE);
328 termaction.sa_sigaction = TerminationSignalHandler;
329 termaction.sa_flags = SA_SIGINFO;
330 sigaction(SIGFPE, &termaction, &oldaction);
335static void InvalidOperationDetection() { ; }