40 #ifndef G4FPEDetection_h
41 #define G4FPEDetection_h 1
46 #if (defined(__GNUC__) && !defined(__clang__))
55 struct sigaction termaction, oldaction;
57 static void G4StackBackTrace()
63 int nptrs = backtrace( buffer, BSIZE );
65 char ** strings = backtrace_symbols( buffer, nptrs );
66 if ( strings == NULL ) {
67 perror(
"backtrace_symbols" );
70 std::cerr << std::endl<<
"Call Stack:" << std::endl;
71 for (
int j = 0; j < nptrs; j++ ){
73 std::cerr << nptrs-j-1 <<
": ";
75 char * mangled_start = strchr( strings[j],
'(' ) + 1;
76 if (mangled_start) *(mangled_start-1) =
'\0';
77 char * mangled_end = strchr( mangled_start,
'+' );
78 if ( mangled_end ) *mangled_end =
'\0';
82 if ( mangled_end && strlen(mangled_start) )
83 realname = abi::__cxa_demangle( mangled_start, 0, 0, &status );
85 std::cerr << strings[j]<<
" : " << realname << std::endl;
88 std::cerr << strings[j] << std::endl;
96 static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
void* )
98 std::cerr <<
"ERROR: " << sig;
99 std::string message =
"Floating-point exception (FPE).";
102 switch (sinfo->si_code) {
107 message =
"Integer divide by zero.";
110 message =
"Integer overflow.";
113 message =
"Floating point divide by zero.";
116 message =
"Floating point overflow.";
119 message =
"Floating point underflow.";
122 message =
"Floating point inexact result.";
125 message =
"Floating point invalid operation.";
128 message =
"Subscript out of range.";
131 message =
"Unknown error.";
136 std::cerr <<
" - " << message << std::endl;
143 std::cout << std::endl
145 <<
"############################################" << std::endl
147 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
149 <<
"############################################" << std::endl;
151 (
void) feenableexcept( FE_DIVBYZERO );
152 (
void) feenableexcept( FE_INVALID );
156 sigfillset(&termaction.sa_mask);
157 sigdelset(&termaction.sa_mask,SIGFPE);
158 termaction.sa_sigaction=TerminationSignalHandler;
159 termaction.sa_flags=SA_SIGINFO;
160 sigaction(SIGFPE, &termaction, &oldaction);
163 #elif defined(__MACH__)
167 #define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
168 #define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
172 #define FE_EXCEPT_SHIFT 22 // shift flags right to get masks
173 #define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
175 static inline int feenableexcept (
unsigned int excepts)
178 unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT,
181 if ( fegetenv (&fenv) ) {
return -1; }
182 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
183 fenv = (fenv & ~new_excepts) | new_excepts;
185 return ( fesetenv (&fenv) ? -1 : old_excepts );
188 static inline int fedisableexcept (
unsigned int excepts)
191 unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT),
194 if ( fegetenv (&fenv) ) {
return -1; }
195 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
198 return ( fesetenv (&fenv) ? -1 : old_excepts );
203 static inline int feenableexcept (
unsigned int excepts)
206 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
209 if ( fegetenv (&fenv) ) {
return -1; }
210 old_excepts = fenv.__control & FE_ALL_EXCEPT;
214 fenv.__control &= ~new_excepts;
215 fenv.__mxcsr &= ~(new_excepts << 7);
217 return ( fesetenv (&fenv) ? -1 : old_excepts );
220 static inline int fedisableexcept (
unsigned int excepts)
223 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
226 if ( fegetenv (&fenv) ) {
return -1; }
227 old_excepts = fenv.__control & FE_ALL_EXCEPT;
231 fenv.__control |= new_excepts;
232 fenv.__mxcsr |= new_excepts << 7;
234 return ( fesetenv (&fenv) ? -1 : old_excepts );
239 static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
void* )
241 std::cerr <<
"ERROR: " << sig;
242 std::string message =
"Floating-point exception (FPE).";
245 switch (sinfo->si_code) {
250 message =
"Integer divide by zero.";
253 message =
"Integer overflow.";
256 message =
"Floating point divide by zero.";
259 message =
"Floating point overflow.";
262 message =
"Floating point underflow.";
265 message =
"Floating point inexact result.";
268 message =
"Floating point invalid operation.";
271 message =
"Subscript out of range.";
274 message =
"Unknown error.";
279 std::cerr <<
" - " << message << std::endl;
286 struct sigaction termaction, oldaction;
288 std::cout << std::endl
290 <<
"############################################" << std::endl
292 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
294 <<
"############################################" << std::endl;
296 feenableexcept ( FE_DIVBYZERO );
297 feenableexcept ( FE_INVALID );
301 sigfillset(&termaction.sa_mask);
302 sigdelset(&termaction.sa_mask,SIGFPE);
303 termaction.sa_sigaction=TerminationSignalHandler;
304 termaction.sa_flags=SA_SIGINFO;
305 sigaction(SIGFPE, &termaction, &oldaction);
static void InvalidOperationDetection()
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData