|
Sierra Toolkit
Version of the Day
|
00001 00010 #include <iostream> 00011 00012 #include <signal.h> 00013 00014 #include <stk_util/diag/Env.hpp> 00015 #include <stk_util/diag/Signal.hpp> 00016 #include <stk_util/util/Callback.hpp> 00017 #include <stk_util/util/FeatureTest.hpp> 00018 #include <stk_util/diag/SignalHandler.hpp> 00019 00020 namespace sierra { 00021 namespace Env { 00022 00023 namespace { 00024 00029 class EnvSignal 00030 { 00031 public: 00032 static EnvSignal &instance() { 00033 static EnvSignal env_signal; 00034 00035 return env_signal; 00036 } 00037 00038 private: 00039 EnvSignal() 00040 : m_enabled(false), 00041 m_hupReceived(false), 00042 hupCallback(*this, &EnvSignal::hupHandler), 00043 segvCallback(*this, &EnvSignal::segvHandler), 00044 illCallback(*this, &EnvSignal::illHandler), 00045 busCallback(*this, &EnvSignal::busHandler), 00046 termCallback(*this, &EnvSignal::termHandler) 00047 {} 00048 00049 public: 00065 inline sigjmp_buf *getSigJmpBuf() { 00066 m_enabled = true; 00067 00068 return &m_sigJmpBuf; 00069 } 00070 00076 void disableSigLongJmp() { 00077 m_enabled = false; 00078 } 00079 00087 const std::string &message() const { 00088 return m_message; 00089 } 00090 00095 bool getHUPReceived() { 00096 return m_hupReceived; 00097 } 00098 00103 void activateSignals(); 00104 00109 void deactivateSignals(); 00110 00111 private: 00112 void doSignal(const char *message, int signal); 00113 void hupHandler(); 00114 void segvHandler(); 00115 void illHandler(); 00116 void busHandler(); 00117 void termHandler(); 00118 void intHandler(); 00119 00120 private: 00121 sigjmp_buf m_sigJmpBuf; 00122 bool m_enabled; 00123 bool m_hupReceived; 00124 std::string m_message; 00125 00126 Callback<EnvSignal> hupCallback; 00127 Callback<EnvSignal> segvCallback; 00128 Callback<EnvSignal> illCallback; 00129 Callback<EnvSignal> busCallback; 00130 Callback<EnvSignal> termCallback; 00131 // Callback<EnvSignal> intCallback; 00132 00133 }; 00134 00135 00136 void 00137 EnvSignal::activateSignals() 00138 { 00139 SignalHandler::instance().add_handler(SIGSEGV, EnvSignal::segvCallback); 00140 SignalHandler::instance().add_handler(SIGILL, EnvSignal::illCallback); 00141 SignalHandler::instance().add_handler(SIGBUS, EnvSignal::busCallback); 00142 // SignalHandler::instance().add_handler(SIGINT, EnvSignal::intCallback); 00143 00144 #if defined(SIERRA_USER_SHUTDOWN_SIGNAL) 00145 SignalHandler::instance().add_handler(SIERRA_USER_SHUTDOWN_SIGNAL, EnvSignal::hupCallback); 00146 #endif 00147 #if defined(SIERRA_SHUTDOWN_SIGNAL) 00148 SignalHandler::instance().add_handler(SIERRA_SHUTDOWN_SIGNAL, EnvSignal::hupCallback); 00149 #endif 00150 #if defined(SIERRA_MPI_ABORT_SIGNAL) 00151 SignalHandler::instance().add_handler(SIERRA_MPI_ABORT_SIGNAL, EnvSignal::termCallback); 00152 #endif 00153 } 00154 00155 00156 void 00157 EnvSignal::deactivateSignals() 00158 { 00159 SignalHandler::instance().remove_handler(SIGSEGV, EnvSignal::segvCallback); 00160 SignalHandler::instance().remove_handler(SIGILL, EnvSignal::illCallback); 00161 SignalHandler::instance().remove_handler(SIGBUS, EnvSignal::busCallback); 00162 // SignalHandler::instance().add_handler(SIGINT, EnvSignal::intCallback); 00163 00164 #if defined(SIERRA_USER_SHUTDOWN_SIGNAL) 00165 SignalHandler::instance().remove_handler(SIERRA_USER_SHUTDOWN_SIGNAL, EnvSignal::hupCallback); 00166 #endif 00167 #if defined(SIERRA_SHUTDOWN_SIGNAL) 00168 SignalHandler::instance().remove_handler(SIERRA_SHUTDOWN_SIGNAL, EnvSignal::hupCallback); 00169 #endif 00170 #if defined(SIERRA_MPI_ABORT_SIGNAL) 00171 SignalHandler::instance().remove_handler(SIERRA_MPI_ABORT_SIGNAL, EnvSignal::termCallback); 00172 #endif 00173 } 00174 00175 00176 void 00177 EnvSignal::doSignal( 00178 const char * message, 00179 int signal) 00180 { 00181 if (!m_enabled) { 00182 // std::cout << message << std::endl << "Signal exception handling not enabled" << std::endl; 00183 ::raise(signal); 00184 return; 00185 } 00186 else { 00187 m_enabled = false; 00188 m_message = message; 00189 ::siglongjmp(m_sigJmpBuf, signal); 00190 } 00191 } 00192 00193 00194 void 00195 EnvSignal::hupHandler() 00196 { 00197 m_hupReceived = true; 00198 } 00199 00200 00201 void 00202 EnvSignal::intHandler() 00203 { 00204 m_hupReceived = true; 00205 } 00206 00207 00208 void 00209 EnvSignal::segvHandler() 00210 { 00211 SignalHandler::instance().remove_handler(SIGSEGV, EnvSignal::segvCallback); 00212 doSignal("Segmentation violation error", SIGSEGV); 00213 } 00214 00215 void 00216 EnvSignal::busHandler() 00217 { 00218 SignalHandler::instance().remove_handler(SIGBUS, EnvSignal::busCallback); 00219 doSignal("Bus error", SIGBUS); 00220 } 00221 00222 00223 void 00224 EnvSignal::illHandler() 00225 { 00226 SignalHandler::instance().remove_handler(SIGILL, EnvSignal::illCallback); 00227 doSignal("Illegal instruction error", SIGILL); 00228 } 00229 00230 00231 void 00232 EnvSignal::termHandler() 00233 { 00234 SignalHandler::instance().remove_handler(SIGTERM, EnvSignal::termCallback); 00235 doSignal("Terminate signal received, likely due to an abort on another processor\n" 00236 "Refer to standard output log for more information", SIGTERM); 00237 } 00238 00239 } // namespace <unnamed> 00240 00241 00242 void 00243 activate_signals() 00244 { 00245 EnvSignal::instance().activateSignals(); 00246 } 00247 00248 00249 void 00250 deactivate_signals() 00251 { 00252 EnvSignal::instance().deactivateSignals(); 00253 } 00254 00255 00256 sigjmp_buf * 00257 get_sigjmpbuf() 00258 { 00259 return EnvSignal::instance().getSigJmpBuf(); 00260 } 00261 00262 00263 void 00264 disable_siglongjmp() 00265 { 00266 return EnvSignal::instance().disableSigLongJmp(); 00267 } 00268 00269 00270 const std::string & 00271 get_signal_message() 00272 { 00273 return EnvSignal::instance().message(); 00274 } 00275 00276 00277 bool 00278 HUP_received() 00279 { 00280 return EnvSignal::instance().getHUPReceived(); 00281 } 00282 00283 } // namespace Env 00284 } // namespace sierra