exception SIGSEGV inherits Signal;
exception SIGSYS inherits Signal;
-
- enumeration Signals is
- ---purpose:
- -- The "posix" signals.
- --
- S_SIGHUP, -- "hangup."
- S_SIGINT, -- "interrupt."
- S_SIGQUIT, -- "quit."
- S_SIGILL, -- "illegal instruction."
- S_SIGKILL, -- "kill."
- S_SIGBUS, -- "bus error."
- S_SIGSEGV, -- "segmentation violation."
- S_SIGSYS, -- "bad argument to system call."
- S_SIGFPE, -- "floating point exception."
- S_FPE_FLTDIV_TRAP, -- "floating/decimal divide by zero."
- S_FPE_INTDIV_TRAP, -- "integer divide by zero."
- S_FPE_FLTOVF_TRAP, -- "floating overflow."
- S_FPE_INTOVF_TRAP, -- "integer overflow."
- S_FPE_FLTUND_TRAP, -- "floating underflow."
- S_FPE_FLTINEX_TRAP -- "floating inexact result."
- end Signals;
-
----------------------------------------
-- Exceptions ( Windows NT specific ) --
----------------------------------------
exception Exception_STATUS_NO_MEMORY inherits Exception; -- generating by 'HeapAlloc'
exception Exception_CTRL_BREAK inherits Exception; -- generating by 'Ctrl-C' keystroke
- ----------------------------------------------
- -- Handler and SegvHandler (UNIX specific ) --
- ----------------------------------------------
-
- --
- -- Handler(aSignal: Signals; aCode: Signals)
- --
-
- Handler(aSignal: Signals; aSigInfo: Address; aContext: Address)
- ---Purpose:
- -- 1) Raise a exception when aSignal is a floating point signal.
- -- aSignal is SIGFPE.
- -- aCode is
- -- (FPE: Floating Point Exception)
- -- (FLT: FLoaTing operation.)
- -- (INT: INTeger operation.)
- -- (DIV: DIVided by zero.)
- -- (OVF: OVerFlow.)
- -- (INEX: INEXact operation.)
- --
- -- FPE_FLTDIV_TRAP (the exception "DivideByZero" is raised.)
- -- FPE_INTDIV_TRAP (the exception "DivideByZero" is raised.)
- --
- -- FPE_FLTOVF_TRAP (the exception "Overflow" is raised.)
- -- FPE_INTOVF_TRAP (the exception "Overflow" is raised.)
- --
- -- FPE_FLTINEX_TRAP (the exception "NumericError" is raised.)
- --
- -- 2) Display the signal name, and call "exit" with signal number for
- -- a "Hardware" signal.
- --
- raises
- DivideByZero,
- Overflow,
- Underflow,
- SIGHUP,
- SIGINT,
- SIGQUIT,
- SIGILL,
- SIGKILL,
- SIGBUS,
- SIGSEGV,
- SIGSYS
- is private;
-
- SegvHandler(aSignal: Signals; aSigInfo: Address; aContext: Address)
- ---Purpose:
- -- Handle access to null object and segmentation violation
- --
- raises
- NullObject,
- SIGSEGV
- is private;
-
- ---------------------------------------
- -- WntHandler (Windows NT specific ) --
- ---------------------------------------
-
- WntHandler ( exceptionInfo : Address from Standard )
- returns Integer from Standard
- raises DivideByZero,
- Overflow,
- Underflow,
- Exception_ACCESS_VIOLATION,
- Exception_ARRAY_BOUNDS_EXCEEDED,
- Exception_FLT_DENORMAL_OPERAND,
- Exception_FLT_DIVIDE_BY_ZERO,
- Exception_FLT_INEXACT_RESULT,
- Exception_FLT_INVALID_OPERATION,
- Exception_FLT_OVERFLOW,
- Exception_FLT_STACK_CHECK,
- Exception_FLT_UNDERFLOW,
- Exception_ILLEGAL_INSTRUCTION,
- Exception_IN_PAGE_ERROR,
- Exception_INVALID_DISPOSITION,
- Exception_NONCONTINUABLE_EXCEPTION,
- Exception_PRIV_INSTRUCTION,
- Exception_STACK_OVERFLOW,
- Exception_STATUS_NO_MEMORY
- is private;
- ---Purpose:
- -- 1) Raises an exception if the exception due to floating point errors.
- -- Flosting point errors:
- -- EXCEPTION_FLT_DENORMAL_OPERAND
- -- EXCEPTION_FLT_DIVIDE_BY_ZERO
- -- EXCEPTION_FLT_INEXACT_RESULT
- -- EXCEPTION_FLT_INVALID_OPERATION
- -- EXCEPTOPN_FLT_OVERFLOW
- -- EXCEPTION_FLT_STACK_CHECK
- -- EXCEPTION_FLT_UNDERFLOW
- -- 2) Displays a message box 'Continue' - 'Debugger' - 'Stop' if the environment
- -- variable 'CSF_EXCEPTION_PROMPT' is set and takes appropriate action.
- -- Raises an exception otherwise.
-
SetSignal(theFloatingSignal: Boolean = Standard_True);
---Purpose:
-- Sets signal and exception handlers.
#endif
#endif
-
-//============================================================================
-//==== SetSignal
-//==== Set the differents signals:
//============================================================================
-
-void OSD::SetSignal(const Standard_Boolean aFloatingSignal)
-{
- static int first_time = 3 ;
- struct sigaction act, oact;
- int stat = 0;
-
- if( aFloatingSignal ) {
- //==== Enable the floating point exceptions ===============
-#if defined (__sun) || defined (SOLARIS)
- sigfpe_handler_type PHandler = (sigfpe_handler_type) Handler ;
- stat = ieee_handler("set", "invalid", PHandler);
- stat = ieee_handler("set", "division", PHandler) || stat;
- stat = ieee_handler("set", "overflow", PHandler) || stat;
- //stat = ieee_handler("set", "underflow", PHandler) || stat;
- //stat = ieee_handler("set", "inexact", PHandler) || stat;
- if (stat) {
- cerr << "ieee_handler does not work !!! KO " << endl;
- }
-#elif defined (linux)
- feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
- //feenableexcept (FE_INVALID | FE_DIVBYZERO);
- fFltExceptions = Standard_True;
-#endif
- }
- else if ( first_time & 1 ) {
-// cout << "SetSignal( Standard_False ) is not implemented..." << endl ;
- first_time = first_time & (~ 1) ;
- }
-
-#if defined (sgi) || defined (IRIX )
- if ( first_time & 2 ) {
- char *TRAP_FPE = getenv("TRAP_FPE") ;
- if ( TRAP_FPE == NULL ) {
- cout << "On SGI you must set TRAP_FPE environment variable : " << endl ;
- cout << "set env(TRAP_FPE) \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\" or" << endl ;
- cout << "setenv TRAP_FPE \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\"" << endl ;
-// exit(1) ;
- first_time = first_time & (~ 2) ;
- }
- }
-#endif
-
- //==== Save the old Signal Handler, and set the new one ===================
-
- sigemptyset(&act.sa_mask) ;
-
-#ifdef SA_RESTART
- act.sa_flags = SA_RESTART ;
-#else
- act.sa_flags = 0 ;
-#endif
-#ifdef SA_SIGINFO
- act.sa_flags = act.sa_flags | SA_SIGINFO ;
- act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &Handler ;
-#else
- act.sa_handler = (SIG_PFV) &Handler ;
-#endif
-
- //==== Always detected the signal "SIGFPE" =================================
- stat = sigaction(SIGFPE,&act,&oact); // ...... floating point exception
- if (stat) {
- cerr << "sigaction does not work !!! KO " << endl;
- perror("sigaction ");
- }
-
- //==== Detected the only the "free" signals ================================
- sigaction(SIGHUP,&act,&oact); // ...... hangup
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGHUP,&oact,&oact);
-#endif
-
- sigaction(SIGINT,&act,&oact); // ...... interrupt
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGINT,&oact,&oact);
-#endif
-
- sigaction(SIGQUIT,&act,&oact); // ...... quit
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGQUIT,&oact,&oact);
-#endif
-
- sigaction(SIGILL,&act,&oact); // ...... illegal instruction
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGILL,&oact,&oact);
-#endif
-
- sigaction(SIGBUS,&act,&oact); // ...... bus error
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGBUS,&oact,&oact);
-#endif
-
-#if (!defined (linux)) && (!defined(LININTEL))
- sigaction(SIGSYS,&act,&oact); // ...... bad argument to system call
-
-# ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGSYS,&oact,&oact);
-# endif
-#endif
-
-#if defined (__sgi) || defined(IRIX)
- sigaction(SIGTRAP,&act,&oact); // Integer Divide By Zero (IRIX)
-
-# ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGTRAP,&oact,&oact);
-# endif
-#endif
-
-#ifdef SA_SIGINFO
- act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
-#else
- act.sa_handler = (SIG_PFV) &SegvHandler ;
-#endif
-
- if ( sigaction( SIGSEGV , &act , &oact ) ) // ...... segmentation violation
- perror("OSD::SetSignal sigaction( SIGSEGV , &act , &oact ) ") ;
-
-#ifdef OBJS
- if(oact.sa_handler)
- sigaction(SIGSEGV,&oact,&oact);
-#endif
-#if defined(__osf__) || defined(DECOSF1)
- struct sigaction action, prev_action;
- action.sa_handler = SIG_IGN;
- action.sa_mask = 0;
- action.sa_flags = 0;
-
- if (sigaction (SIGFPE, &action, &prev_action) == -1) {
- perror ("sigaction");
- exit (1);
- }
-#endif
-
-}
-//============================================================================
-//==== Handler
+//==== Handler
//==== Catche the differents signals:
//==== 1- The Fatal signals, which cause the end of process:
//==== 2- The exceptions which are "signaled" by Raise.
//==== FPE_FLTOVF_TRAP // ..... [floating overflow]
//==== SIGSEGV is handled by "SegvHandler()"
//============================================================================
-
-
-void OSD::Handler(const OSD_Signals theSignal,
- const Standard_Address
#ifdef SA_SIGINFO
- theSigInfo
-#endif
- ,const Standard_Address
-#if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION)
- theContext
+static void Handler (const int theSignal, siginfo_t *theSigInfo, const Standard_Address theContext)
+#else
+static void Handler (const int theSignal)
#endif
- )
{
struct sigaction oldact, act;
-
// re-install the signal
-
if ( ! sigaction (theSignal, NULL, &oldact) ) {
- // cout << " signal is " << theSignal << " handler is " << oldact.sa_handler << endl;
- if (sigaction (theSignal, &oldact, &act)) perror ("sigaction");
+ // cout << " signal is " << theSignal << " handler is " << oldact.sa_handler << endl;
+ if (sigaction (theSignal, &oldact, &act)) perror ("sigaction");
+ }
+ else {
+ perror ("sigaction");
}
- else
- perror ("sigaction");
siginfo_t * aSigInfo = NULL;
#ifdef SA_SIGINFO
- aSigInfo = (siginfo_t *) theSigInfo;
+ aSigInfo = theSigInfo;
#endif
-#if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION)
-
-//#ifdef DEB
-// cout << " current thread " << pthread_self() << endl;
-//#endif
-
-
+#if defined(HAVE_PTHREAD_H) && defined(NO_CXX_EXCEPTION)
if (pthread_self() != getOCCThread() || !Standard_ErrorHandler::IsInTryBlock()) {
// use the previous signal handler
- // cout << "OSD::Handler: signal " << (int) theSignal << " occured outside a try block " << endl ;
-
+ // cout << "OSD::Handler: signal " << (int) theSignal << " occured outside a try block " << endl ;
struct sigaction *oldSignals = GetOldSigAction();
- struct sigaction asigacthandler = oldSignals[(int) theSignal];
-
+ struct sigaction asigacthandler = oldSignals[theSignal >= 0 && theSignal < NSIG ? theSignal : 0];
+
if (asigacthandler.sa_flags & SA_SIGINFO) {
void (*aCurInfoHandle)(int, siginfo_t *, void *) = asigacthandler.sa_sigaction;
if (aSigInfo) {
- switch (aSigInfo->si_signo) {
- case SIGFPE:
- {
+ switch (aSigInfo->si_signo) {
+ case SIGFPE:
+ {
#ifdef SOLARIS
- sigfpe_handler_type *aIEEEHandlerTab = GetOldFPE();
- sigfpe_handler_type aIEEEHandler = NULL;
-
- switch (aSigInfo->si_code) {
- case FPE_INTDIV_TRAP :
- case FPE_FLTDIV_TRAP :
- aIEEEHandler = aIEEEHandlerTab[1];
- break;
- case FPE_INTOVF_TRAP :
- case FPE_FLTOVF_TRAP :
- aIEEEHandler = aIEEEHandlerTab[2];
- break;
- case FPE_FLTUND_TRAP :
- aIEEEHandler = aIEEEHandlerTab[4];
- break;
- case FPE_FLTRES_TRAP:
- aIEEEHandler = aIEEEHandlerTab[3];
- break;
- case FPE_FLTINV_TRAP :
- aIEEEHandler = aIEEEHandlerTab[0];
- break;
- case FPE_FLTSUB_TRAP :
- default:
- break;
- }
- if (aIEEEHandler) {
- // cout << "OSD::Handler: calling previous IEEE signal handler with info" << endl ;
- void (*aFPEHandler)(int, siginfo_t *, void *) = (void(*)(int, siginfo*, void*)) aIEEEHandler;
- (*aFPEHandler) (theSignal, aSigInfo, theContext);
- return;
- }
-#endif
- }
- break;
- case SIGSEGV:
- switch (aSigInfo->si_code) {
- case SEGV_MAPERR:
- // cout << "OSD::Handler: SIGSEGV signal : address not mapped to object";
- break;
- case SEGV_ACCERR:
- // cout << "OSD::Handler: SIGSEGV signal : invalid permissions for mapped object";
- break;
- default:
- // cout << "OSD::Handler: SIGSEGV signal : unknown segv";
- break;
- }
- // cout << " at address " << (void *) aSigInfo->si_addr << endl;
- break;
- case SIGBUS:
- switch (aSigInfo->si_code) {
- case BUS_ADRALN:
- // cout << "OSD::Handler: SIGBUS signal : invalid address alignment";
- break;
- case BUS_ADRERR:
- // cout << "OSD::Handler: SIGBUS signal : non-existent physical address";
- break;
- case BUS_OBJERR:
- // cout << "OSD::Handler: SIGBUS signal : object specific hardware error";
- break;
- default:
- // cout << "OSD::Handler: SIGBUS signal : unknown sig bus";
- break;
- }
- // cout << " at " << (void *) aSigInfo->si_addr << endl;
- break;
- case SIGILL:
- // cout << "OSD::Handler: illegal instruction signal " << endl;
- break;
-#ifdef SIGSYS
- case SIGSYS:
- // cout << "OSD::Handler: bad argument to system call signal"<< endl ;
- break;
-#endif
- case SIGINT:
- // cout << "OSD::Handler: interrupt signal" << endl;
- break;
- default:
- break;
- }
+ sigfpe_handler_type *aIEEEHandlerTab = GetOldFPE();
+ sigfpe_handler_type aIEEEHandler = NULL;
+ switch (aSigInfo->si_code) {
+ case FPE_INTDIV_TRAP :
+ case FPE_FLTDIV_TRAP :
+ aIEEEHandler = aIEEEHandlerTab[1];
+ break;
+ case FPE_INTOVF_TRAP :
+ case FPE_FLTOVF_TRAP :
+ aIEEEHandler = aIEEEHandlerTab[2];
+ break;
+ case FPE_FLTUND_TRAP :
+ aIEEEHandler = aIEEEHandlerTab[4];
+ break;
+ case FPE_FLTRES_TRAP :
+ aIEEEHandler = aIEEEHandlerTab[3];
+ break;
+ case FPE_FLTINV_TRAP :
+ aIEEEHandler = aIEEEHandlerTab[0];
+ break;
+ case FPE_FLTSUB_TRAP :
+ default:
+ break;
+ }
+ if (aIEEEHandler) {
+ // cout << "OSD::Handler: calling previous IEEE signal handler with info" << endl ;
+ (*aIEEEHandler) (theSignal, aSigInfo, theContext);
+ return;
+ }
+#endif
+ break;
+ }
+ default:
+ break;
+ }
}
if (aCurInfoHandle) {
- // cout << "OSD::Handler: calling previous signal handler with info " << aCurInfoHandle << endl ;
- (*aCurInfoHandle) (theSignal, aSigInfo, theContext);
- cerr << " previous signal handler return" << endl ;
- return;
+ // cout << "OSD::Handler: calling previous signal handler with info " << aCurInfoHandle << endl ;
+ (*aCurInfoHandle) (theSignal, aSigInfo, theContext);
+ cerr << " previous signal handler return" << endl ;
+ return;
}
else {
// cout << "OSD::Handler: no handler with info for the signal" << endl;
}
- } else {
- // no siginfi needed for the signal
+ }
+ else {
+ // no siginfo needed for the signal
void (*aCurHandler) (int) = asigacthandler.sa_handler;
if(aCurHandler) {
- // cout << "OSD::Handler: calling previous signal handler" << endl ;
- (*aCurHandler) (theSignal);
- cerr << " previous signal handler return" << endl ;
- return;
- }
+ // cout << "OSD::Handler: calling previous signal handler" << endl ;
+ (*aCurHandler) (theSignal);
+ cerr << " previous signal handler return" << endl ;
+ return;
+ }
}
// cout << " Signal occured outside a try block, but no handler for it" <<endl;
return;
}
#endif
-
// cout << "OSD::Handler: signal " << (int) theSignal << " occured inside a try block " << endl ;
-
- if ( ADR_ACT_SIGIO_HANDLER != NULL ) (*ADR_ACT_SIGIO_HANDLER)() ;
-
+ if ( ADR_ACT_SIGIO_HANDLER != NULL )
+ (*ADR_ACT_SIGIO_HANDLER)() ;
#ifdef linux
if (fFltExceptions)
feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
//feenableexcept (FE_INVALID | FE_DIVBYZERO);
#endif
-
sigset_t set;
sigemptyset(&set);
-
- switch(theSignal) {
-
+ switch (theSignal) {
case SIGHUP:
OSD_SIGHUP::NewInstance("SIGHUP 'hangup' detected.")->Jump();
exit(SIGHUP);
break;
-
case SIGINT:
// For safe handling of Control-C as stop event, arm a variable but do not
// generate longjump (we are out of context anyway)
fCtrlBrk = Standard_True;
-// OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump();
-// exit(SIGINT);
+ // OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump();
+ // exit(SIGINT);
break;
-
case SIGQUIT:
OSD_SIGQUIT::NewInstance("SIGQUIT 'quit' detected.")->Jump();
exit(SIGQUIT);
break;
-
case SIGILL:
OSD_SIGILL::NewInstance("SIGILL 'illegal instruction' detected.")->Jump();
exit(SIGILL);
break;
-
case SIGKILL:
OSD_SIGKILL::NewInstance("SIGKILL 'kill' detected.")->Jump();
exit(SIGKILL);
break;
-
case SIGBUS:
sigaddset(&set, SIGBUS);
sigprocmask(SIG_UNBLOCK, &set, NULL) ;
OSD_SIGBUS::NewInstance("SIGBUS 'bus error' detected.")->Jump();
exit(SIGBUS);
break;
-
case SIGSEGV:
OSD_SIGSEGV::NewInstance("SIGSEGV 'segmentation violation' detected.")->Jump();
exit(SIGSEGV);
break;
-
#ifdef SIGSYS
case SIGSYS:
OSD_SIGSYS::NewInstance("SIGSYS 'bad argument to system call' detected.")->Jump();
exit(SIGSYS);
break;
#endif
-
- case SIGFPE:
- {
+ case SIGFPE:
sigaddset(&set, SIGFPE);
sigprocmask(SIG_UNBLOCK, &set, NULL) ;
#ifdef DECOSF1
-// Pour DEC/OSF1 SIGFPE = Division par zero.
-// should be clarified why in debug mode only?
+ // Pour DEC/OSF1 SIGFPE = Division par zero.
+ // should be clarified why in debug mode only?
#ifdef DEBUG
Standard_DivideByZero::NewInstance('')->Jump;
#endif
break;
-#endif
+#endif
#if (!defined (__sun)) && (!defined(SOLARIS))
Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump();
break;
#else
// Reste SOLARIS
- if (aSigInfo ) {
+ if (aSigInfo) {
switch(aSigInfo->si_code) {
case FPE_FLTDIV_TRAP :
- Standard_DivideByZero::NewInstance("Floating Divide By Zero")->Jump(); break;
+ Standard_DivideByZero::NewInstance("Floating Divide By Zero")->Jump();
+ break;
case FPE_INTDIV_TRAP :
- Standard_DivideByZero::NewInstance("Integer Divide By Zero")->Jump(); break;
+ Standard_DivideByZero::NewInstance("Integer Divide By Zero")->Jump();
+ break;
case FPE_FLTOVF_TRAP :
- Standard_Overflow::NewInstance("Floating Overflow")->Jump(); break;
+ Standard_Overflow::NewInstance("Floating Overflow")->Jump();
+ break;
case FPE_INTOVF_TRAP :
- Standard_Overflow::NewInstance("Integer Overflow")->Jump(); break;
+ Standard_Overflow::NewInstance("Integer Overflow")->Jump();
+ break;
case FPE_FLTUND_TRAP :
- Standard_NumericError::NewInstance("Floating Underflow")->Jump(); break;
+ Standard_NumericError::NewInstance("Floating Underflow")->Jump();
+ break;
case FPE_FLTRES_TRAP:
- Standard_NumericError::NewInstance("Floating Point Inexact Result")->Jump(); break;
+ Standard_NumericError::NewInstance("Floating Point Inexact Result")->Jump();
+ break;
case FPE_FLTINV_TRAP :
- Standard_NumericError::NewInstance("Invalid Floating Point Operation")->Jump(); break;
+ Standard_NumericError::NewInstance("Invalid Floating Point Operation")->Jump();
+ break;
default:
- Standard_NumericError::NewInstance("Numeric Error")->Jump(); break;
+ Standard_NumericError::NewInstance("Numeric Error")->Jump();
+ break;
}
- }
- else {
+ } else {
Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump();
}
#endif
break;
- }
#if defined (__sgi) || defined(IRIX)
- case SIGTRAP:
+ case SIGTRAP:
sigaddset(&set, SIGTRAP);
sigprocmask(SIG_UNBLOCK, &set, NULL) ;
Standard_DivideByZero::NewInstance("SIGTRAP IntegerDivideByZero")->Jump(); break;
#endif
default:
- cout << "Unexpected signal " << (Standard_Integer ) theSignal << endl ;
- }
-}
-
-//============================================================================
-//==== ControlBreak
-//============================================================================
-
-void OSD :: ControlBreak ()
-{
- if ( fCtrlBrk ) {
- fCtrlBrk = Standard_False;
- OSD_Exception_CTRL_BREAK::Raise ("*** INTERRUPT ***");
+ cout << "Unexpected signal " << theSignal << endl ;
+ break;
}
}
//============================================================================
-//==== SegvHandler
+//==== SegvHandler
//============================================================================
-
#ifdef SA_SIGINFO
-#ifdef NO_CXX_EXCEPTION
-void OSD::SegvHandler(const OSD_Signals theSig,
- const Standard_Address ip,
- const Standard_Address theContext)
+static void SegvHandler(const int theSignal,
+ siginfo_t *ip,
+ const Standard_Address theContext)
{
+#ifdef NO_CXX_EXCEPTION
if (!Standard_ErrorHandler::IsInTryBlock()) {
- Handler(theSig, ip, theContext);
+ Handler(theSignal, ip, theContext);
return;
}
-#else
-void OSD::SegvHandler(const OSD_Signals,
- const Standard_Address ip,
- const Standard_Address)
-{
#endif
-
#ifdef linux
if (fFltExceptions)
feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
//feenableexcept (FE_INVALID | FE_DIVBYZERO);
#endif
-
// cout << "OSD::SegvHandler activated(SA_SIGINFO)" << endl ;
if ( ip != NULL ) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
sigprocmask (SIG_UNBLOCK, &set, NULL) ;
- void *address = ((siginfo_t *)ip)->si_addr ;
+ void *address = ip->si_addr ;
if ( (((long) address )& ~0xffff) == (long) UndefinedHandleAddress ) {
- Standard_NullObject::NewInstance("Attempt to access to null object")->Jump();
- }
+ Standard_NullObject::NewInstance("Attempt to access to null object")->Jump();
+ }
else {
char Msg[100];
sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",
- (long ) address ) ;
+ (long ) address ) ;
OSD_SIGSEGV::NewInstance(Msg)->Jump();
}
- }
- else
+ }
+ else {
cout << "Wrong undefined address." << endl ;
+ }
exit(SIGSEGV);
}
-#if defined (_hpux) || defined(HPUX)
-//============================================================================
-//==== SegvHandler
-//============================================================================
-
+#elif defined (_hpux) || defined(HPUX)
// Not ACTIVE ? SA_SIGINFO is defined on SUN, OSF, SGI and HP (and Linux) !
// pour version 09.07
-void OSD::SegvHandler(const OSD_Signals aSig, const Standard_Address code,
- const Standard_Address scp)
-//void OSD::SegvHandler(const OSD_Signals aSig, int code, const Standard_Address scp)
+
+static void SegvHandler(const int theSignal,
+ siginfo_t *ip,
+ const Standard_Address theContext)
{
unsigned long Space ;
unsigned long Offset ;
char Msg[100] ;
- if ( scp != NULL ) {
- Space = ((struct sigcontext *)scp)->sc_sl.sl_ss.ss_cr20 ;
- Offset = ((struct sigcontext *)scp)->sc_sl.sl_ss.ss_cr21 ;
+ if ( theContext != NULL ) {
+ Space = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr20 ;
+ Offset = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr21 ;
// cout << "Wrong address = " << hex(Offset) << endl ;
- if ((Offset & ~0xffff) == (long)UndefinedHandleAddress)
- Standard_NullObject::Jump("Attempt to access to null object") ;
+ if ((Offset & ~0xffff) == (long)UndefinedHandleAddress) {
+ Standard_NullObject::Jump("Attempt to access to null object") ;
+ }
else {
- sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ;
- OSD_SIGSEGV::Jump(Msg);
+ sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ;
+ OSD_SIGSEGV::Jump(Msg);
// scp->sc_pcoq_head = scp->sc_pcoq_tail ; Permettrait de continuer a
// scp->sc_pcoq_tail = scp->sc_pcoq_tail + 0x4 ; l'intruction suivant le segv.
}
}
- else
+ else {
cout << "Wrong undefined address." << endl ;
+ }
exit(SIGSEGV);
-}
+}
+
+#endif
+
+//============================================================================
+//==== SetSignal
+//==== Set the differents signals:
+//============================================================================
+
+void OSD::SetSignal(const Standard_Boolean aFloatingSignal)
+{
+ static int first_time = 3 ;
+ struct sigaction act, oact;
+ int stat = 0;
+
+ if( aFloatingSignal ) {
+ //==== Enable the floating point exceptions ===============
+#if defined (__sun) || defined (SOLARIS)
+ sigfpe_handler_type PHandler = (sigfpe_handler_type) Handler ;
+ stat = ieee_handler("set", "invalid", PHandler);
+ stat = ieee_handler("set", "division", PHandler) || stat;
+ stat = ieee_handler("set", "overflow", PHandler) || stat;
+
+ //stat = ieee_handler("set", "underflow", PHandler) || stat;
+ //stat = ieee_handler("set", "inexact", PHandler) || stat;
+
+ if (stat) {
+ cerr << "ieee_handler does not work !!! KO " << endl;
+ }
+#elif defined (linux)
+ feenableexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
+ //feenableexcept (FE_INVALID | FE_DIVBYZERO);
+ fFltExceptions = Standard_True;
+#endif
+ }
+ else if ( first_time & 1 ) {
+// cout << "SetSignal( Standard_False ) is not implemented..." << endl ;
+ first_time = first_time & (~ 1) ;
+ }
+
+#if defined (sgi) || defined (IRIX )
+ if ( first_time & 2 ) {
+ char *TRAP_FPE = getenv("TRAP_FPE") ;
+ if ( TRAP_FPE == NULL ) {
+ cout << "On SGI you must set TRAP_FPE environment variable : " << endl ;
+ cout << "set env(TRAP_FPE) \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\" or" << endl ;
+ cout << "setenv TRAP_FPE \"UNDERFL=FLUSH_ZERO;OVERFL=DEFAULT;DIVZERO=DEFAULT;INT_OVERFL=DEFAULT\"" << endl ;
+// exit(1) ;
+ first_time = first_time & (~ 2) ;
+ }
+ }
+#endif
+
+ //==== Save the old Signal Handler, and set the new one ===================
+
+ sigemptyset(&act.sa_mask) ;
+
+#ifdef SA_RESTART
+ act.sa_flags = SA_RESTART ;
+#else
+ act.sa_flags = 0 ;
+#endif
+#ifdef SA_SIGINFO
+ act.sa_flags = act.sa_flags | SA_SIGINFO ;
+ act.sa_sigaction = /*(void(*)(int, siginfo_t *, void*))*/ Handler;
+#else
+ act.sa_handler = /*(SIG_PFV)*/ Handler;
+#endif
+ //==== Always detected the signal "SIGFPE" =================================
+ stat = sigaction(SIGFPE,&act,&oact); // ...... floating point exception
+ if (stat) {
+ cerr << "sigaction does not work !!! KO " << endl;
+ perror("sigaction ");
+ }
+
+ //==== Detected the only the "free" signals ================================
+ sigaction(SIGHUP,&act,&oact); // ...... hangup
+
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGHUP,&oact,&oact);
+#endif
+
+ sigaction(SIGINT,&act,&oact); // ...... interrupt
+
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGINT,&oact,&oact);
#endif
+
+ sigaction(SIGQUIT,&act,&oact); // ...... quit
+
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGQUIT,&oact,&oact);
+#endif
+
+ sigaction(SIGILL,&act,&oact); // ...... illegal instruction
+
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGILL,&oact,&oact);
+#endif
+
+ sigaction(SIGBUS,&act,&oact); // ...... bus error
+
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGBUS,&oact,&oact);
+#endif
+
+#if (!defined (linux)) && (!defined(LININTEL))
+ sigaction(SIGSYS,&act,&oact); // ...... bad argument to system call
+
+# ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGSYS,&oact,&oact);
+# endif
+#endif
+
+#if defined (__sgi) || defined(IRIX)
+ sigaction(SIGTRAP,&act,&oact); // Integer Divide By Zero (IRIX)
+
+# ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGTRAP,&oact,&oact);
+# endif
+#endif
+
+#ifdef SA_SIGINFO
+ act.sa_sigaction = /*(void(*)(int, siginfo_t *, void*))*/ SegvHandler;
#else
-// Must be there for compatibility with Windows NT system ---------------
+ act.sa_handler = /*(SIG_PFV)*/ SegvHandler;
+#endif
-Standard_Integer OSD :: WntHandler ( const Standard_Address )
- {return 0 ;}
+ if ( sigaction( SIGSEGV , &act , &oact ) ) // ...... segmentation violation
+ perror("OSD::SetSignal sigaction( SIGSEGV , &act , &oact ) ") ;
+#ifdef OBJS
+ if(oact.sa_handler)
+ sigaction(SIGSEGV,&oact,&oact);
+#endif
+#if defined(__osf__) || defined(DECOSF1)
+ struct sigaction action, prev_action;
+ action.sa_handler = SIG_IGN;
+ action.sa_mask = 0;
+ action.sa_flags = 0;
+
+ if (sigaction (SIGFPE, &action, &prev_action) == -1) {
+ perror ("sigaction");
+ exit (1);
+ }
#endif
+
+}
+
+//============================================================================
+//==== ControlBreak
+//============================================================================
+
+void OSD :: ControlBreak ()
+{
+ if ( fCtrlBrk ) {
+ fCtrlBrk = Standard_False;
+ OSD_Exception_CTRL_BREAK::Raise ("*** INTERRUPT ***");
+ }
+}
+
#endif
Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
switch( signum ) {
case SIGFPE :
- if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
- cout << "signal error" << endl ;
- switch( sub_code ) {
- case _FPE_INVALID :
- CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ;
- break ;
- case _FPE_DENORMAL :
- CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ;
- break ;
- case _FPE_ZERODIVIDE :
- CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ;
- break ;
- case _FPE_OVERFLOW :
- CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ;
- break ;
- case _FPE_UNDERFLOW :
- CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ;
- break ;
- case _FPE_INEXACT :
- CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ;
- break ;
- default:
- cout << "SIGWntHandler(default) -> Standard_NumericError::Raise(\"Floating Point Error\");"
- << endl ;
- Standard_NumericError::Raise("Floating Point Error");
- break ;
- }
- break ;
- case SIGSEGV :
- if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
- cout << "signal error" << endl ;
- CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ;
- break ;
+ if ( signal( signum , (void(*)(int))SIGWntHandler ) == SIG_ERR )
+ cout << "signal error" << endl ;
+ switch( sub_code ) {
+ case _FPE_INVALID :
+ CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ;
+ break ;
+ case _FPE_DENORMAL :
+ CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ;
+ break ;
+ case _FPE_ZERODIVIDE :
+ CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ;
+ break ;
+ case _FPE_OVERFLOW :
+ CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ;
+ break ;
+ case _FPE_UNDERFLOW :
+ CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ;
+ break ;
+ case _FPE_INEXACT :
+ CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ;
+ break ;
+ default:
+ cout << "SIGWntHandler(default) -> Standard_NumericError::Raise(\"Floating Point Error\");" << endl;
+ Standard_NumericError::Raise("Floating Point Error");
+ break ;
+ }
+ break ;
+ case SIGSEGV :
+ if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
+ cout << "signal error" << endl ;
+ CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ;
+ break ;
case SIGILL :
- if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
- cout << "signal error" << endl ;
- CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ;
- break ;
- default:
- cout << "SIGWntHandler unexpected signal : "
- << signum << endl ;
- break ;
- }
+ if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
+ cout << "signal error" << endl ;
+ CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ;
+ break ;
+ default:
+ cout << "SIGWntHandler unexpected signal : " << signum << endl ;
+ break ;
+ }
DebugBreak ();
#endif
}
-//=======================================================================
-//function : WntHandler
-//purpose : Will be used when user's code is compiled with /EHs
-// option and unless user sets his own exception handler with
-// ::SetUnhandledExceptionFilter().
-//=======================================================================
-Standard_Integer OSD::WntHandler (const Standard_Address theExceptionInfo)
-{
- LPEXCEPTION_POINTERS lpXP = (LPEXCEPTION_POINTERS )theExceptionInfo;
- DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
-
- return CallHandler (dwExceptionCode,
- lpXP->ExceptionRecord->ExceptionInformation[1],
- lpXP->ExceptionRecord->ExceptionInformation[0]);
-}
-
//=======================================================================
//function : TranslateSE
//purpose : Translate Structural Exceptions into C++ exceptions
CallHandler(theCode, info1, info0);
}
#endif
+//=======================================================================
+//function : WntHandler
+//purpose : Will be used when user's code is compiled with /EHs
+// option and unless user sets his own exception handler with
+// ::SetUnhandledExceptionFilter().
+//=======================================================================
+static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
+{
+ DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
+ return CallHandler (dwExceptionCode,
+ lpXP->ExceptionRecord->ExceptionInformation[1],
+ lpXP->ExceptionRecord->ExceptionInformation[0]);
+}
//=======================================================================
//function : SetSignal
//purpose :
// when user's code is compiled with /EHs
// Replaces the existing top-level exception filter for all existing and all future threads
// in the calling process
- aPreviousFilter = ::SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER )&OSD::WntHandler);
+ aPreviousFilter = ::SetUnhandledExceptionFilter (/*(LPTOP_LEVEL_EXCEPTION_FILTER)*/ WntHandler);
// Signal handlers will only be used when the method ::raise() will be used
// Handlers must be set for every thread
- if (signal (SIGSEGV, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
+ if (signal (SIGSEGV, (void(*)(int))SIGWntHandler) == SIG_ERR)
cout << "signal(OSD::SetSignal) error\n";
- if (signal (SIGFPE, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
+ if (signal (SIGFPE, (void(*)(int))SIGWntHandler) == SIG_ERR)
cout << "signal(OSD::SetSignal) error\n";
- if (signal (SIGILL, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
+ if (signal (SIGILL, (void(*)(int))SIGWntHandler) == SIG_ERR)
cout << "signal(OSD::SetSignal) error\n";
// Set Ctrl-C and Ctrl-Break handler
#undef __finally
#undef __leave
#endif
-
-// Must be there for compatibility with UNIX system code ----------------------
-
-//void OSD::Handler(const OSD_Signals aSig,
-// const OSD_Signals aCode){}
-void OSD::Handler(const OSD_Signals /*theSignal*/,
- const Standard_Address /*theSigInfo*/,
- const Standard_Address /*theContext*/) {}
-
-void OSD::SegvHandler(const OSD_Signals /*aSig*/,
- const Standard_Address /*code*/,
- const Standard_Address /*scp*/){}
-
#endif // WNT