1
0
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:
abv 2017-10-07 19:26:38 +03:00 committed by bugmaster
parent 022d142b24
commit 9e4791171c
2 changed files with 36 additions and 38 deletions

View File

@ -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")

View File

@ -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 ***");
}
}