1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-06 18:26:22 +03:00

0022545: Improved exception handling

This commit is contained in:
Roman Lygin 2012-11-15 13:17:30 +04:00
parent 06c23d6a33
commit 0ac0c8b4ae
2 changed files with 299 additions and 368 deletions

View File

@ -339,21 +339,56 @@ is
-- variable 'CSF_EXCEPTION_PROMPT' is set and takes appropriate action. -- variable 'CSF_EXCEPTION_PROMPT' is set and takes appropriate action.
-- Raises an exception otherwise. -- Raises an exception otherwise.
SetSignal(aFloatingSignal: Boolean = Standard_True); SetSignal(theFloatingSignal: Boolean = Standard_True);
---Purpose: ---Purpose:
-- 1) Arms some floating point signals, and sets a "Handler" for them. -- Sets signal and exception handlers.
-- 2) Sets a "Handler" for the "Hardware" signals. -- <b>Windows-specific notes<\b>
-- For Win32 users: under VC++ you can control which method of handling -- Compiled with MS VC++ sets 3 main handlers:
-- exceptions is used by means of UseSETranslator method before calling -- @li Signal handlers (via ::signal() functions) that translate system signals
-- SetSignal -- (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; AvailableMemory returns Integer from Standard;
---Purpose: Returns available memory in Kilobytes. ---Purpose: Returns available memory in Kilobytes.
@ -408,19 +443,4 @@ is
-- then this method checks whether Ctrl-Break keystroke was or -- then this method checks whether Ctrl-Break keystroke was or
-- not. If yes then raises Exception_CTRL_BREAK. -- 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; end OSD;

View File

@ -18,13 +18,6 @@
#include <OSD.ixx> #include <OSD.ixx>
static Standard_Boolean fSETranslator =
#ifdef _MSC_VER
Standard_True;
#else
Standard_False;
#endif
#ifdef WNT #ifdef WNT
//---------------------------- Windows NT System -------------------------------- //---------------------------- Windows NT System --------------------------------
@ -53,6 +46,7 @@ static Standard_Boolean fSETranslator =
#include <Standard_DivideByZero.hxx> #include <Standard_DivideByZero.hxx>
#include <Standard_Overflow.hxx> #include <Standard_Overflow.hxx>
#include <Standard_ProgramError.hxx> #include <Standard_ProgramError.hxx>
#include <Standard_Mutex.hxx>
#include <OSD_WNT_1.hxx> #include <OSD_WNT_1.hxx>
@ -70,11 +64,13 @@ static Standard_Boolean fFltExceptions;
static Standard_Boolean fDbgLoaded; static Standard_Boolean fDbgLoaded;
static Standard_Boolean fCtrlBrk; 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 LONG __fastcall _osd_raise ( DWORD, LPTSTR );
static BOOL WINAPI _osd_ctrl_break_handler ( DWORD ); static BOOL WINAPI _osd_ctrl_break_handler ( DWORD );
extern "C" Standard_EXPORT LONG _osd_debug ( void ); extern "C" Standard_EXPORT LONG _osd_debug ( void );
extern "C" Standard_EXPORT void _debug_break ( Standard_PCharacter );
MB_DESC fatalErrorDesc[] = { MB_DESC fatalErrorDesc[] = {
@ -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 | _EM_UNDERFLOW )
# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW ) # define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW )
//============================================================================ //=======================================================================
//==== WntHandler //function : CallHandler
//============================================================================ //purpose :
//=======================================================================
Standard_Integer OSD :: WntHandler ( const Standard_Address exceptionInfo ) static LONG CallHandler (DWORD dwExceptionCode,
{ ptrdiff_t ExceptionInformation1,
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) ptrdiff_t ExceptionInformation0)
{ {
#if !defined(__CYGWIN32__) && !defined(__MINGW32__) #if !defined(__CYGWIN32__) && !defined(__MINGW32__)
Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
static TCHAR buffer[ 2048 ]; static TCHAR buffer[ 2048 ];
int flterr = 0; int flterr = 0;
@ -318,6 +231,10 @@ static LONG CallHandler (DWORD dwExceptionCode ,
if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) { 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 ); MessageBeep ( MB_ICONHAND );
int msgID = MsgBox ( NULL, buffer, TEXT( "Error detected" ), 4, fatalErrorDesc ); int msgID = MsgBox ( NULL, buffer, TEXT( "Error detected" ), 4, fatalErrorDesc );
// cout << "flterr" << flterr << " fFltExceptions " << fFltExceptions << endl ; // 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 ; // cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ;
} }
} }
return _osd_raise ( dwExceptionCode, buffer ); return _osd_raise ( dwExceptionCode, buffer );
#else #else
return 0; return 0;
#endif #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 //function : TranslateSE
//purpose : Translate Structural Exceptions into C++ exceptions //purpose : Translate Structural Exceptions into C++ exceptions
// Will be used when user's code is compiled with /EHa option
//======================================================================= //=======================================================================
#ifdef _MSC_VER #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 ) 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; ptrdiff_t info1 = 0, info0 = 0;
if ( theExcPtr ) { if ( theExcPtr ) {
info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1]; info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1];
@ -386,87 +384,60 @@ static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr )
} }
#endif #endif
//============================================================================ //=======================================================================
//==== SetSignal //function : SetSignal
//============================================================================ //purpose :
//=======================================================================
#ifdef _MSC_VER void OSD::SetSignal (const Standard_Boolean theFloatingSignal)
// 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 ) {
#if !defined(__CYGWIN32__) && !defined(__MINGW32__) #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 ; OSD_Environment env (TEXT("CSF_DEBUG_MODE"));
LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter ; TCollection_AsciiString val = env.Value();
if (!env.Failed())
if ( first_time ) { {
// OSD_Environment env ( TEXT( "CSF_EXCEPTION_PROMPT" ) ); cout << "Environment variable CSF_DEBUG_MODE setted.\n";
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; fMsgBox = Standard_True;
} }
else { else
// cout << "Environment variable CSF_DEBUG_MODE not setted." << endl ; {
fMsgBox = Standard_False; fMsgBox = Standard_False;
} }
if (!fSETranslator) { // Set exception handler (ignored when running under debugger). It will be used in most cases
aPreviousFilter = // when user's code is compiled with /EHs
SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER)&OSD::WntHandler); // Replaces the existing top-level exception filter for all existing and all future threads
// cout << "SetUnhandledExceptionFilter previous filer : " << hex << aPreviousFilter << dec << endl ; // in the calling process
aPreviousFilter = ::SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER )&OSD::WntHandler);
if ( signal( SIGSEGV , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) // Signal handlers will only be used when the method ::raise() will be used
cout << "signal(OSD::SetSignal) error" << endl ; // Handlers must be set for every thread
if ( signal( SIGFPE , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) if (signal (SIGSEGV, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
cout << "signal(OSD::SetSignal) error" << endl ; cout << "signal(OSD::SetSignal) error\n";
if ( signal( SIGILL , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) if (signal (SIGFPE, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
cout << "signal(OSD::SetSignal) error" << endl ; 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; fCtrlBrk = Standard_False;
SetConsoleCtrlHandler ( &_osd_ctrl_break_handler, TRUE ); SetConsoleCtrlHandler (&_osd_ctrl_break_handler, TRUE);
}
#ifdef _MSC_VER #ifdef _MSC_VER
if (fSETranslator) { _se_translator_function pOldSeFunc = _set_se_translator (TranslateSE);
// use Structural Exception translator (one per thread)
_se_translator_function pOldSeFunc = _set_se_translator( TranslateSE );
}
#endif #endif
fFltExceptions = aFloatingSignal; fFltExceptions = theFloatingSignal;
if ( aFloatingSignal ) { if (theFloatingSignal)
_controlfp ( 0, _OSD_FPX ); // JR add : {
if ( first_time ) { _controlfp (0, _OSD_FPX); // JR add :
// cout << "SetSignal with floating point traps : " << hex << _controlfp(0,0) << dec << endl ;
first_time = 0 ;
}
} }
else { else {
_controlfp ( _OSD_FPX , _OSD_FPX ); // JR add : _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 ;
} }
}
#endif #endif
} // end OSD :: SetSignal } // 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 ) static LONG __fastcall _osd_raise ( DWORD dwCode, LPTSTR msg )
{ {
if ( msg[ 0 ] == TEXT( '\x03' ) ) ++msg; if (msg[0] == TEXT('\x03')) ++msg;
switch ( dwCode ) {
switch (dwCode)
{
case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ACCESS_VIOLATION:
OSD_Exception_ACCESS_VIOLATION::Raise (msg);
OSD_Exception_ACCESS_VIOLATION :: Raise ( msg ); break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
OSD_Exception_ARRAY_BOUNDS_EXCEEDED::Raise (msg);
OSD_Exception_ARRAY_BOUNDS_EXCEEDED :: Raise ( msg ); break;
case EXCEPTION_DATATYPE_MISALIGNMENT: case EXCEPTION_DATATYPE_MISALIGNMENT:
Standard_ProgramError::Raise (msg);
Standard_ProgramError :: Raise ( msg ); break;
case EXCEPTION_ILLEGAL_INSTRUCTION: case EXCEPTION_ILLEGAL_INSTRUCTION:
OSD_Exception_ILLEGAL_INSTRUCTION::Raise (msg);
OSD_Exception_ILLEGAL_INSTRUCTION :: Raise ( msg ); break;
case EXCEPTION_IN_PAGE_ERROR: case EXCEPTION_IN_PAGE_ERROR:
OSD_Exception_IN_PAGE_ERROR::Raise (msg);
OSD_Exception_IN_PAGE_ERROR :: Raise ( msg ); break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_DIVIDE_BY_ZERO:
Standard_DivideByZero::Raise (msg);
Standard_DivideByZero :: Raise ( msg ); break;
case EXCEPTION_INT_OVERFLOW: case EXCEPTION_INT_OVERFLOW:
OSD_Exception_INT_OVERFLOW::Raise (msg);
OSD_Exception_INT_OVERFLOW :: Raise ( msg ); break;
case EXCEPTION_INVALID_DISPOSITION: case EXCEPTION_INVALID_DISPOSITION:
OSD_Exception_INVALID_DISPOSITION::Raise (msg);
OSD_Exception_INVALID_DISPOSITION :: Raise ( msg ); break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION: case EXCEPTION_NONCONTINUABLE_EXCEPTION:
OSD_Exception_NONCONTINUABLE_EXCEPTION::Raise (msg);
OSD_Exception_NONCONTINUABLE_EXCEPTION :: Raise ( msg ); break;
case EXCEPTION_PRIV_INSTRUCTION: case EXCEPTION_PRIV_INSTRUCTION:
OSD_Exception_PRIV_INSTRUCTION::Raise (msg);
OSD_Exception_PRIV_INSTRUCTION :: Raise ( msg ); break;
case EXCEPTION_STACK_OVERFLOW: case EXCEPTION_STACK_OVERFLOW:
OSD_Exception_STACK_OVERFLOW::Raise (msg);
OSD_Exception_STACK_OVERFLOW :: Raise ( msg ); break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_DIVIDE_BY_ZERO:
Standard_DivideByZero :: Raise ( msg ); Standard_DivideByZero::Raise (msg);
break;
case EXCEPTION_FLT_STACK_CHECK: case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_OVERFLOW:
Standard_Overflow :: Raise ( msg ); Standard_Overflow::Raise (msg);
break;
case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_FLT_UNDERFLOW:
Standard_Underflow :: Raise ( msg ); Standard_Underflow::Raise (msg);
break;
case EXCEPTION_FLT_INVALID_OPERATION: case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_DENORMAL_OPERAND: case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_INEXACT_RESULT: case EXCEPTION_FLT_INEXACT_RESULT:
case STATUS_FLOAT_MULTIPLE_TRAPS: case STATUS_FLOAT_MULTIPLE_TRAPS:
case STATUS_FLOAT_MULTIPLE_FAULTS: case STATUS_FLOAT_MULTIPLE_FAULTS:
Standard_NumericError :: Raise ( msg ); Standard_NumericError::Raise (msg);
break;
default: default:
break; break;
} // end switch } // end switch
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} // end _osd_raise } // end _osd_raise
//============================================================================ //============================================================================
@ -677,34 +639,6 @@ LONG _osd_debug ( void ) {
#undef __leave #undef __leave
#endif #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 ---------------------- // Must be there for compatibility with UNIX system code ----------------------
//void OSD::Handler(const OSD_Signals aSig, //void OSD::Handler(const OSD_Signals aSig,
@ -718,26 +652,3 @@ void OSD::SegvHandler(const OSD_Signals aSig,
const Standard_Address scp){} const Standard_Address scp){}
#endif // WNT #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;
}