Sierra Toolkit  Version of the Day
Signal.cpp
1 
10 #include <iostream>
11 
12 #include <signal.h>
13 
14 #include <stk_util/diag/Env.hpp>
15 #include <stk_util/diag/Signal.hpp>
17 #include <stk_util/util/FeatureTest.hpp>
19 
20 namespace sierra {
21 namespace Env {
22 
23 namespace {
24 
29 class EnvSignal
30 {
31 public:
32  static EnvSignal &instance() {
33  static EnvSignal env_signal;
34 
35  return env_signal;
36  }
37 
38 private:
39  EnvSignal()
40  : m_enabled(false),
41  m_hupReceived(false),
42  hupCallback(*this, &EnvSignal::hupHandler),
43  segvCallback(*this, &EnvSignal::segvHandler),
44  illCallback(*this, &EnvSignal::illHandler),
45  busCallback(*this, &EnvSignal::busHandler),
46  termCallback(*this, &EnvSignal::termHandler)
47  {}
48 
49 public:
65  inline sigjmp_buf *getSigJmpBuf() {
66  m_enabled = true;
67 
68  return &m_sigJmpBuf;
69  }
70 
76  void disableSigLongJmp() {
77  m_enabled = false;
78  }
79 
87  const std::string &message() const {
88  return m_message;
89  }
90 
95  bool getHUPReceived() {
96  return m_hupReceived;
97  }
98 
103  void activateSignals();
104 
109  void deactivateSignals();
110 
111 private:
112  void doSignal(const char *message, int signal);
113  void hupHandler();
114  void segvHandler();
115  void illHandler();
116  void busHandler();
117  void termHandler();
118  void intHandler();
119 
120 private:
121  sigjmp_buf m_sigJmpBuf;
122  bool m_enabled;
123  bool m_hupReceived;
124  std::string m_message;
125 
126  Callback<EnvSignal> hupCallback;
127  Callback<EnvSignal> segvCallback;
128  Callback<EnvSignal> illCallback;
129  Callback<EnvSignal> busCallback;
130  Callback<EnvSignal> termCallback;
131 // Callback<EnvSignal> intCallback;
132 
133 };
134 
135 
136  void
137 EnvSignal::activateSignals()
138 {
139  SignalHandler::instance().add_handler(SIGSEGV, EnvSignal::segvCallback);
140  SignalHandler::instance().add_handler(SIGILL, EnvSignal::illCallback);
141  SignalHandler::instance().add_handler(SIGBUS, EnvSignal::busCallback);
142 // SignalHandler::instance().add_handler(SIGINT, EnvSignal::intCallback);
143 
144 #if defined(SIERRA_USER_SHUTDOWN_SIGNAL)
145  SignalHandler::instance().add_handler(SIERRA_USER_SHUTDOWN_SIGNAL, EnvSignal::hupCallback);
146 #endif
147 #if defined(SIERRA_SHUTDOWN_SIGNAL)
148  SignalHandler::instance().add_handler(SIERRA_SHUTDOWN_SIGNAL, EnvSignal::hupCallback);
149 #endif
150 #if defined(SIERRA_MPI_ABORT_SIGNAL)
151  SignalHandler::instance().add_handler(SIERRA_MPI_ABORT_SIGNAL, EnvSignal::termCallback);
152 #endif
153 }
154 
155 
156 void
157 EnvSignal::deactivateSignals()
158 {
159  SignalHandler::instance().remove_handler(SIGSEGV, EnvSignal::segvCallback);
160  SignalHandler::instance().remove_handler(SIGILL, EnvSignal::illCallback);
161  SignalHandler::instance().remove_handler(SIGBUS, EnvSignal::busCallback);
162 // SignalHandler::instance().add_handler(SIGINT, EnvSignal::intCallback);
163 
164 #if defined(SIERRA_USER_SHUTDOWN_SIGNAL)
165  SignalHandler::instance().remove_handler(SIERRA_USER_SHUTDOWN_SIGNAL, EnvSignal::hupCallback);
166 #endif
167 #if defined(SIERRA_SHUTDOWN_SIGNAL)
168  SignalHandler::instance().remove_handler(SIERRA_SHUTDOWN_SIGNAL, EnvSignal::hupCallback);
169 #endif
170 #if defined(SIERRA_MPI_ABORT_SIGNAL)
171  SignalHandler::instance().remove_handler(SIERRA_MPI_ABORT_SIGNAL, EnvSignal::termCallback);
172 #endif
173 }
174 
175 
176 void
177 EnvSignal::doSignal(
178  const char * message,
179  int signal)
180 {
181  if (!m_enabled) {
182 // std::cout << message << std::endl << "Signal exception handling not enabled" << std::endl;
183  ::raise(signal);
184  return;
185  }
186  else {
187  m_enabled = false;
188  m_message = message;
189  ::siglongjmp(m_sigJmpBuf, signal);
190  }
191 }
192 
193 
194 void
195 EnvSignal::hupHandler()
196 {
197  m_hupReceived = true;
198 }
199 
200 
201 void
202 EnvSignal::intHandler()
203 {
204  m_hupReceived = true;
205 }
206 
207 
208 void
209 EnvSignal::segvHandler()
210 {
211  SignalHandler::instance().remove_handler(SIGSEGV, EnvSignal::segvCallback);
212  doSignal("Segmentation violation error", SIGSEGV);
213 }
214 
215 void
216 EnvSignal::busHandler()
217 {
218  SignalHandler::instance().remove_handler(SIGBUS, EnvSignal::busCallback);
219  doSignal("Bus error", SIGBUS);
220 }
221 
222 
223 void
224 EnvSignal::illHandler()
225 {
226  SignalHandler::instance().remove_handler(SIGILL, EnvSignal::illCallback);
227  doSignal("Illegal instruction error", SIGILL);
228 }
229 
230 
231 void
232 EnvSignal::termHandler()
233 {
234  SignalHandler::instance().remove_handler(SIGTERM, EnvSignal::termCallback);
235  doSignal("Terminate signal received, likely due to an abort on another processor\n"
236  "Refer to standard output log for more information", SIGTERM);
237 }
238 
239 } // namespace <unnamed>
240 
241 
242 void
244 {
245  EnvSignal::instance().activateSignals();
246 }
247 
248 
249 void
251 {
252  EnvSignal::instance().deactivateSignals();
253 }
254 
255 
256 sigjmp_buf *
258 {
259  return EnvSignal::instance().getSigJmpBuf();
260 }
261 
262 
263 void
264 disable_siglongjmp()
265 {
266  return EnvSignal::instance().disableSigLongJmp();
267 }
268 
269 
270 const std::string &
272 {
273  return EnvSignal::instance().message();
274 }
275 
276 
277 bool
279 {
280  return EnvSignal::instance().getHUPReceived();
281 }
282 
283 } // namespace Env
284 } // namespace sierra
Definition: Env.cpp:53
sigjmp_buf * get_sigjmpbuf()
Function get_sigjmpbuf enables signal handling and returns a pointer to the jump buffer for ::sigsetj...
Definition: Signal.cpp:257
void remove_handler(int signal, CallbackBase &callback)
Member function remove_handler ...
static SignalHandler & instance()
Member function instance ...
bool HUP_received()
Function request_shutdown sets the shutdown requested flag so that future calls to shutdown_requested...
Definition: Signal.cpp:278
const std::string & get_signal_message()
Function disable_siglongjmp disables the long jump buffer. When signals are received, they return to the caller without long jumping to the set jump point.
Definition: Signal.cpp:271
void add_handler(int signal, CallbackBase &callback)
Member function add_handler ...
void deactivate_signals()
Function deactivate_signals disables the signal handlers.
Definition: Signal.cpp:250
void activate_signals()
Function activate_signals enables the signal handlers.
Definition: Signal.cpp:243