Changeset 1340 for trunk/source/global/management/include/G4FPEDetection.hh
- Timestamp:
- Nov 5, 2010, 3:45:55 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/global/management/include/G4FPEDetection.hh
r1337 r1340 25 25 // 26 26 // 27 // $Id: G4FPEDetection.hh,v 1. 2 2006/11/15 16:00:18 gcosmoExp $28 // GEANT4 tag $Name: g eant4-09-04-beta-01$27 // $Id: G4FPEDetection.hh,v 1.5 2010/10/14 17:02:52 mkelsey Exp $ 28 // GEANT4 tag $Name: global-V09-03-22 $ 29 29 // 30 30 // … … 32 32 // 33 33 // ----------------------------------------------------------------------- 34 // This global method should be used on LINUX platforms with gcc compiler35 // for activating NaN detection and FPE signals, and forcing abortion of36 // the application at the time these are detected.34 // This global method should be used on LINUX or MacOSX platforms with gcc 35 // compiler for activating NaN detection and FPE signals, and forcing 36 // abortion of the application at the time these are detected. 37 37 // Meant to be used for debug purposes, can be activated by compiling the 38 38 // "run" module with the flag G4FPE_DEBUG set in the environment. … … 41 41 #ifndef G4FPEDetection_h 42 42 #define G4FPEDetection_h 1 43 44 #include <iostream> 45 #include <stdlib.h> /* abort(), exit() */ 43 46 44 47 #ifdef __linux__ … … 48 51 #include <csignal> 49 52 50 #include <iostream>51 52 53 struct sigaction termaction, oldaction; 53 54 54 void TerminationSignalHandler(int sig)55 static void TerminationSignalHandler(int sig, siginfo_t* sinfo, void* /* context */) 55 56 { 56 57 std::cerr << "ERROR: " << sig; 57 std::string message; 58 switch (SIGFPE) 59 { 58 std::string message = "Floating-point exception (FPE)."; 59 60 if (sinfo) { 61 switch (sinfo->si_code) { 62 #ifdef FPE_NOOP /* BUG: MacOSX uses this instead of INTDIV */ 63 case FPE_NOOP: 64 #endif 60 65 case FPE_INTDIV: 61 66 message = "Integer divide by zero."; … … 85 90 message = "Unknown error."; 86 91 break; 87 } 92 } 93 } 94 88 95 std::cerr << " - " << message << std::endl; 89 96 90 97 ::abort(); 91 98 } 92 99 93 void InvalidOperationDetection()100 static void InvalidOperationDetection() 94 101 { 95 102 std::cout << std::endl … … 106 113 //(void) feenableexcept( FE_UNDERFLOW ); 107 114 108 sigset_t *def_set; 109 def_set=&termaction.sa_mask; 110 sigfillset(def_set); 111 sigdelset(def_set,SIGFPE); 112 termaction.sa_handler=TerminationSignalHandler; 113 termaction.sa_flags=0; 114 sigaction(SIGFPE, &termaction,&oldaction); 115 } 116 #endif 117 #else 118 void InvalidOperationDetection() {;} 119 #endif 120 121 #endif 115 sigdelset(&termaction.sa_mask,SIGFPE); 116 termaction.sa_sigaction=TerminationSignalHandler; 117 termaction.sa_flags=SA_SIGINFO; 118 sigaction(SIGFPE, &termaction, &oldaction); 119 } 120 #endif 121 #elif __MACH__ /* MacOSX */ 122 123 #include <fenv.h> 124 #include <signal.h> 125 126 #define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__)) 127 #define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__)) 128 129 #if DEFINED_PPC 130 131 #define FE_EXCEPT_SHIFT 22 // shift flags right to get masks 132 #define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT 133 134 static inline int feenableexcept (unsigned int excepts) 135 { 136 static fenv_t fenv; 137 unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT, 138 old_excepts; // all previous masks 139 140 if ( fegetenv (&fenv) ) { return -1; } 141 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; 142 fenv = (fenv & ~new_excepts) | new_excepts; 143 144 return ( fesetenv (&fenv) ? -1 : old_excepts ); 145 } 146 147 static inline int fedisableexcept (unsigned int excepts) 148 { 149 static fenv_t fenv; 150 unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT), 151 old_excepts; // previous masks 152 153 if ( fegetenv (&fenv) ) { return -1; } 154 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; 155 fenv &= still_on; 156 157 return ( fesetenv (&fenv) ? -1 : old_excepts ); 158 } 159 160 #elif DEFINED_INTEL 161 162 static inline int feenableexcept (unsigned int excepts) 163 { 164 static fenv_t fenv; 165 unsigned int new_excepts = excepts & FE_ALL_EXCEPT, 166 old_excepts; // previous masks 167 168 if ( fegetenv (&fenv) ) { return -1; } 169 old_excepts = fenv.__control & FE_ALL_EXCEPT; 170 171 // unmask 172 // 173 fenv.__control &= ~new_excepts; 174 fenv.__mxcsr &= ~(new_excepts << 7); 175 176 return ( fesetenv (&fenv) ? -1 : old_excepts ); 177 } 178 179 static inline int fedisableexcept (unsigned int excepts) 180 { 181 static fenv_t fenv; 182 unsigned int new_excepts = excepts & FE_ALL_EXCEPT, 183 old_excepts; // all previous masks 184 185 if ( fegetenv (&fenv) ) { return -1; } 186 old_excepts = fenv.__control & FE_ALL_EXCEPT; 187 188 // mask 189 // 190 fenv.__control |= new_excepts; 191 fenv.__mxcsr |= new_excepts << 7; 192 193 return ( fesetenv (&fenv) ? -1 : old_excepts ); 194 } 195 196 #endif /* PPC or INTEL enabling */ 197 198 static void TerminationSignalHandler(int sig, siginfo_t* sinfo, void* /* context */) 199 { 200 std::cerr << "ERROR: " << sig; 201 std::string message = "Floating-point exception (FPE)."; 202 203 if (sinfo) { 204 switch (sinfo->si_code) { 205 #ifdef FPE_NOOP /* BUG: MacOSX uses this instead of INTDIV */ 206 case FPE_NOOP: 207 #endif 208 case FPE_INTDIV: 209 message = "Integer divide by zero."; 210 break; 211 case FPE_INTOVF: 212 message = "Integer overflow."; 213 break; 214 case FPE_FLTDIV: 215 message = "Floating point divide by zero."; 216 break; 217 case FPE_FLTOVF: 218 message = "Floating point overflow."; 219 break; 220 case FPE_FLTUND: 221 message = "Floating point underflow."; 222 break; 223 case FPE_FLTRES: 224 message = "Floating point inexact result."; 225 break; 226 case FPE_FLTINV: 227 message = "Floating point invalid operation."; 228 break; 229 case FPE_FLTSUB: 230 message = "Subscript out of range."; 231 break; 232 default: 233 message = "Unknown error."; 234 break; 235 } 236 } 237 238 std::cerr << " - " << message << std::endl; 239 240 ::abort(); 241 } 242 243 static void InvalidOperationDetection() 244 { 245 struct sigaction termaction, oldaction; 246 247 std::cout << std::endl 248 << " " 249 << "############################################" << std::endl 250 << " " 251 << "!!! WARNING - FPE detection is activated !!!" << std::endl 252 << " " 253 << "############################################" << std::endl; 254 255 feenableexcept ( FE_DIVBYZERO ); 256 feenableexcept ( FE_INVALID ); 257 // fedisableexcept( FE_OVERFLOW ); 258 // fedisableexcept( FE_UNDERFLOW ); 259 260 sigdelset(&termaction.sa_mask,SIGFPE); 261 termaction.sa_sigaction=TerminationSignalHandler; 262 termaction.sa_flags=SA_SIGINFO; 263 sigaction(SIGFPE, &termaction, &oldaction); 264 } 265 #else /* Not Linux, nor MacOSX ... */ 266 267 static void InvalidOperationDetection() {;} 268 269 #endif 270 271 #endif
Note: See TracChangeset
for help on using the changeset viewer.