973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
7fd59977 |
13 | |
42cf5bc1 |
14 | |
15 | #include <OSD.hxx> |
7fd59977 |
16 | |
9bf6baed |
17 | #ifndef _WIN32 |
7fd59977 |
18 | |
19 | //---------- All Systems except Windows NT : ---------------------------------- |
20 | |
7fd59977 |
21 | # include <stdio.h> |
22 | |
23 | #include <OSD_WhoAmI.hxx> |
24 | #include <OSD_SIGHUP.hxx> |
25 | #include <OSD_SIGINT.hxx> |
26 | #include <OSD_SIGQUIT.hxx> |
27 | #include <OSD_SIGILL.hxx> |
28 | #include <OSD_SIGKILL.hxx> |
29 | #include <OSD_SIGBUS.hxx> |
30 | #include <OSD_SIGSEGV.hxx> |
31 | #include <OSD_SIGSYS.hxx> |
8a262fa1 |
32 | #include <OSD_Exception_CTRL_BREAK.hxx> |
7fd59977 |
33 | #include <Standard_NumericError.hxx> |
7fd59977 |
34 | #include <Standard_DivideByZero.hxx> |
35 | #include <Standard_Overflow.hxx> |
36 | |
37 | #include <Standard_ErrorHandler.hxx> |
38 | |
39 | // POSIX threads |
03155c18 |
40 | #include <pthread.h> |
7fd59977 |
41 | |
42 | #ifdef linux |
43 | #include <fenv.h> |
7fd59977 |
44 | static Standard_Boolean fFltExceptions = Standard_False; |
45 | #endif |
46 | |
8a262fa1 |
47 | // variable signalling that Control-C has been pressed (SIGINT signal) |
48 | static Standard_Boolean fCtrlBrk; |
49 | |
7fd59977 |
50 | //const OSD_WhoAmI Iam = OSD_WPackage; |
51 | |
52 | typedef void (ACT_SIGIO_HANDLER)(void) ; |
53 | ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ; |
54 | |
7fd59977 |
55 | #ifdef DECOSF1 |
56 | typedef void (* SIG_PFV) (int); |
57 | #endif |
58 | |
7fd59977 |
59 | #ifdef __GNUC__ |
60 | # include <stdlib.h> |
61 | # include <stdio.h> |
62 | #else |
63 | # ifdef SA_SIGINFO |
64 | # ifndef _AIX |
65 | # include <sys/siginfo.h> |
66 | # endif |
67 | # endif |
68 | #endif |
69 | typedef void (* SIG_PFV) (int); |
70 | |
03155c18 |
71 | #include <signal.h> |
7fd59977 |
72 | |
d8d01f6e |
73 | #if !defined(__ANDROID__) && !defined(__QNX__) |
9bf6baed |
74 | #include <sys/signal.h> |
75 | #endif |
76 | |
77 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
7fd59977 |
78 | //============================================================================ |
79 | //==== GetOldSigAction |
80 | //==== get previous |
81 | //============================================================================ |
82 | |
83 | static struct sigaction *GetOldSigAction() |
84 | { |
85 | static struct sigaction oldSignals[NSIG]; |
86 | return oldSignals; |
87 | } |
88 | |
89 | #ifdef SOLARIS |
90 | static sigfpe_handler_type *GetOldFPE() |
91 | { |
92 | static sigfpe_handler_type aIEEEHandler[5] = { NULL, NULL, NULL, NULL, NULL } ; |
93 | return aIEEEHandler; |
94 | } |
95 | #endif |
96 | #endif |
97 | |
7fd59977 |
98 | //============================================================================ |
89c4bca8 |
99 | //==== Handler |
7fd59977 |
100 | //==== Catche the differents signals: |
101 | //==== 1- The Fatal signals, which cause the end of process: |
102 | //==== 2- The exceptions which are "signaled" by Raise. |
103 | //==== The Fatal Signals: |
104 | //==== SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGKILL, SIGBUS, SIGSYS |
105 | //==== The Exceptions: |
106 | //==== SIGFPE |
107 | //==== (SUN versions) |
108 | //==== FPE_INTOVF_TRAP // ..... integer overflow |
109 | //==== FPE_INTDIV_TRAP // ..... integer divide by zero |
110 | //==== FPE_FLTINEX_TRAP // ..... [floating inexact result] |
111 | //==== FPE_FLTDIV_TRAP // ..... [floating divide by zero] |
112 | //==== FPE_FLTUND_TRAP // ..... [floating underflow] |
113 | //==== FPE_FLTOPER_TRAP // ..... [floating inexact result] |
114 | //==== FPE_FLTOVF_TRAP // ..... [floating overflow] |
115 | //==== SIGSEGV is handled by "SegvHandler()" |
116 | //============================================================================ |
7fd59977 |
117 | #ifdef SA_SIGINFO |
c85385c0 |
118 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
89c4bca8 |
119 | static void Handler (const int theSignal, siginfo_t *theSigInfo, const Standard_Address theContext) |
c85385c0 |
120 | #else |
121 | static void Handler (const int theSignal, siginfo_t */*theSigInfo*/, const Standard_Address /*theContext*/) |
122 | #endif |
89c4bca8 |
123 | #else |
124 | static void Handler (const int theSignal) |
7fd59977 |
125 | #endif |
7fd59977 |
126 | { |
127 | struct sigaction oldact, act; |
7fd59977 |
128 | // re-install the signal |
7fd59977 |
129 | if ( ! sigaction (theSignal, NULL, &oldact) ) { |
89c4bca8 |
130 | // cout << " signal is " << theSignal << " handler is " << oldact.sa_handler << endl; |
131 | if (sigaction (theSignal, &oldact, &act)) perror ("sigaction"); |
132 | } |
133 | else { |
134 | perror ("sigaction"); |
7fd59977 |
135 | } |
7fd59977 |
136 | |
89c4bca8 |
137 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
7fd59977 |
138 | if (pthread_self() != getOCCThread() || !Standard_ErrorHandler::IsInTryBlock()) { |
139 | // use the previous signal handler |
89c4bca8 |
140 | // cout << "OSD::Handler: signal " << (int) theSignal << " occured outside a try block " << endl ; |
7fd59977 |
141 | struct sigaction *oldSignals = GetOldSigAction(); |
89c4bca8 |
142 | struct sigaction asigacthandler = oldSignals[theSignal >= 0 && theSignal < NSIG ? theSignal : 0]; |
143 | |
7fd59977 |
144 | if (asigacthandler.sa_flags & SA_SIGINFO) { |
145 | void (*aCurInfoHandle)(int, siginfo_t *, void *) = asigacthandler.sa_sigaction; |
7d679df3 |
146 | |
147 | siginfo_t * aSigInfo = NULL; |
148 | #ifdef SA_SIGINFO |
149 | aSigInfo = theSigInfo; |
150 | #endif |
151 | |
7fd59977 |
152 | if (aSigInfo) { |
89c4bca8 |
153 | switch (aSigInfo->si_signo) { |
154 | case SIGFPE: |
155 | { |
7fd59977 |
156 | #ifdef SOLARIS |
89c4bca8 |
157 | sigfpe_handler_type *aIEEEHandlerTab = GetOldFPE(); |
158 | sigfpe_handler_type aIEEEHandler = NULL; |
159 | switch (aSigInfo->si_code) { |
160 | case FPE_INTDIV_TRAP : |
161 | case FPE_FLTDIV_TRAP : |
162 | aIEEEHandler = aIEEEHandlerTab[1]; |
163 | break; |
164 | case FPE_INTOVF_TRAP : |
165 | case FPE_FLTOVF_TRAP : |
166 | aIEEEHandler = aIEEEHandlerTab[2]; |
167 | break; |
168 | case FPE_FLTUND_TRAP : |
169 | aIEEEHandler = aIEEEHandlerTab[4]; |
170 | break; |
171 | case FPE_FLTRES_TRAP : |
172 | aIEEEHandler = aIEEEHandlerTab[3]; |
173 | break; |
174 | case FPE_FLTINV_TRAP : |
175 | aIEEEHandler = aIEEEHandlerTab[0]; |
176 | break; |
177 | case FPE_FLTSUB_TRAP : |
178 | default: |
179 | break; |
180 | } |
181 | if (aIEEEHandler) { |
182 | // cout << "OSD::Handler: calling previous IEEE signal handler with info" << endl ; |
183 | (*aIEEEHandler) (theSignal, aSigInfo, theContext); |
184 | return; |
185 | } |
186 | #endif |
187 | break; |
188 | } |
189 | default: |
190 | break; |
191 | } |
7fd59977 |
192 | } |
193 | if (aCurInfoHandle) { |
89c4bca8 |
194 | // cout << "OSD::Handler: calling previous signal handler with info " << aCurInfoHandle << endl ; |
195 | (*aCurInfoHandle) (theSignal, aSigInfo, theContext); |
0797d9d3 |
196 | #ifdef OCCT_DEBUG |
89c4bca8 |
197 | cerr << " previous signal handler return" << endl ; |
63c629aa |
198 | #endif |
89c4bca8 |
199 | return; |
7fd59977 |
200 | } |
201 | else { |
202 | // cout << "OSD::Handler: no handler with info for the signal" << endl; |
203 | } |
89c4bca8 |
204 | } |
205 | else { |
206 | // no siginfo needed for the signal |
7fd59977 |
207 | void (*aCurHandler) (int) = asigacthandler.sa_handler; |
208 | if(aCurHandler) { |
89c4bca8 |
209 | // cout << "OSD::Handler: calling previous signal handler" << endl ; |
210 | (*aCurHandler) (theSignal); |
0797d9d3 |
211 | #ifdef OCCT_DEBUG |
89c4bca8 |
212 | cerr << " previous signal handler return" << endl ; |
63c629aa |
213 | #endif |
89c4bca8 |
214 | return; |
215 | } |
7fd59977 |
216 | } |
217 | // cout << " Signal occured outside a try block, but no handler for it" <<endl; |
218 | return; |
219 | } |
220 | #endif |
221 | |
7fd59977 |
222 | // cout << "OSD::Handler: signal " << (int) theSignal << " occured inside a try block " << endl ; |
89c4bca8 |
223 | if ( ADR_ACT_SIGIO_HANDLER != NULL ) |
224 | (*ADR_ACT_SIGIO_HANDLER)() ; |
7fd59977 |
225 | #ifdef linux |
226 | if (fFltExceptions) |
227 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
228 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
229 | #endif |
7fd59977 |
230 | sigset_t set; |
231 | sigemptyset(&set); |
89c4bca8 |
232 | switch (theSignal) { |
7fd59977 |
233 | case SIGHUP: |
234 | OSD_SIGHUP::NewInstance("SIGHUP 'hangup' detected.")->Jump(); |
235 | exit(SIGHUP); |
236 | break; |
7fd59977 |
237 | case SIGINT: |
8a262fa1 |
238 | // For safe handling of Control-C as stop event, arm a variable but do not |
239 | // generate longjump (we are out of context anyway) |
240 | fCtrlBrk = Standard_True; |
89c4bca8 |
241 | // OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump(); |
242 | // exit(SIGINT); |
7fd59977 |
243 | break; |
7fd59977 |
244 | case SIGQUIT: |
245 | OSD_SIGQUIT::NewInstance("SIGQUIT 'quit' detected.")->Jump(); |
246 | exit(SIGQUIT); |
247 | break; |
7fd59977 |
248 | case SIGILL: |
249 | OSD_SIGILL::NewInstance("SIGILL 'illegal instruction' detected.")->Jump(); |
250 | exit(SIGILL); |
251 | break; |
7fd59977 |
252 | case SIGKILL: |
253 | OSD_SIGKILL::NewInstance("SIGKILL 'kill' detected.")->Jump(); |
254 | exit(SIGKILL); |
255 | break; |
7fd59977 |
256 | case SIGBUS: |
257 | sigaddset(&set, SIGBUS); |
258 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
259 | OSD_SIGBUS::NewInstance("SIGBUS 'bus error' detected.")->Jump(); |
260 | exit(SIGBUS); |
261 | break; |
7fd59977 |
262 | case SIGSEGV: |
263 | OSD_SIGSEGV::NewInstance("SIGSEGV 'segmentation violation' detected.")->Jump(); |
264 | exit(SIGSEGV); |
265 | break; |
7fd59977 |
266 | #ifdef SIGSYS |
267 | case SIGSYS: |
268 | OSD_SIGSYS::NewInstance("SIGSYS 'bad argument to system call' detected.")->Jump(); |
269 | exit(SIGSYS); |
270 | break; |
271 | #endif |
89c4bca8 |
272 | case SIGFPE: |
7fd59977 |
273 | sigaddset(&set, SIGFPE); |
274 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
275 | #ifdef DECOSF1 |
89c4bca8 |
276 | // Pour DEC/OSF1 SIGFPE = Division par zero. |
7fd59977 |
277 | Standard_DivideByZero::NewInstance('')->Jump; |
7fd59977 |
278 | break; |
89c4bca8 |
279 | #endif |
7fd59977 |
280 | #if (!defined (__sun)) && (!defined(SOLARIS)) |
281 | Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump(); |
282 | break; |
283 | #else |
284 | // Reste SOLARIS |
89c4bca8 |
285 | if (aSigInfo) { |
7fd59977 |
286 | switch(aSigInfo->si_code) { |
287 | case FPE_FLTDIV_TRAP : |
89c4bca8 |
288 | Standard_DivideByZero::NewInstance("Floating Divide By Zero")->Jump(); |
289 | break; |
7fd59977 |
290 | case FPE_INTDIV_TRAP : |
89c4bca8 |
291 | Standard_DivideByZero::NewInstance("Integer Divide By Zero")->Jump(); |
292 | break; |
7fd59977 |
293 | case FPE_FLTOVF_TRAP : |
89c4bca8 |
294 | Standard_Overflow::NewInstance("Floating Overflow")->Jump(); |
295 | break; |
7fd59977 |
296 | case FPE_INTOVF_TRAP : |
89c4bca8 |
297 | Standard_Overflow::NewInstance("Integer Overflow")->Jump(); |
298 | break; |
7fd59977 |
299 | case FPE_FLTUND_TRAP : |
89c4bca8 |
300 | Standard_NumericError::NewInstance("Floating Underflow")->Jump(); |
301 | break; |
7fd59977 |
302 | case FPE_FLTRES_TRAP: |
89c4bca8 |
303 | Standard_NumericError::NewInstance("Floating Point Inexact Result")->Jump(); |
304 | break; |
7fd59977 |
305 | case FPE_FLTINV_TRAP : |
89c4bca8 |
306 | Standard_NumericError::NewInstance("Invalid Floating Point Operation")->Jump(); |
307 | break; |
7fd59977 |
308 | default: |
89c4bca8 |
309 | Standard_NumericError::NewInstance("Numeric Error")->Jump(); |
310 | break; |
7fd59977 |
311 | } |
89c4bca8 |
312 | } else { |
7fd59977 |
313 | Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump(); |
314 | } |
315 | #endif |
316 | break; |
7fd59977 |
317 | #if defined (__sgi) || defined(IRIX) |
89c4bca8 |
318 | case SIGTRAP: |
7fd59977 |
319 | sigaddset(&set, SIGTRAP); |
320 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
321 | Standard_DivideByZero::NewInstance("SIGTRAP IntegerDivideByZero")->Jump(); break; |
322 | #endif |
323 | default: |
0797d9d3 |
324 | #ifdef OCCT_DEBUG |
89c4bca8 |
325 | cout << "Unexpected signal " << theSignal << endl ; |
63c629aa |
326 | #endif |
89c4bca8 |
327 | break; |
8a262fa1 |
328 | } |
329 | } |
330 | |
7fd59977 |
331 | //============================================================================ |
89c4bca8 |
332 | //==== SegvHandler |
7fd59977 |
333 | //============================================================================ |
7fd59977 |
334 | #ifdef SA_SIGINFO |
335 | |
89c4bca8 |
336 | static void SegvHandler(const int theSignal, |
337 | siginfo_t *ip, |
338 | const Standard_Address theContext) |
7fd59977 |
339 | { |
89c4bca8 |
340 | #ifdef NO_CXX_EXCEPTION |
7fd59977 |
341 | if (!Standard_ErrorHandler::IsInTryBlock()) { |
89c4bca8 |
342 | Handler(theSignal, ip, theContext); |
7fd59977 |
343 | return; |
344 | } |
c85385c0 |
345 | #else |
04e93070 |
346 | (void)theSignal; // silence GCC warnings |
347 | (void)theContext; |
7fd59977 |
348 | #endif |
7fd59977 |
349 | #ifdef linux |
350 | if (fFltExceptions) |
351 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
352 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
353 | #endif |
7fd59977 |
354 | // cout << "OSD::SegvHandler activated(SA_SIGINFO)" << endl ; |
355 | if ( ip != NULL ) { |
356 | sigset_t set; |
357 | sigemptyset(&set); |
358 | sigaddset(&set, SIGSEGV); |
359 | sigprocmask (SIG_UNBLOCK, &set, NULL) ; |
89c4bca8 |
360 | void *address = ip->si_addr ; |
4d9421a9 |
361 | { |
7fd59977 |
362 | char Msg[100]; |
363 | sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx", |
89c4bca8 |
364 | (long ) address ) ; |
7fd59977 |
365 | OSD_SIGSEGV::NewInstance(Msg)->Jump(); |
366 | } |
89c4bca8 |
367 | } |
0797d9d3 |
368 | #ifdef OCCT_DEBUG |
89c4bca8 |
369 | else { |
7fd59977 |
370 | cout << "Wrong undefined address." << endl ; |
89c4bca8 |
371 | } |
63c629aa |
372 | #endif |
7fd59977 |
373 | exit(SIGSEGV); |
374 | } |
375 | |
89c4bca8 |
376 | #elif defined (_hpux) || defined(HPUX) |
7fd59977 |
377 | // Not ACTIVE ? SA_SIGINFO is defined on SUN, OSF, SGI and HP (and Linux) ! |
378 | // pour version 09.07 |
89c4bca8 |
379 | |
380 | static void SegvHandler(const int theSignal, |
381 | siginfo_t *ip, |
382 | const Standard_Address theContext) |
7fd59977 |
383 | { |
384 | unsigned long Space ; |
385 | unsigned long Offset ; |
386 | char Msg[100] ; |
387 | |
89c4bca8 |
388 | if ( theContext != NULL ) { |
389 | Space = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr20 ; |
390 | Offset = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr21 ; |
7fd59977 |
391 | // cout << "Wrong address = " << hex(Offset) << endl ; |
4d9421a9 |
392 | { |
89c4bca8 |
393 | sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ; |
394 | OSD_SIGSEGV::Jump(Msg); |
7fd59977 |
395 | // scp->sc_pcoq_head = scp->sc_pcoq_tail ; Permettrait de continuer a |
396 | // scp->sc_pcoq_tail = scp->sc_pcoq_tail + 0x4 ; l'intruction suivant le segv. |
397 | } |
398 | } |
0797d9d3 |
399 | #ifdef OCCT_DEBUG |
89c4bca8 |
400 | else { |
7fd59977 |
401 | cout << "Wrong undefined address." << endl ; |
89c4bca8 |
402 | } |
63c629aa |
403 | #endif |
7fd59977 |
404 | exit(SIGSEGV); |
89c4bca8 |
405 | } |
406 | |
407 | #endif |
408 | |
409 | //============================================================================ |
410 | //==== SetSignal |
411 | //==== Set the differents signals: |
412 | //============================================================================ |
413 | |
414 | void OSD::SetSignal(const Standard_Boolean aFloatingSignal) |
415 | { |
416 | static int first_time = 3 ; |
417 | struct sigaction act, oact; |
418 | int stat = 0; |
419 | |
420 | if( aFloatingSignal ) { |
421 | //==== Enable the floating point exceptions =============== |
422 | #if defined (__sun) || defined (SOLARIS) |
423 | sigfpe_handler_type PHandler = (sigfpe_handler_type) Handler ; |
424 | stat = ieee_handler("set", "invalid", PHandler); |
425 | stat = ieee_handler("set", "division", PHandler) || stat; |
426 | stat = ieee_handler("set", "overflow", PHandler) || stat; |
427 | |
428 | //stat = ieee_handler("set", "underflow", PHandler) || stat; |
429 | //stat = ieee_handler("set", "inexact", PHandler) || stat; |
430 | |
431 | if (stat) { |
0797d9d3 |
432 | #ifdef OCCT_DEBUG |
89c4bca8 |
433 | cerr << "ieee_handler does not work !!! KO " << endl; |
63c629aa |
434 | #endif |
89c4bca8 |
435 | } |
436 | #elif defined (linux) |
437 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
438 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
439 | fFltExceptions = Standard_True; |
440 | #endif |
441 | } |
442 | else if ( first_time & 1 ) { |
443 | // cout << "SetSignal( Standard_False ) is not implemented..." << endl ; |
444 | first_time = first_time & (~ 1) ; |
445 | } |
446 | |
447 | #if defined (sgi) || defined (IRIX ) |
448 | if ( first_time & 2 ) { |
449 | char *TRAP_FPE = getenv("TRAP_FPE") ; |
450 | if ( TRAP_FPE == NULL ) { |
0797d9d3 |
451 | #ifdef OCCT_DEBUG |
89c4bca8 |
452 | cout << "On SGI you must set TRAP_FPE environment variable : " << endl ; |
453 | cout << "set env(TRAP_FPE) \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\" or" << endl ; |
454 | cout << "setenv TRAP_FPE \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\"" << endl ; |
63c629aa |
455 | #endif |
89c4bca8 |
456 | // exit(1) ; |
457 | first_time = first_time & (~ 2) ; |
458 | } |
459 | } |
460 | #endif |
461 | |
462 | //==== Save the old Signal Handler, and set the new one =================== |
463 | |
464 | sigemptyset(&act.sa_mask) ; |
465 | |
466 | #ifdef SA_RESTART |
467 | act.sa_flags = SA_RESTART ; |
468 | #else |
469 | act.sa_flags = 0 ; |
470 | #endif |
471 | #ifdef SA_SIGINFO |
472 | act.sa_flags = act.sa_flags | SA_SIGINFO ; |
473 | act.sa_sigaction = /*(void(*)(int, siginfo_t *, void*))*/ Handler; |
474 | #else |
475 | act.sa_handler = /*(SIG_PFV)*/ Handler; |
476 | #endif |
7fd59977 |
477 | |
89c4bca8 |
478 | //==== Always detected the signal "SIGFPE" ================================= |
479 | stat = sigaction(SIGFPE,&act,&oact); // ...... floating point exception |
480 | if (stat) { |
0797d9d3 |
481 | #ifdef OCCT_DEBUG |
89c4bca8 |
482 | cerr << "sigaction does not work !!! KO " << endl; |
63c629aa |
483 | #endif |
89c4bca8 |
484 | perror("sigaction "); |
485 | } |
486 | |
487 | //==== Detected the only the "free" signals ================================ |
488 | sigaction(SIGHUP,&act,&oact); // ...... hangup |
489 | |
490 | #ifdef OBJS |
491 | if(oact.sa_handler) |
492 | sigaction(SIGHUP,&oact,&oact); |
493 | #endif |
494 | |
495 | sigaction(SIGINT,&act,&oact); // ...... interrupt |
496 | |
497 | #ifdef OBJS |
498 | if(oact.sa_handler) |
499 | sigaction(SIGINT,&oact,&oact); |
7fd59977 |
500 | #endif |
89c4bca8 |
501 | |
502 | sigaction(SIGQUIT,&act,&oact); // ...... quit |
503 | |
504 | #ifdef OBJS |
505 | if(oact.sa_handler) |
506 | sigaction(SIGQUIT,&oact,&oact); |
507 | #endif |
508 | |
509 | sigaction(SIGILL,&act,&oact); // ...... illegal instruction |
510 | |
511 | #ifdef OBJS |
512 | if(oact.sa_handler) |
513 | sigaction(SIGILL,&oact,&oact); |
514 | #endif |
515 | |
516 | sigaction(SIGBUS,&act,&oact); // ...... bus error |
517 | |
518 | #ifdef OBJS |
519 | if(oact.sa_handler) |
520 | sigaction(SIGBUS,&oact,&oact); |
521 | #endif |
522 | |
57c28b61 |
523 | #if (!defined (linux)) && (!defined(__linux__)) |
89c4bca8 |
524 | sigaction(SIGSYS,&act,&oact); // ...... bad argument to system call |
525 | |
526 | # ifdef OBJS |
527 | if(oact.sa_handler) |
528 | sigaction(SIGSYS,&oact,&oact); |
529 | # endif |
530 | #endif |
531 | |
532 | #if defined (__sgi) || defined(IRIX) |
533 | sigaction(SIGTRAP,&act,&oact); // Integer Divide By Zero (IRIX) |
534 | |
535 | # ifdef OBJS |
536 | if(oact.sa_handler) |
537 | sigaction(SIGTRAP,&oact,&oact); |
538 | # endif |
539 | #endif |
540 | |
541 | #ifdef SA_SIGINFO |
542 | act.sa_sigaction = /*(void(*)(int, siginfo_t *, void*))*/ SegvHandler; |
7fd59977 |
543 | #else |
89c4bca8 |
544 | act.sa_handler = /*(SIG_PFV)*/ SegvHandler; |
545 | #endif |
7fd59977 |
546 | |
89c4bca8 |
547 | if ( sigaction( SIGSEGV , &act , &oact ) ) // ...... segmentation violation |
548 | perror("OSD::SetSignal sigaction( SIGSEGV , &act , &oact ) ") ; |
7fd59977 |
549 | |
89c4bca8 |
550 | #ifdef OBJS |
551 | if(oact.sa_handler) |
552 | sigaction(SIGSEGV,&oact,&oact); |
553 | #endif |
554 | #if defined(__osf__) || defined(DECOSF1) |
555 | struct sigaction action, prev_action; |
556 | action.sa_handler = SIG_IGN; |
557 | action.sa_mask = 0; |
558 | action.sa_flags = 0; |
559 | |
560 | if (sigaction (SIGFPE, &action, &prev_action) == -1) { |
561 | perror ("sigaction"); |
562 | exit (1); |
563 | } |
7fd59977 |
564 | #endif |
89c4bca8 |
565 | |
566 | } |
567 | |
568 | //============================================================================ |
569 | //==== ControlBreak |
570 | //============================================================================ |
571 | |
572 | void OSD :: ControlBreak () |
573 | { |
574 | if ( fCtrlBrk ) { |
575 | fCtrlBrk = Standard_False; |
576 | OSD_Exception_CTRL_BREAK::Raise ("*** INTERRUPT ***"); |
577 | } |
578 | } |
579 | |
7fd59977 |
580 | #endif |