From 89c4bca8462bbb29736c6322883cade064109a33 Mon Sep 17 00:00:00 2001 From: ski Date: Thu, 28 Nov 2013 18:10:25 +0400 Subject: [PATCH] 0024304: Eliminate GCC compiler warning about exceeding maximum value for type in case label Methods OSD::Handler(), OSD::SegvHandler(), OSD::WntHandler() were made static Type cast were removed when pointer on signal handler function is used Enumeration OSD_Signal removed --- src/OSD/OSD.cdl | 116 ------- src/OSD/OSD.cxx | 2 +- src/OSD/OSD_signal.cxx | 647 ++++++++++++++++--------------------- src/OSD/OSD_signal_WNT.cxx | 132 ++++---- 4 files changed, 343 insertions(+), 554 deletions(-) diff --git a/src/OSD/OSD.cdl b/src/OSD/OSD.cdl index 5482440aeb..0514489376 100755 --- a/src/OSD/OSD.cdl +++ b/src/OSD/OSD.cdl @@ -190,28 +190,6 @@ is 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 ) -- ---------------------------------------- @@ -238,100 +216,6 @@ is 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. diff --git a/src/OSD/OSD.cxx b/src/OSD/OSD.cxx index a6a913de8c..6e046126a2 100755 --- a/src/OSD/OSD.cxx +++ b/src/OSD/OSD.cxx @@ -18,7 +18,7 @@ #include - +#include #include #include #if HAVE_IEEEFP_H diff --git a/src/OSD/OSD_signal.cxx b/src/OSD/OSD_signal.cxx index 73d3a8866d..bd7d5ab8c0 100755 --- a/src/OSD/OSD_signal.cxx +++ b/src/OSD/OSD_signal.cxx @@ -144,159 +144,8 @@ static sigfpe_handler_type *GetOldFPE() #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. @@ -314,378 +163,452 @@ void OSD::SetSignal(const Standard_Boolean aFloatingSignal) //==== 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" <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 diff --git a/src/OSD/OSD_signal_WNT.cxx b/src/OSD/OSD_signal_WNT.cxx index 8f526d25f2..32df473568 100755 --- a/src/OSD/OSD_signal_WNT.cxx +++ b/src/OSD/OSD_signal_WNT.cxx @@ -272,69 +272,51 @@ static void SIGWntHandler (int signum, int sub_code) 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 @@ -360,7 +342,20 @@ static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr ) 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 : @@ -387,15 +382,15 @@ void OSD::SetSignal (const Standard_Boolean theFloatingSignal) // 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 @@ -616,17 +611,4 @@ LONG _osd_debug ( void ) { #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 -- 2.20.1