diff --git a/src/OSD/OSD.cdl b/src/OSD/OSD.cdl index 85f08da49f..7235c416ee 100755 --- a/src/OSD/OSD.cdl +++ b/src/OSD/OSD.cdl @@ -28,17 +28,17 @@ package OSD -- 2.0 -- 3.0 -- Windows NT 30/09/96 ( EUG ) - ---Purpose: Set of Operating Sytem Dependent Tools + ---Purpose: Set of Operating Sytem Dependent Tools -- (O)perating (S)ystem (D)ependent -uses +uses - Standard , - Quantity , + Standard , + Quantity , TCollection is - + exception OSDError inherits Failure from Standard ; imported Function; @@ -51,7 +51,7 @@ is ---Purpose: This is set of possible machine types -- used in OSD_Host::MachineType - enumeration SysType is Unknown,Default,UnixBSD, UnixSystemV, VMS, OS2, + enumeration SysType is Unknown,Default,UnixBSD, UnixSystemV, VMS, OS2, OSF, MacOs, Taligent, WindowsNT, LinuxREDHAT,Aix; ---Purpose: Thisd is a set of possible system types. -- 'Default' means SysType of machine operating this process. @@ -59,7 +59,7 @@ is -- All UNIX-like are grouped under "UnixBSD" or "UnixSystemV". -- Such systems are Solaris, NexTOS ... -- A category of systems accept MSDOS-like path such as - -- WindowsNT and OS2. + -- WindowsNT and OS2. enumeration FromWhere is FromBeginning, FromHere, FromEnd; ---Purpose: Used by OSD_File in the method Seek. @@ -70,7 +70,7 @@ is -- -- ReadLock allows only one reading of the file at a time. -- - -- WriteLock prevents others writing into a file(excepted the user + -- WriteLock prevents others writing into a file(excepted the user -- who puts the lock)but allows everybody to read. -- -- ExclusiveLock prevents reading and writing except for the @@ -94,8 +94,8 @@ is enumeration KindFile is FILE, DIRECTORY, LINK, SOCKET, UNKNOWN; ---Purpose: Specifies the type of files. - private enumeration WhoAmI is WDirectory, WDirectoryIterator, - WEnvironment, WFile, WFileNode, WFileIterator, WMailBox, + private enumeration WhoAmI is WDirectory, WDirectoryIterator, + WEnvironment, WFile, WFileNode, WFileIterator, WMailBox, WPath, WProcess, WProtection, WSemaphore, WHost, WDisk, WChronometer, WSharedMemory, WTimer, WPackage, WPrinter, WEnvironmentIterator; @@ -109,7 +109,7 @@ is class Protection; ---Purpose: Gets and sets protection attributes of 'system , user , -- group, and world'. - + class Path; ---Purpose: Manages independent system path translation. @@ -132,7 +132,7 @@ is ---Purpose: Searches sub-directories in current directory. class Chronometer; - ---Purpose: Measures time elapsed for performance program tests. + ---Purpose: Measures time elapsed for performance program tests. -- Measures CPU time consumed by a method call. class Timer; @@ -155,17 +155,17 @@ is ---Purpose: Process specific oriented tools class SharedMemory; - ---Purpose: Manages shared memory. + ---Purpose: Manages shared memory. class Semaphore; ---Purpose: Manages semaphores. - + -- class Mutex is alias Mutex from Standard; ---Purpose: Mutex object to synchronize threads within one process - + class MailBox; ---Purpose: Manages asynchronous mail boxes. - + class SharedLibrary; ---Purpose: Provides tools to load a shared library -- and retrieve the address of an entry point. @@ -177,11 +177,11 @@ is ---Purpose: A tool to manage threads class Real2String; - ---Purpose: Convertion of CString to Real and reciprocally + ---Purpose: Convertion of CString to Real and reciprocally class Localizer; ---Purpose: Manages locale. - + ----------------------------------------------- -- UNIX specific exceptions and enumeration -- @@ -196,12 +196,12 @@ is exception SIGBUS inherits Signal; exception SIGSEGV inherits Signal; exception SIGSYS inherits Signal; - + enumeration Signals is ---purpose: -- The "posix" signals. - -- + -- S_SIGHUP, -- "hangup." S_SIGINT, -- "interrupt." S_SIGQUIT, -- "quit." @@ -218,13 +218,13 @@ is S_FPE_FLTUND_TRAP, -- "floating underflow." S_FPE_FLTINEX_TRAP -- "floating inexact result." end Signals; - + ---------------------------------------- -- Exceptions ( Windows NT specific ) -- ---------------------------------------- exception Exception inherits Failure from Standard; - + exception Exception_ACCESS_VIOLATION inherits Exception; exception Exception_ARRAY_BOUNDS_EXCEEDED inherits Exception; exception Exception_FLT_DENORMAL_OPERAND inherits Exception; @@ -249,35 +249,35 @@ is -- Handler and SegvHandler (UNIX specific ) -- ---------------------------------------------- - -- - -- Handler(aSignal: Signals; aCode: Signals) - -- - - Handler(aSignal: Signals; aSigInfo: Address; aContext: Address) + -- + -- 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 + -- 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, + DivideByZero, Overflow, Underflow, SIGHUP, @@ -338,42 +338,77 @@ is -- 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(aFloatingSignal: Boolean = Standard_True); + + SetSignal(theFloatingSignal: Boolean = Standard_True); ---Purpose: - -- 1) Arms some floating point signals, and sets a "Handler" for them. - -- 2) Sets a "Handler" for the "Hardware" signals. - -- For Win32 users: under VC++ you can control which method of handling - -- exceptions is used by means of UseSETranslator method before calling - -- SetSignal + -- Sets signal and exception handlers. + -- Windows-specific notes<\b> + -- Compiled with MS VC++ sets 3 main handlers: + -- @li Signal handlers (via ::signal() functions) that translate system signals + -- (SIGSEGV, SIGFPE, SIGILL) into C++ exceptions (classes inheriting + -- Standard_Failure). They only be called if user calls ::raise() function + -- with one of supported signal type set. + -- @li Exception handler OSD::WntHandler() (via ::SetUnhandledExceptionFilter()) + -- that will be used when user's code is compiled with /EHs option. + -- @li Structured exception (SE) translator (via _set_se_translator()) that + -- translates SE exceptions (aka asynchronous exceptions) into the + -- C++ exceptions inheriting Standard_Failure. This translator will be + -- used when user's code is compiled with /EHa option. + -- . + -- This approach ensures that regardless of the option the user chooses to + -- compile his code with (/EHs or /EHa), signals (or SE exceptions) will be + -- translated into Open CASCADE C++ exceptions. + -- . + -- If @a theFloatingSignal is TRUE then floating point exceptions will be + -- generated in accordance with the mask + -- _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW<\tt> that is + -- used to call ::_controlfp() system function. If @a theFloatingSignal is FALSE + -- corresponding operations (e.g. division by zero) will gracefully complete + -- without an exception. + -- . + -- Unix-specific notes<\b> + -- OSD::SetSignal() sets handlers (via ::sigaction()) for multiple signals + -- (SIGFPE, SIGSEGV, etc). Currently the number of handled signals is much + -- greater than for Windows, in the future this may change to provide better + -- consistency with Windows. + -- . + -- @a theFloatingSignal is recognized on Sun Solaris, Linux, and SGI Irix to + -- generate floating-point exception according to the mask + -- FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW (in Linux conventions).
+ -- When compiled with OBJS macro defined, already set signal handlers (e.g. + -- by Data Base Managers) are not redefined. + -- . + -- Common notes<\b> + -- If OSD::SetSignal() method is used in at least one thread, it must also be + -- called in any other thread where Open CASCADE will be used, to ensure + -- consistency of behavior. Its @a aFloatingSignal argument must be consistent + -- across threads. + -- . + -- Keep in mind that whether the C++ exception will really be thrown (i.e. + -- ::throw() will be called) is regulated by the NO_CXX_EXCEPTIONS and + -- OCC_CONVERT_SIGNALS macros used during compilation of Open CASCADE and + -- user's code. Refer to Foundation Classes User's Guide for further details. -- - -- Warning: - -- Some "Data Base Managers" use their own "Handler" for the signals - -- such as "SIGSEGV". So if a "Handler" is set for a signal it will - -- not be replaced by Standard "Handler". It is managed by OBJS - -- preprocessor definition. - -- - ---Level: Internal AvailableMemory returns Integer from Standard; ---Purpose: Returns available memory in Kilobytes. ---Level: Advanced - + SecSleep(aDelay: Integer from Standard); ---Purpose: Commands the process to sleep for a number of seconds. - ---Level: Public + ---Level: Public MilliSecSleep(aDelay: Integer from Standard); ---Purpose: Commands the process to sleep for a number of milliseconds - ---Level: Public + ---Level: Public - RealToCString(aReal: Real; aString:out PCharacter) + RealToCString(aReal: Real; aString:out PCharacter) returns Boolean ; ---Purpose: -- Converts aReal into aCstring in exponential format with a period as -- decimal point, no thousand separator and no grouping of digits. -- The conversion is independant from the current locale - ---Level: Public + ---Level: Public CStringToReal(aString: CString; aReal: out Real) returns Boolean ; ---Purpose: @@ -381,46 +416,31 @@ is -- decimal point, no thousand separator and no grouping of digits -- into aReal . -- The conversion is independant from the current locale. - ---Level: Public + ---Level: Public IsDivisible(aDividend, aDivisor: Real from Standard) returns Boolean from Standard; ---Purpose: Tests if the quotient theDividend/theDivisor -- does not overflow - ---Level: Public - + ---Level: Public + GetExponent(aReal: Real from Standard) returns Integer from Standard; ---Purpose: Returns the exponent in base 2 of a floating-point number. - ---Level: Public - + ---Level: Public + GetMantissa(aReal: Real from Standard) returns Real from Standard; ---Purpose: Returns the mantissa of a floating-point number. - ---Level: Public - + ---Level: Public + ------------------------- -- Windows NT specific -- ------------------------- - + ControlBreak raises Exception_CTRL_BREAK; ---Purpose: since Windows NT does not support 'SIGINT' signal like UNIX, -- then this method checks whether Ctrl-Break keystroke was or -- not. If yes then raises Exception_CTRL_BREAK. - UseSETranslator(useSE : Boolean); - ---Purpose: Defines whether SetSignal must use _se_translator_function or - -- SetUnhandledExceptionFilter and signal to catch system - -- exceptions. The default behaviour is to use SE translator. - -- Warning: Using SE translator method SetSignal should be called for each - -- new created thread, while using the alternative method - -- the exception handler is established once for the whole - -- process and all its threads. - -- This function takes effect only under VC++ compiler. - - UseSETranslator returns Boolean; - ---Purpose: Returns the current value of the flag set by above method. - end OSD; - - diff --git a/src/OSD/OSD_signal_WNT.cxx b/src/OSD/OSD_signal_WNT.cxx index 396aad4388..f49c663410 100755 --- a/src/OSD/OSD_signal_WNT.cxx +++ b/src/OSD/OSD_signal_WNT.cxx @@ -18,13 +18,6 @@ #include -static Standard_Boolean fSETranslator = -#ifdef _MSC_VER - Standard_True; -#else - Standard_False; -#endif - #ifdef WNT //---------------------------- Windows NT System -------------------------------- @@ -53,6 +46,7 @@ static Standard_Boolean fSETranslator = #include #include #include +#include #include @@ -70,14 +64,16 @@ static Standard_Boolean fFltExceptions; static Standard_Boolean fDbgLoaded; static Standard_Boolean fCtrlBrk; +// used to forbid simultaneous execution of setting / executing handlers +static Standard_Mutex THE_SIGNAL_MUTEX; + static LONG __fastcall _osd_raise ( DWORD, LPTSTR ); static BOOL WINAPI _osd_ctrl_break_handler ( DWORD ); extern "C" Standard_EXPORT LONG _osd_debug ( void ); -extern "C" Standard_EXPORT void _debug_break ( Standard_PCharacter ); MB_DESC fatalErrorDesc[] = { - + { MBT_ICON, ( int )IDI_HAND }, { MBT_BUTTON, IDYES, TEXT( "Continue" ) }, { MBT_BUTTON, IDNO, TEXT( "Debugger" ) }, @@ -85,104 +81,21 @@ MB_DESC fatalErrorDesc[] = { }; -static LONG CallHandler (DWORD, ptrdiff_t, ptrdiff_t); -static void SIGWntHandler (int, int); - - //# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW ) # define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW ) -//============================================================================ -//==== WntHandler -//============================================================================ - -Standard_Integer OSD :: WntHandler ( const Standard_Address exceptionInfo ) -{ - - LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )exceptionInfo; - DWORD dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode; - -// cout << "WntHandler " << dwExceptionCode << " " << lpXP->ExceptionRecord->ExceptionInformation[1] -// << " " <ExceptionRecord->ExceptionInformation[0] << endl ; - - return CallHandler( dwExceptionCode , - lpXP -> ExceptionRecord -> ExceptionInformation[ 1 ] , - lpXP -> ExceptionRecord -> ExceptionInformation[ 0 ] ) ; - -} - -//============================================================================ -//==== SIGWntHandler -//============================================================================ - -static void SIGWntHandler(int signum , int sub_code ) { - -#if !defined(__CYGWIN32__) && !defined(__MINGW32__) - -// cout << "SIGWntHandler " << signum << " subcode " << sub_code << endl ; - 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 ; - 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 ; - } -// cout << "return from SIGWntHandler -> DebugBreak " << endl ; - DebugBreak (); - -#endif - -} - -//============================================================================ -//==== CallHandler -//============================================================================ - -static LONG CallHandler (DWORD dwExceptionCode , - ptrdiff_t ExceptionInformation1 , - ptrdiff_t ExceptionInformation0) +//======================================================================= +//function : CallHandler +//purpose : +//======================================================================= +static LONG CallHandler (DWORD dwExceptionCode, + ptrdiff_t ExceptionInformation1, + ptrdiff_t ExceptionInformation0) { #if !defined(__CYGWIN32__) && !defined(__MINGW32__) + Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling static TCHAR buffer[ 2048 ]; int flterr = 0; @@ -318,6 +231,10 @@ static LONG CallHandler (DWORD dwExceptionCode , if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) { + // reset FP operations before message box, otherwise it may fail to show up + _fpreset(); + _clearfp(); + MessageBeep ( MB_ICONHAND ); int msgID = MsgBox ( NULL, buffer, TEXT( "Error detected" ), 4, fatalErrorDesc ); // cout << "flterr" << flterr << " fFltExceptions " << fFltExceptions << endl ; @@ -360,23 +277,104 @@ static LONG CallHandler (DWORD dwExceptionCode , // cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ; } } - return _osd_raise ( dwExceptionCode, buffer ); - #else return 0; #endif +} -} // end OSD :: WntHandler +//======================================================================= +//function : SIGWntHandler +//purpose : Will only be used if user calls ::raise() function with +// signal type set in OSD::SetSignal() - SIGSEGV, SIGFPE, SIGILL +// (the latter will likely be removed in the future) +//======================================================================= +static void SIGWntHandler (int signum, int sub_code) +{ +#if !defined(__CYGWIN32__) && !defined(__MINGW32__) + 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 ; + 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 ; + } + 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 +// Will be used when user's code is compiled with /EHa option //======================================================================= - #ifdef _MSC_VER + +// If this file compiled with the default MSVC options for exception +// handling (/GX or /EHsc) then the following warning is issued: +// warning C4535: calling _set_se_translator() requires /EHa +// However it is correctly inserted and used when user's code compiled with /EHa. +// So, here we disable the warning. +#pragma warning (disable:4535) + static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr ) { + Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling ptrdiff_t info1 = 0, info0 = 0; if ( theExcPtr ) { info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1]; @@ -386,87 +384,60 @@ static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr ) } #endif -//============================================================================ -//==== SetSignal -//============================================================================ - -#ifdef _MSC_VER -// MSV 31.08.2005 -// If we compile this file under MSVC 7.1 with the default options for -// exception handling (/GX or /EHsc) then the following warning is issued: -// warning C4535: calling _set_se_translator() requires /EHa -// Till now all worked with the default options, and there was no difference -// found in exception handling behaviour between /EHa and /EHs options. -// So, here we disable the warning, and leave the default compiler options. -// If some reason appears to turn to /EHa option this pragma can be removed. -#pragma warning (disable:4535) -#endif - -void OSD :: SetSignal ( const Standard_Boolean aFloatingSignal ) { - +//======================================================================= +//function : SetSignal +//purpose : +//======================================================================= +void OSD::SetSignal (const Standard_Boolean theFloatingSignal) +{ #if !defined(__CYGWIN32__) && !defined(__MINGW32__) + Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling + LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter; - static int first_time = 1 ; - LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter ; + OSD_Environment env (TEXT("CSF_DEBUG_MODE")); + TCollection_AsciiString val = env.Value(); + if (!env.Failed()) + { + cout << "Environment variable CSF_DEBUG_MODE setted.\n"; + fMsgBox = Standard_True; + } + else + { + fMsgBox = Standard_False; + } - if ( first_time ) { -// OSD_Environment env ( TEXT( "CSF_EXCEPTION_PROMPT" ) ); - OSD_Environment env ( TEXT( "CSF_DEBUG_MODE" ) ); - TCollection_AsciiString val; + // Set exception handler (ignored when running under debugger). It will be used in most cases + // 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); - val = env.Value (); + // 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) + cout << "signal(OSD::SetSignal) error\n"; + if (signal (SIGFPE, (void (*)(int ) )&SIGWntHandler) == SIG_ERR) + cout << "signal(OSD::SetSignal) error\n"; + if (signal (SIGILL, (void (*)(int ) )&SIGWntHandler) == SIG_ERR) + cout << "signal(OSD::SetSignal) error\n"; - if ( !env.Failed () ) { - cout << "Environment variable CSF_DEBUG_MODE setted." << endl ; - fMsgBox = Standard_True; - } - else { -// cout << "Environment variable CSF_DEBUG_MODE not setted." << endl ; - fMsgBox = Standard_False; - } - - if (!fSETranslator) { - aPreviousFilter = - SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER)&OSD::WntHandler); -// cout << "SetUnhandledExceptionFilter previous filer : " << hex << aPreviousFilter << dec << endl ; - - if ( signal( SIGSEGV , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) - cout << "signal(OSD::SetSignal) error" << endl ; - if ( signal( SIGFPE , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) - cout << "signal(OSD::SetSignal) error" << endl ; - if ( signal( SIGILL , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) - cout << "signal(OSD::SetSignal) error" << endl ; - } - - fCtrlBrk = Standard_False; - SetConsoleCtrlHandler ( &_osd_ctrl_break_handler, TRUE ); - } + // Set Ctrl-C and Ctrl-Break handler + fCtrlBrk = Standard_False; + SetConsoleCtrlHandler (&_osd_ctrl_break_handler, TRUE); #ifdef _MSC_VER - if (fSETranslator) { - // use Structural Exception translator (one per thread) - _se_translator_function pOldSeFunc = _set_se_translator( TranslateSE ); - } + _se_translator_function pOldSeFunc = _set_se_translator (TranslateSE); #endif - fFltExceptions = aFloatingSignal; - if ( aFloatingSignal ) { - _controlfp ( 0, _OSD_FPX ); // JR add : - if ( first_time ) { -// cout << "SetSignal with floating point traps : " << hex << _controlfp(0,0) << dec << endl ; - first_time = 0 ; - } - } - else { - _controlfp ( _OSD_FPX , _OSD_FPX ); // JR add : - if ( first_time ) { -// cout << "SetSignal without floating point traps : " << hex << _controlfp(0,0) << dec << endl ; - first_time = 0 ; - } - } - + fFltExceptions = theFloatingSignal; + if (theFloatingSignal) + { + _controlfp (0, _OSD_FPX); // JR add : + } + else { + _controlfp (_OSD_FPX, _OSD_FPX); // JR add : + } #endif - } // end OSD :: SetSignal //============================================================================ @@ -509,73 +480,64 @@ static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) { static LONG __fastcall _osd_raise ( DWORD dwCode, LPTSTR msg ) { - if ( msg[ 0 ] == TEXT( '\x03' ) ) ++msg; - - switch ( dwCode ) { - - case EXCEPTION_ACCESS_VIOLATION: - - OSD_Exception_ACCESS_VIOLATION :: Raise ( msg ); - - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - - OSD_Exception_ARRAY_BOUNDS_EXCEEDED :: Raise ( msg ); - - case EXCEPTION_DATATYPE_MISALIGNMENT: - - Standard_ProgramError :: Raise ( msg ); - - case EXCEPTION_ILLEGAL_INSTRUCTION: - - OSD_Exception_ILLEGAL_INSTRUCTION :: Raise ( msg ); - - case EXCEPTION_IN_PAGE_ERROR: - - OSD_Exception_IN_PAGE_ERROR :: Raise ( msg ); - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - - Standard_DivideByZero :: Raise ( msg ); - - case EXCEPTION_INT_OVERFLOW: - - OSD_Exception_INT_OVERFLOW :: Raise ( msg ); - - case EXCEPTION_INVALID_DISPOSITION: - - OSD_Exception_INVALID_DISPOSITION :: Raise ( msg ); - - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - - OSD_Exception_NONCONTINUABLE_EXCEPTION :: Raise ( msg ); - - case EXCEPTION_PRIV_INSTRUCTION: - - OSD_Exception_PRIV_INSTRUCTION :: Raise ( msg ); - - case EXCEPTION_STACK_OVERFLOW: - - OSD_Exception_STACK_OVERFLOW :: Raise ( msg ); - - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - Standard_DivideByZero :: Raise ( msg ); - case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_FLT_OVERFLOW: - Standard_Overflow :: Raise ( msg ); - case EXCEPTION_FLT_UNDERFLOW: - Standard_Underflow :: Raise ( msg ); - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_INEXACT_RESULT: - case STATUS_FLOAT_MULTIPLE_TRAPS: - case STATUS_FLOAT_MULTIPLE_FAULTS: - Standard_NumericError :: Raise ( msg ); - default: - break; - } // end switch - - return EXCEPTION_EXECUTE_HANDLER; + if (msg[0] == TEXT('\x03')) ++msg; + switch (dwCode) + { + case EXCEPTION_ACCESS_VIOLATION: + OSD_Exception_ACCESS_VIOLATION::Raise (msg); + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + OSD_Exception_ARRAY_BOUNDS_EXCEEDED::Raise (msg); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + Standard_ProgramError::Raise (msg); + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + OSD_Exception_ILLEGAL_INSTRUCTION::Raise (msg); + break; + case EXCEPTION_IN_PAGE_ERROR: + OSD_Exception_IN_PAGE_ERROR::Raise (msg); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + Standard_DivideByZero::Raise (msg); + break; + case EXCEPTION_INT_OVERFLOW: + OSD_Exception_INT_OVERFLOW::Raise (msg); + break; + case EXCEPTION_INVALID_DISPOSITION: + OSD_Exception_INVALID_DISPOSITION::Raise (msg); + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + OSD_Exception_NONCONTINUABLE_EXCEPTION::Raise (msg); + break; + case EXCEPTION_PRIV_INSTRUCTION: + OSD_Exception_PRIV_INSTRUCTION::Raise (msg); + break; + case EXCEPTION_STACK_OVERFLOW: + OSD_Exception_STACK_OVERFLOW::Raise (msg); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + Standard_DivideByZero::Raise (msg); + break; + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_OVERFLOW: + Standard_Overflow::Raise (msg); + break; + case EXCEPTION_FLT_UNDERFLOW: + Standard_Underflow::Raise (msg); + break; + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_INEXACT_RESULT: + case STATUS_FLOAT_MULTIPLE_TRAPS: + case STATUS_FLOAT_MULTIPLE_FAULTS: + Standard_NumericError::Raise (msg); + break; + default: + break; + } // end switch + return EXCEPTION_EXECUTE_HANDLER; } // end _osd_raise //============================================================================ @@ -677,34 +639,6 @@ LONG _osd_debug ( void ) { #undef __leave #endif -//============================================================================ -//==== _debug_break -//============================================================================ - -void _debug_break ( Standard_PCharacter msg ) { - - OSD_Environment env ( "CSF_DEBUG_MODE" ); - Standard_Character buff[ 2048 ]; - - env.Value (); - - if ( env.Failed () ) return; - - lstrcpy ( buff, msg ); - lstrcat ( buff, _TEXT( "\nExit to debugger ?" ) ); - - if ( MessageBox ( - NULL, buff, _TEXT( "DEBUG" ), MB_SYSTEMMODAL | MB_ICONQUESTION | MB_YESNO - ) == IDYES - ) { - - _osd_debug (); - DebugBreak (); - - } // end if - -} // end _debug_break - // Must be there for compatibility with UNIX system code ---------------------- //void OSD::Handler(const OSD_Signals aSig, @@ -718,26 +652,3 @@ void OSD::SegvHandler(const OSD_Signals aSig, const Standard_Address scp){} #endif // WNT - - -//======================================================================= -//function : UseSETranslator -//purpose : Defines whether to use _se_translator_function or -// SetUnhandledExceptionFilter and signal to catch system exceptions -//======================================================================= - -void OSD::UseSETranslator( const Standard_Boolean -#ifdef _MSC_VER - useSE -#endif - ) -{ -#ifdef _MSC_VER - fSETranslator = useSE; -#endif -} - -Standard_Boolean OSD::UseSETranslator() -{ - return fSETranslator; -}