mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-01 17:36:21 +03:00
0029171: Foundation Classes - C signal handler does not work on MinGW
Setting signal handler is enabled in OSD::SetSignal() for MinGW (works only for SEH builds of MinGW, not for SJLJ builds). Due to absence of function _set_se_translator(), handler is set using C signal() function and thus is called asynchronously. Macro OCC_CONVERT_SIGNALS is enabled for MinGW build to support converting signals to C++ exceptions using long jumps (the same as on Linux). Code raising exceptions in OSD::SetSignal() is corrected to use method Jump() instead of C++ throw.
This commit is contained in:
parent
022d142b24
commit
9e4791171c
@ -25,7 +25,7 @@ if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
add_definitions (-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -fPIC")
|
||||
|
@ -65,10 +65,9 @@
|
||||
#include <float.h>
|
||||
|
||||
static Standard_Boolean fCtrlBrk;
|
||||
#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
|
||||
|
||||
static Standard_Boolean fMsgBox;
|
||||
static Standard_Boolean fFltExceptions;
|
||||
static Standard_Boolean fDbgLoaded;
|
||||
|
||||
// used to forbid simultaneous execution of setting / executing handlers
|
||||
static Standard_Mutex THE_SIGNAL_MUTEX;
|
||||
@ -76,13 +75,20 @@ static Standard_Mutex THE_SIGNAL_MUTEX;
|
||||
static LONG __fastcall _osd_raise ( DWORD, LPSTR );
|
||||
static BOOL WINAPI _osd_ctrl_break_handler ( DWORD );
|
||||
|
||||
#ifndef OCCT_UWP
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
static Standard_Boolean fDbgLoaded;
|
||||
static LONG _osd_debug ( void );
|
||||
#endif
|
||||
|
||||
//# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW )
|
||||
# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW )
|
||||
|
||||
#ifdef OCC_CONVERT_SIGNALS
|
||||
#define THROW_OR_JUMP(Type,Message) Type::NewInstance(Message)->Jump()
|
||||
#else
|
||||
#define THROW_OR_JUMP(Type,Message) throw Type(Message)
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : CallHandler
|
||||
//purpose :
|
||||
@ -148,7 +154,8 @@ static LONG CallHandler (DWORD dwExceptionCode,
|
||||
break ;
|
||||
case STATUS_NO_MEMORY:
|
||||
// cout << "CallHandler : STATUS_NO_MEMORY:" << endl ;
|
||||
throw OSD_Exception_STATUS_NO_MEMORY ( "MEMORY ALLOCATION ERROR ( no room in the process heap )" );
|
||||
THROW_OR_JUMP (OSD_Exception_STATUS_NO_MEMORY, "MEMORY ALLOCATION ERROR ( no room in the process heap )");
|
||||
break;
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
// cout << "CallHandler : EXCEPTION_ACCESS_VIOLATION:" << endl ;
|
||||
StringCchPrintfW (buffer, _countof(buffer), L"%s%s%s0x%.8p%s%s%s", L"ACCESS VIOLATION",
|
||||
@ -227,7 +234,7 @@ static LONG CallHandler (DWORD dwExceptionCode,
|
||||
_fpreset();
|
||||
_clearfp();
|
||||
|
||||
#ifndef OCCT_UWP
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
MessageBeep ( MB_ICONHAND );
|
||||
int aChoice = ::MessageBoxW (0, buffer, L"OCCT Exception Handler", MB_ABORTRETRYIGNORE | MB_ICONSTOP);
|
||||
if (aChoice == IDRETRY)
|
||||
@ -287,7 +294,7 @@ static void SIGWntHandler (int signum, int sub_code)
|
||||
break ;
|
||||
default:
|
||||
cout << "SIGWntHandler(default) -> throw Standard_NumericError(\"Floating Point Error\");" << endl;
|
||||
throw Standard_NumericError("Floating Point Error");
|
||||
THROW_OR_JUMP (Standard_NumericError, "Floating Point Error");
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
@ -309,7 +316,6 @@ static void SIGWntHandler (int signum, int sub_code)
|
||||
DebugBreak ();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : TranslateSE
|
||||
@ -342,7 +348,6 @@ static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr )
|
||||
// option and unless user sets his own exception handler with
|
||||
// ::SetUnhandledExceptionFilter().
|
||||
//=======================================================================
|
||||
#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
|
||||
static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
|
||||
{
|
||||
DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
|
||||
@ -351,7 +356,6 @@ static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
|
||||
lpXP->ExceptionRecord->ExceptionInformation[1],
|
||||
lpXP->ExceptionRecord->ExceptionInformation[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : SetSignal
|
||||
@ -359,11 +363,8 @@ static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
|
||||
//=======================================================================
|
||||
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
|
||||
#if !defined(OCCT_UWP) || defined(NTDDI_WIN10_TH2)
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter;
|
||||
|
||||
OSD_Environment env ("CSF_DEBUG_MODE");
|
||||
TCollection_AsciiString val = env.Value();
|
||||
if (!env.Failed())
|
||||
@ -380,7 +381,7 @@ 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)*/ WntHandler);
|
||||
::SetUnhandledExceptionFilter (/*(LPTOP_LEVEL_EXCEPTION_FILTER)*/ WntHandler);
|
||||
#endif // NTDDI_WIN10_TH2
|
||||
|
||||
// Signal handlers will only be used when the method ::raise() will be used
|
||||
@ -410,9 +411,6 @@ void OSD::SetSignal (const Standard_Boolean theFloatingSignal)
|
||||
else {
|
||||
_controlfp (_OSD_FPX, _OSD_FPX); // JR add :
|
||||
}
|
||||
#else
|
||||
(void)theFloatingSignal; // silence compiler warning on MinGw
|
||||
#endif
|
||||
} // end OSD :: SetSignal
|
||||
|
||||
//============================================================================
|
||||
@ -424,7 +422,7 @@ void OSD::ControlBreak () {
|
||||
throw OSD_Exception_CTRL_BREAK ( "*** INTERRUPT ***" );
|
||||
}
|
||||
} // end OSD :: ControlBreak
|
||||
#if !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
|
||||
#ifndef OCCT_UWP
|
||||
//============================================================================
|
||||
//==== _osd_ctrl_break_handler
|
||||
@ -439,6 +437,7 @@ static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) {
|
||||
return TRUE;
|
||||
} // end _osd_ctrl_break_handler
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
//==== _osd_raise
|
||||
//============================================================================
|
||||
@ -449,54 +448,54 @@ static LONG __fastcall _osd_raise ( DWORD dwCode, LPSTR msg )
|
||||
switch (dwCode)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
throw OSD_Exception_ACCESS_VIOLATION(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ACCESS_VIOLATION, msg);
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
throw OSD_Exception_ARRAY_BOUNDS_EXCEEDED(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ARRAY_BOUNDS_EXCEEDED, msg);
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
throw Standard_ProgramError(msg);
|
||||
THROW_OR_JUMP (Standard_ProgramError, msg);
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
throw OSD_Exception_ILLEGAL_INSTRUCTION(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ILLEGAL_INSTRUCTION, msg);
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
throw OSD_Exception_IN_PAGE_ERROR(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_IN_PAGE_ERROR, msg);
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
throw Standard_DivideByZero(msg);
|
||||
THROW_OR_JUMP (Standard_DivideByZero, msg);
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
throw OSD_Exception_INT_OVERFLOW(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_INT_OVERFLOW, msg);
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
throw OSD_Exception_INVALID_DISPOSITION(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_INVALID_DISPOSITION, msg);
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
throw OSD_Exception_NONCONTINUABLE_EXCEPTION(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_NONCONTINUABLE_EXCEPTION, msg);
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
throw OSD_Exception_PRIV_INSTRUCTION(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_PRIV_INSTRUCTION, msg);
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
throw OSD_Exception_STACK_OVERFLOW(msg);
|
||||
THROW_OR_JUMP (OSD_Exception_STACK_OVERFLOW, msg);
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
throw Standard_DivideByZero(msg);
|
||||
THROW_OR_JUMP (Standard_DivideByZero, msg);
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
throw Standard_Overflow(msg);
|
||||
THROW_OR_JUMP (Standard_Overflow, msg);
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
throw Standard_Underflow(msg);
|
||||
THROW_OR_JUMP (Standard_Underflow, 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:
|
||||
throw Standard_NumericError(msg);
|
||||
THROW_OR_JUMP (Standard_NumericError, msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -504,10 +503,10 @@ static LONG __fastcall _osd_raise ( DWORD dwCode, LPSTR msg )
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
} // end _osd_raise
|
||||
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
//============================================================================
|
||||
//==== _osd_debug
|
||||
//============================================================================
|
||||
#ifndef OCCT_UWP
|
||||
LONG _osd_debug ( void ) {
|
||||
|
||||
LONG action ;
|
||||
@ -590,10 +589,9 @@ LONG _osd_debug ( void ) {
|
||||
return action ;
|
||||
|
||||
} // end _osd_debug
|
||||
#endif /* ! OCCT_UWP && ! __CYGWIN__ && ! __MINGW32__ */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#else /* ! _WIN32 */
|
||||
|
||||
//---------- All Systems except Windows NT : ----------------------------------
|
||||
|
||||
@ -1031,7 +1029,7 @@ void OSD :: ControlBreak ()
|
||||
{
|
||||
if ( fCtrlBrk ) {
|
||||
fCtrlBrk = Standard_False;
|
||||
throw OSD_Exception_CTRL_BREAK("*** INTERRUPT ***");
|
||||
throw OSD_Exception_CTRL_BREAK ("*** INTERRUPT ***");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user