-- 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;
---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.
-- 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.
--
-- 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
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;
class Protection;
---Purpose: Gets and sets protection attributes of 'system , user ,
-- group, and world'.
-
+
class Path;
---Purpose: Manages independent system path translation.
---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;
---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.
---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 --
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."
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;
-- 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,
-- 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.
+ -- <b>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
+ -- <tt>_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.
+ -- .
+ -- <b>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
+ -- <tt>FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW</tt> (in Linux conventions).<br>
+ -- When compiled with OBJS macro defined, already set signal handlers (e.g.
+ -- by Data Base Managers) are not redefined.
+ -- .
+ -- <b>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:
-- 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;
-
-
#include <OSD.ixx>
-static Standard_Boolean fSETranslator =
-#ifdef _MSC_VER
- Standard_True;
-#else
- Standard_False;
-#endif
-
#ifdef WNT
//---------------------------- Windows NT System --------------------------------
#include <Standard_DivideByZero.hxx>
#include <Standard_Overflow.hxx>
#include <Standard_ProgramError.hxx>
+#include <Standard_Mutex.hxx>
#include <OSD_WNT_1.hxx>
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" ) },
};
-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]
-// << " " <<lpXP->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;
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 ;
// cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ;
}
}
-
return _osd_raise ( dwExceptionCode, buffer );
-
#else
return 0;
#endif
+}
+
+//=======================================================================
+//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;
-} // end OSD :: WntHandler
+ 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];
}
#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;
+
+ 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;
+ }
- static int first_time = 1 ;
- LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter ;
-
- if ( first_time ) {
-// OSD_Environment env ( TEXT( "CSF_EXCEPTION_PROMPT" ) );
- OSD_Environment env ( TEXT( "CSF_DEBUG_MODE" ) );
- TCollection_AsciiString val;
-
- val = env.Value ();
-
- 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 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);
+
+ // 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";
+
+ // 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
//============================================================================
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
//============================================================================
#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,
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;
-}