7fd59977 |
1 | |
2 | #include <OSD.ixx> |
3 | |
4 | #ifndef WNT |
5 | |
6 | //---------- All Systems except Windows NT : ---------------------------------- |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | # include <config.h> |
10 | #endif |
11 | |
12 | # include <stdio.h> |
13 | |
14 | #include <OSD_WhoAmI.hxx> |
15 | #include <OSD_SIGHUP.hxx> |
16 | #include <OSD_SIGINT.hxx> |
17 | #include <OSD_SIGQUIT.hxx> |
18 | #include <OSD_SIGILL.hxx> |
19 | #include <OSD_SIGKILL.hxx> |
20 | #include <OSD_SIGBUS.hxx> |
21 | #include <OSD_SIGSEGV.hxx> |
22 | #include <OSD_SIGSYS.hxx> |
23 | #include <Standard_NumericError.hxx> |
24 | #include <Standard_NullObject.hxx> |
25 | #include <Standard_DivideByZero.hxx> |
26 | #include <Standard_Overflow.hxx> |
27 | |
28 | #include <Standard_ErrorHandler.hxx> |
29 | |
30 | // POSIX threads |
31 | #ifdef HAVE_PTHREAD_H |
32 | #include <pthread.h> |
33 | #endif |
34 | |
35 | #ifdef HAVE_PTHREAD_H |
36 | static pthread_t getOCCThread () { |
37 | static pthread_t TheOCCThread = 0; |
38 | return TheOCCThread ; |
39 | } |
40 | #endif |
41 | |
42 | #ifdef linux |
43 | #include <fenv.h> |
44 | #include <fpu_control.h> |
45 | static Standard_Boolean fFltExceptions = Standard_False; |
46 | #endif |
47 | |
48 | //const OSD_WhoAmI Iam = OSD_WPackage; |
49 | |
50 | typedef void (ACT_SIGIO_HANDLER)(void) ; |
51 | ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ; |
52 | |
53 | #if defined(HAVE_FLOATINGPOINT_H) && defined(HAVE_SYS_MACHSIG_H) |
54 | # include <floatingpoint.h> |
55 | # include <sys/machsig.h> |
56 | // JPT : Difference between SUN/SUNOS and SUN/SOLARIS |
57 | # define FPE_FLTDIV_TRAP FPE_FLTDIV |
58 | # define FPE_INTDIV_TRAP FPE_INTDIV |
59 | # define FPE_FLTOVF_TRAP FPE_FLTOVF |
60 | # define FPE_INTOVF_TRAP FPE_INTOVF |
61 | # define FPE_FLTUND_TRAP FPE_FLTUND |
62 | |
63 | #define FPE_FLTRES_TRAP FPE_FLTRES /* floating point inexact result */ |
64 | #define FPE_FLTINV_TRAP FPE_FLTINV /* invalid floating point operation */ |
65 | #define FPE_FLTSUB_TRAP FPE_FLTSUB /* subscript out of range */ |
66 | |
67 | extern "C" {int ieee_handler(char *,char *, sigfpe_handler_type&);} |
68 | # include <stdlib.h> |
69 | #endif |
70 | |
71 | #ifdef DECOSF1 |
72 | typedef void (* SIG_PFV) (int); |
73 | #endif |
74 | |
75 | #if defined(HAVE_SIGFPE_H) && defined(HAVE_SYS_SIGINFO_H) |
76 | # include <sigfpe.h> |
77 | # include <sys/siginfo.h> |
78 | # define FPE_FLTDIV_TRAP FPE_FLTDIV |
79 | # define FPE_INTDIV_TRAP FPE_INTDIV |
80 | # define FPE_FLTOVF_TRAP FPE_FLTOVF |
81 | # define FPE_INTOVF_TRAP FPE_INTOVF |
82 | # define FPE_FLTUND_TRAP FPE_FLTUND |
83 | #endif |
84 | |
85 | #ifdef __GNUC__ |
86 | # include <stdlib.h> |
87 | # include <stdio.h> |
88 | #else |
89 | # ifdef SA_SIGINFO |
90 | # ifndef _AIX |
91 | # include <sys/siginfo.h> |
92 | # endif |
93 | # endif |
94 | #endif |
95 | typedef void (* SIG_PFV) (int); |
96 | |
97 | #ifdef HAVE_SIGNAL_H |
98 | # include <signal.h> |
99 | #endif |
100 | |
101 | #ifdef HAVE_SYS_SIGNAL_H |
102 | # include <sys/signal.h> |
103 | #endif |
104 | |
105 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
106 | //============================================================================ |
107 | //==== GetOldSigAction |
108 | //==== get previous |
109 | //============================================================================ |
110 | |
111 | static struct sigaction *GetOldSigAction() |
112 | { |
113 | static struct sigaction oldSignals[NSIG]; |
114 | return oldSignals; |
115 | } |
116 | |
117 | #ifdef SOLARIS |
118 | static sigfpe_handler_type *GetOldFPE() |
119 | { |
120 | static sigfpe_handler_type aIEEEHandler[5] = { NULL, NULL, NULL, NULL, NULL } ; |
121 | return aIEEEHandler; |
122 | } |
123 | #endif |
124 | #endif |
125 | |
126 | |
127 | //============================================================================ |
128 | //==== SetSignal |
129 | //==== Set the differents signals: |
130 | //============================================================================ |
131 | |
132 | void OSD::SetSignal(const Standard_Boolean aFloatingSignal) |
133 | { |
134 | static int first_time = 3 ; |
135 | struct sigaction act, oact; |
136 | int stat = 0; |
137 | |
138 | if( aFloatingSignal ) { |
139 | //==== Enable the floating point exceptions =============== |
140 | #if defined (__sun) || defined (SOLARIS) |
141 | sigfpe_handler_type PHandler = (sigfpe_handler_type) Handler ; |
142 | stat = ieee_handler("set", "invalid", PHandler); |
143 | stat = ieee_handler("set", "division", PHandler) || stat; |
144 | stat = ieee_handler("set", "overflow", PHandler) || stat; |
145 | //stat = ieee_handler("set", "underflow", PHandler) || stat; |
146 | //stat = ieee_handler("set", "inexact", PHandler) || stat; |
147 | if (stat) { |
148 | cerr << "ieee_handler does not work !!! KO " << endl; |
149 | } |
150 | #elif defined (linux) |
151 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
152 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
153 | fFltExceptions = Standard_True; |
154 | #endif |
155 | } |
156 | else if ( first_time & 1 ) { |
157 | // cout << "SetSignal( Standard_False ) is not implemented..." << endl ; |
158 | first_time = first_time & (~ 1) ; |
159 | } |
160 | |
161 | #if defined (sgi) || defined (IRIX ) |
162 | if ( first_time & 2 ) { |
163 | char *TRAP_FPE = getenv("TRAP_FPE") ; |
164 | if ( TRAP_FPE == NULL ) { |
165 | cout << "On SGI you must set TRAP_FPE environment variable : " << endl ; |
166 | cout << "set env(TRAP_FPE) \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\" or" << endl ; |
167 | cout << "setenv TRAP_FPE \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\"" << endl ; |
168 | // exit(1) ; |
169 | first_time = first_time & (~ 2) ; |
170 | } |
171 | } |
172 | #endif |
173 | |
174 | //==== Save the old Signal Handler, and set the new one =================== |
175 | |
176 | sigemptyset(&act.sa_mask) ; |
177 | |
178 | #ifdef SA_RESTART |
179 | act.sa_flags = SA_RESTART ; |
180 | #else |
181 | act.sa_flags = 0 ; |
182 | #endif |
183 | #ifdef SA_SIGINFO |
184 | act.sa_flags = act.sa_flags | SA_SIGINFO ; |
185 | act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &Handler ; |
186 | #else |
187 | act.sa_handler = (SIG_PFV) &Handler ; |
188 | #endif |
189 | |
190 | //==== Always detected the signal "SIGFPE" ================================= |
191 | stat = sigaction(SIGFPE,&act,&oact); // ...... floating point exception |
192 | if (stat) { |
193 | cerr << "sigaction does not work !!! KO " << endl; |
194 | perror("sigaction "); |
195 | } |
196 | |
197 | //==== Detected the only the "free" signals ================================ |
198 | sigaction(SIGHUP,&act,&oact); // ...... hangup |
199 | |
200 | #ifdef OBJS |
201 | if(oact.sa_handler) |
202 | sigaction(SIGHUP,&oact,&oact); |
203 | #endif |
204 | |
205 | sigaction(SIGINT,&act,&oact); // ...... interrupt |
206 | |
207 | #ifdef OBJS |
208 | if(oact.sa_handler) |
209 | sigaction(SIGINT,&oact,&oact); |
210 | #endif |
211 | |
212 | sigaction(SIGQUIT,&act,&oact); // ...... quit |
213 | |
214 | #ifdef OBJS |
215 | if(oact.sa_handler) |
216 | sigaction(SIGQUIT,&oact,&oact); |
217 | #endif |
218 | |
219 | sigaction(SIGILL,&act,&oact); // ...... illegal instruction |
220 | |
221 | #ifdef OBJS |
222 | if(oact.sa_handler) |
223 | sigaction(SIGILL,&oact,&oact); |
224 | #endif |
225 | |
226 | sigaction(SIGBUS,&act,&oact); // ...... bus error |
227 | |
228 | #ifdef OBJS |
229 | if(oact.sa_handler) |
230 | sigaction(SIGBUS,&oact,&oact); |
231 | #endif |
232 | |
233 | #if (!defined (linux)) && (!defined(LININTEL)) |
234 | sigaction(SIGSYS,&act,&oact); // ...... bad argument to system call |
235 | |
236 | # ifdef OBJS |
237 | if(oact.sa_handler) |
238 | sigaction(SIGSYS,&oact,&oact); |
239 | # endif |
240 | #endif |
241 | |
242 | #if defined (__sgi) || defined(IRIX) |
243 | sigaction(SIGTRAP,&act,&oact); // Integer Divide By Zero (IRIX) |
244 | |
245 | # ifdef OBJS |
246 | if(oact.sa_handler) |
247 | sigaction(SIGTRAP,&oact,&oact); |
248 | # endif |
249 | #endif |
250 | |
251 | #ifdef SA_SIGINFO |
252 | act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ; |
253 | #else |
254 | act.sa_handler = (SIG_PFV) &SegvHandler ; |
255 | #endif |
256 | |
257 | if ( sigaction( SIGSEGV , &act , &oact ) ) // ...... segmentation violation |
258 | perror("OSD::SetSignal sigaction( SIGSEGV , &act , &oact ) ") ; |
259 | |
260 | #ifdef OBJS |
261 | if(oact.sa_handler) |
262 | sigaction(SIGSEGV,&oact,&oact); |
263 | #endif |
264 | #if defined(__osf__) || defined(DECOSF1) |
265 | struct sigaction action, prev_action; |
266 | action.sa_handler = SIG_IGN; |
267 | action.sa_mask = 0; |
268 | action.sa_flags = 0; |
269 | |
270 | if (sigaction (SIGFPE, &action, &prev_action) == -1) { |
271 | perror ("sigaction"); |
272 | exit (1); |
273 | } |
274 | #endif |
275 | |
276 | } |
277 | //============================================================================ |
278 | //==== Handler |
279 | //==== Catche the differents signals: |
280 | //==== 1- The Fatal signals, which cause the end of process: |
281 | //==== 2- The exceptions which are "signaled" by Raise. |
282 | //==== The Fatal Signals: |
283 | //==== SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGKILL, SIGBUS, SIGSYS |
284 | //==== The Exceptions: |
285 | //==== SIGFPE |
286 | //==== (SUN versions) |
287 | //==== FPE_INTOVF_TRAP // ..... integer overflow |
288 | //==== FPE_INTDIV_TRAP // ..... integer divide by zero |
289 | //==== FPE_FLTINEX_TRAP // ..... [floating inexact result] |
290 | //==== FPE_FLTDIV_TRAP // ..... [floating divide by zero] |
291 | //==== FPE_FLTUND_TRAP // ..... [floating underflow] |
292 | //==== FPE_FLTOPER_TRAP // ..... [floating inexact result] |
293 | //==== FPE_FLTOVF_TRAP // ..... [floating overflow] |
294 | //==== SIGSEGV is handled by "SegvHandler()" |
295 | //============================================================================ |
296 | |
297 | |
298 | void OSD::Handler(const OSD_Signals theSignal, |
299 | const Standard_Address |
300 | #ifdef SA_SIGINFO |
301 | theSigInfo |
302 | #endif |
303 | ,const Standard_Address |
304 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
305 | theContext |
306 | #endif |
307 | ) |
308 | { |
309 | struct sigaction oldact, act; |
310 | |
311 | // re-install the signal |
312 | |
313 | if ( ! sigaction (theSignal, NULL, &oldact) ) { |
314 | // cout << " signal is " << theSignal << " handler is " << oldact.sa_handler << endl; |
315 | if (sigaction (theSignal, &oldact, &act)) perror ("sigaction"); |
316 | } |
317 | else |
318 | perror ("sigaction"); |
319 | |
320 | siginfo_t * aSigInfo = NULL; |
321 | #ifdef SA_SIGINFO |
322 | aSigInfo = (siginfo_t *) theSigInfo; |
323 | #endif |
324 | |
325 | #if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION) |
326 | |
327 | //#ifdef DEB |
328 | // cout << " current thread " << pthread_self() << endl; |
329 | //#endif |
330 | |
331 | |
332 | if (pthread_self() != getOCCThread() || !Standard_ErrorHandler::IsInTryBlock()) { |
333 | // use the previous signal handler |
334 | // cout << "OSD::Handler: signal " << (int) theSignal << " occured outside a try block " << endl ; |
335 | |
336 | struct sigaction *oldSignals = GetOldSigAction(); |
337 | struct sigaction asigacthandler = oldSignals[(int) theSignal]; |
338 | |
339 | if (asigacthandler.sa_flags & SA_SIGINFO) { |
340 | void (*aCurInfoHandle)(int, siginfo_t *, void *) = asigacthandler.sa_sigaction; |
341 | if (aSigInfo) { |
342 | switch (aSigInfo->si_signo) { |
343 | case SIGFPE: |
344 | { |
345 | #ifdef SOLARIS |
346 | sigfpe_handler_type *aIEEEHandlerTab = GetOldFPE(); |
347 | sigfpe_handler_type aIEEEHandler = NULL; |
348 | |
349 | switch (aSigInfo->si_code) { |
350 | case FPE_INTDIV_TRAP : |
351 | case FPE_FLTDIV_TRAP : |
352 | aIEEEHandler = aIEEEHandlerTab[1]; |
353 | break; |
354 | case FPE_INTOVF_TRAP : |
355 | case FPE_FLTOVF_TRAP : |
356 | aIEEEHandler = aIEEEHandlerTab[2]; |
357 | break; |
358 | case FPE_FLTUND_TRAP : |
359 | aIEEEHandler = aIEEEHandlerTab[4]; |
360 | break; |
361 | case FPE_FLTRES_TRAP: |
362 | aIEEEHandler = aIEEEHandlerTab[3]; |
363 | break; |
364 | case FPE_FLTINV_TRAP : |
365 | aIEEEHandler = aIEEEHandlerTab[0]; |
366 | break; |
367 | case FPE_FLTSUB_TRAP : |
368 | default: |
369 | break; |
370 | } |
371 | if (aIEEEHandler) { |
372 | // cout << "OSD::Handler: calling previous IEEE signal handler with info" << endl ; |
373 | void (*aFPEHandler)(int, siginfo_t *, void *) = (void(*)(int, siginfo*, void*)) aIEEEHandler; |
374 | (*aFPEHandler) (theSignal, aSigInfo, theContext); |
375 | return; |
376 | } |
377 | #endif |
378 | } |
379 | break; |
380 | case SIGSEGV: |
381 | switch (aSigInfo->si_code) { |
382 | case SEGV_MAPERR: |
383 | // cout << "OSD::Handler: SIGSEGV signal : address not mapped to object"; |
384 | break; |
385 | case SEGV_ACCERR: |
386 | // cout << "OSD::Handler: SIGSEGV signal : invalid permissions for mapped object"; |
387 | break; |
388 | default: |
389 | // cout << "OSD::Handler: SIGSEGV signal : unknown segv"; |
390 | break; |
391 | } |
392 | // cout << " at address " << (void *) aSigInfo->si_addr << endl; |
393 | break; |
394 | case SIGBUS: |
395 | switch (aSigInfo->si_code) { |
396 | case BUS_ADRALN: |
397 | // cout << "OSD::Handler: SIGBUS signal : invalid address alignment"; |
398 | break; |
399 | case BUS_ADRERR: |
400 | // cout << "OSD::Handler: SIGBUS signal : non-existent physical address"; |
401 | break; |
402 | case BUS_OBJERR: |
403 | // cout << "OSD::Handler: SIGBUS signal : object specific hardware error"; |
404 | break; |
405 | default: |
406 | // cout << "OSD::Handler: SIGBUS signal : unknown sig bus"; |
407 | break; |
408 | } |
409 | // cout << " at " << (void *) aSigInfo->si_addr << endl; |
410 | break; |
411 | case SIGILL: |
412 | // cout << "OSD::Handler: illegal instruction signal " << endl; |
413 | break; |
414 | #ifdef SIGSYS |
415 | case SIGSYS: |
416 | // cout << "OSD::Handler: bad argument to system call signal"<< endl ; |
417 | break; |
418 | #endif |
419 | case SIGINT: |
420 | // cout << "OSD::Handler: interrupt signal" << endl; |
421 | break; |
422 | default: |
423 | break; |
424 | } |
425 | } |
426 | if (aCurInfoHandle) { |
427 | // cout << "OSD::Handler: calling previous signal handler with info " << aCurInfoHandle << endl ; |
428 | (*aCurInfoHandle) (theSignal, aSigInfo, theContext); |
429 | cerr << " previous signal handler return" << endl ; |
430 | return; |
431 | } |
432 | else { |
433 | // cout << "OSD::Handler: no handler with info for the signal" << endl; |
434 | } |
435 | } else { |
436 | // no siginfi needed for the signal |
437 | void (*aCurHandler) (int) = asigacthandler.sa_handler; |
438 | if(aCurHandler) { |
439 | // cout << "OSD::Handler: calling previous signal handler" << endl ; |
440 | (*aCurHandler) (theSignal); |
441 | cerr << " previous signal handler return" << endl ; |
442 | return; |
443 | } |
444 | } |
445 | // cout << " Signal occured outside a try block, but no handler for it" <<endl; |
446 | return; |
447 | } |
448 | #endif |
449 | |
450 | |
451 | // cout << "OSD::Handler: signal " << (int) theSignal << " occured inside a try block " << endl ; |
452 | |
453 | if ( ADR_ACT_SIGIO_HANDLER != NULL ) (*ADR_ACT_SIGIO_HANDLER)() ; |
454 | |
455 | #ifdef linux |
456 | if (fFltExceptions) |
457 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
458 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
459 | #endif |
460 | |
461 | sigset_t set; |
462 | sigemptyset(&set); |
463 | |
464 | switch(theSignal) { |
465 | |
466 | case SIGHUP: |
467 | OSD_SIGHUP::NewInstance("SIGHUP 'hangup' detected.")->Jump(); |
468 | exit(SIGHUP); |
469 | break; |
470 | |
471 | case SIGINT: |
472 | OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump(); |
473 | exit(SIGINT); |
474 | break; |
475 | |
476 | case SIGQUIT: |
477 | OSD_SIGQUIT::NewInstance("SIGQUIT 'quit' detected.")->Jump(); |
478 | exit(SIGQUIT); |
479 | break; |
480 | |
481 | case SIGILL: |
482 | OSD_SIGILL::NewInstance("SIGILL 'illegal instruction' detected.")->Jump(); |
483 | exit(SIGILL); |
484 | break; |
485 | |
486 | case SIGKILL: |
487 | OSD_SIGKILL::NewInstance("SIGKILL 'kill' detected.")->Jump(); |
488 | exit(SIGKILL); |
489 | break; |
490 | |
491 | case SIGBUS: |
492 | sigaddset(&set, SIGBUS); |
493 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
494 | OSD_SIGBUS::NewInstance("SIGBUS 'bus error' detected.")->Jump(); |
495 | exit(SIGBUS); |
496 | break; |
497 | |
498 | case SIGSEGV: |
499 | OSD_SIGSEGV::NewInstance("SIGSEGV 'segmentation violation' detected.")->Jump(); |
500 | exit(SIGSEGV); |
501 | break; |
502 | |
503 | #ifdef SIGSYS |
504 | case SIGSYS: |
505 | OSD_SIGSYS::NewInstance("SIGSYS 'bad argument to system call' detected.")->Jump(); |
506 | exit(SIGSYS); |
507 | break; |
508 | #endif |
509 | |
510 | case SIGFPE: |
511 | { |
512 | sigaddset(&set, SIGFPE); |
513 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
514 | #ifdef DECOSF1 |
515 | // Pour DEC/OSF1 SIGFPE = Division par zero. |
516 | // should be clarified why in debug mode only? |
517 | #ifdef DEBUG |
518 | Standard_DivideByZero::NewInstance('')->Jump; |
519 | #endif |
520 | break; |
521 | #endif |
522 | #if (!defined (__sun)) && (!defined(SOLARIS)) |
523 | Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump(); |
524 | break; |
525 | #else |
526 | // Reste SOLARIS |
527 | if (aSigInfo ) { |
528 | switch(aSigInfo->si_code) { |
529 | case FPE_FLTDIV_TRAP : |
530 | Standard_DivideByZero::NewInstance("Floating Divide By Zero")->Jump(); break; |
531 | case FPE_INTDIV_TRAP : |
532 | Standard_DivideByZero::NewInstance("Integer Divide By Zero")->Jump(); break; |
533 | case FPE_FLTOVF_TRAP : |
534 | Standard_Overflow::NewInstance("Floating Overflow")->Jump(); break; |
535 | case FPE_INTOVF_TRAP : |
536 | Standard_Overflow::NewInstance("Integer Overflow")->Jump(); break; |
537 | case FPE_FLTUND_TRAP : |
538 | Standard_NumericError::NewInstance("Floating Underflow")->Jump(); break; |
539 | case FPE_FLTRES_TRAP: |
540 | Standard_NumericError::NewInstance("Floating Point Inexact Result")->Jump(); break; |
541 | case FPE_FLTINV_TRAP : |
542 | Standard_NumericError::NewInstance("Invalid Floating Point Operation")->Jump(); break; |
543 | default: |
544 | Standard_NumericError::NewInstance("Numeric Error")->Jump(); break; |
545 | } |
546 | } |
547 | else { |
548 | Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump(); |
549 | } |
550 | #endif |
551 | break; |
552 | } |
553 | #if defined (__sgi) || defined(IRIX) |
554 | case SIGTRAP: |
555 | sigaddset(&set, SIGTRAP); |
556 | sigprocmask(SIG_UNBLOCK, &set, NULL) ; |
557 | Standard_DivideByZero::NewInstance("SIGTRAP IntegerDivideByZero")->Jump(); break; |
558 | #endif |
559 | default: |
560 | cout << "Unexpected signal " << (Standard_Integer ) theSignal << endl ; |
561 | } |
562 | } |
563 | |
564 | //============================================================================ |
565 | //==== SegvHandler |
566 | //============================================================================ |
567 | |
568 | #ifdef SA_SIGINFO |
569 | |
570 | #ifdef NO_CXX_EXCEPTION |
571 | void OSD::SegvHandler(const OSD_Signals theSig, |
572 | const Standard_Address ip, |
573 | const Standard_Address theContext) |
574 | { |
575 | if (!Standard_ErrorHandler::IsInTryBlock()) { |
576 | Handler(theSig, ip, theContext); |
577 | return; |
578 | } |
579 | #else |
580 | void OSD::SegvHandler(const OSD_Signals, |
581 | const Standard_Address ip, |
582 | const Standard_Address) |
583 | { |
584 | #endif |
585 | |
586 | #ifdef linux |
587 | if (fFltExceptions) |
588 | feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); |
589 | //feenableexcept (FE_INVALID | FE_DIVBYZERO); |
590 | #endif |
591 | |
592 | // cout << "OSD::SegvHandler activated(SA_SIGINFO)" << endl ; |
593 | if ( ip != NULL ) { |
594 | sigset_t set; |
595 | sigemptyset(&set); |
596 | sigaddset(&set, SIGSEGV); |
597 | sigprocmask (SIG_UNBLOCK, &set, NULL) ; |
598 | void *address = ((siginfo_t *)ip)->si_addr ; |
599 | if ( (((long) address )& ~0xffff) == (long) UndefinedHandleAddress ) { |
600 | Standard_NullObject::NewInstance("Attempt to access to null object")->Jump(); |
601 | } |
602 | else { |
603 | char Msg[100]; |
604 | sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx", |
605 | (long ) address ) ; |
606 | OSD_SIGSEGV::NewInstance(Msg)->Jump(); |
607 | } |
608 | } |
609 | else |
610 | cout << "Wrong undefined address." << endl ; |
611 | exit(SIGSEGV); |
612 | } |
613 | |
614 | #if defined (_hpux) || defined(HPUX) |
615 | //============================================================================ |
616 | //==== SegvHandler |
617 | //============================================================================ |
618 | |
619 | // Not ACTIVE ? SA_SIGINFO is defined on SUN, OSF, SGI and HP (and Linux) ! |
620 | // pour version 09.07 |
621 | void OSD::SegvHandler(const OSD_Signals aSig, const Standard_Address code, |
622 | const Standard_Address scp) |
623 | //void OSD::SegvHandler(const OSD_Signals aSig, int code, const Standard_Address scp) |
624 | { |
625 | unsigned long Space ; |
626 | unsigned long Offset ; |
627 | char Msg[100] ; |
628 | |
629 | if ( scp != NULL ) { |
630 | Space = ((struct sigcontext *)scp)->sc_sl.sl_ss.ss_cr20 ; |
631 | Offset = ((struct sigcontext *)scp)->sc_sl.sl_ss.ss_cr21 ; |
632 | // cout << "Wrong address = " << hex(Offset) << endl ; |
633 | if ((Offset & ~0xffff) == (long)UndefinedHandleAddress) |
634 | Standard_NullObject::Jump("Attempt to access to null object") ; |
635 | else { |
636 | sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ; |
637 | OSD_SIGSEGV::Jump(Msg); |
638 | // scp->sc_pcoq_head = scp->sc_pcoq_tail ; Permettrait de continuer a |
639 | // scp->sc_pcoq_tail = scp->sc_pcoq_tail + 0x4 ; l'intruction suivant le segv. |
640 | } |
641 | } |
642 | else |
643 | cout << "Wrong undefined address." << endl ; |
644 | exit(SIGSEGV); |
645 | } |
646 | |
647 | #endif |
648 | #else |
649 | // Must be there for compatibility with Windows NT system --------------- |
650 | |
651 | Standard_Integer OSD :: WntHandler ( const Standard_Address ) |
652 | {return 0 ;} |
653 | |
654 | #endif |
655 | #endif |