mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0030762: Foundation Classes - include backtrace within OSD_SIGSEGV
Standard_Failure now holds an optional stack trace dump. Added function Standard::StackTrace() dumping backtrace to the string. SegvHandler within OSD_signal now appends backtrace to the message if OSD::SignalStackTraceLength() is set to non-zero value or environment variable "CSF_DEBUG_MODE" is set for debugging. Added auxiliary macros Standard_NOINLINE disallowing function inlining. Command "dsetsignal" has been extended by -strackTraceLength argument for defining stack trace length within signals redirected to C++ exceptions. Added "ddebugtraces" command for debugging purposes (adding stack traces to all exceptions).
This commit is contained in:
@@ -134,6 +134,14 @@ public:
|
||||
//! not. If yes then raises Exception_CTRL_BREAK.
|
||||
Standard_EXPORT static void ControlBreak();
|
||||
|
||||
//! Returns a length of stack trace to be put into exception redirected from signal;
|
||||
//! 0 by default meaning no stack trace.
|
||||
//! @sa Standard_Failure::GetStackString()
|
||||
Standard_EXPORT static Standard_Integer SignalStackTraceLength();
|
||||
|
||||
//! Sets a length of stack trace to be put into exception redirected from signal.
|
||||
Standard_EXPORT static void SetSignalStackTraceLength (Standard_Integer theLength);
|
||||
|
||||
};
|
||||
|
||||
#endif // _OSD_HeaderFile
|
||||
|
@@ -269,7 +269,7 @@ void OSD_ThreadPool::Launcher::wait()
|
||||
}
|
||||
|
||||
aFailures = TCollection_AsciiString("Multiple exceptions:\n") + aFailures;
|
||||
throw Standard_ProgramError (aFailures.ToCString());
|
||||
throw Standard_ProgramError (aFailures.ToCString(), NULL);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -289,17 +289,17 @@ void OSD_ThreadPool::performJob (Handle(Standard_Failure)& theFailure,
|
||||
{
|
||||
TCollection_AsciiString aMsg = TCollection_AsciiString (aFailure.DynamicType()->Name())
|
||||
+ ": " + aFailure.GetMessageString();
|
||||
theFailure = new Standard_ProgramError (aMsg.ToCString());
|
||||
theFailure = new Standard_ProgramError (aMsg.ToCString(), aFailure.GetStackString());
|
||||
}
|
||||
catch (std::exception& anStdException)
|
||||
{
|
||||
TCollection_AsciiString aMsg = TCollection_AsciiString (typeid(anStdException).name())
|
||||
+ ": " + anStdException.what();
|
||||
theFailure = new Standard_ProgramError (aMsg.ToCString());
|
||||
theFailure = new Standard_ProgramError (aMsg.ToCString(), NULL);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
theFailure = new Standard_ProgramError ("Error: Unknown exception");
|
||||
theFailure = new Standard_ProgramError ("Error: Unknown exception", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Standard_WarningDisableFunctionCast.hxx>
|
||||
|
||||
static OSD_SignalMode OSD_WasSetSignal = OSD_SignalMode_AsIs;
|
||||
static Standard_Integer OSD_SignalStackTraceLength = 0;
|
||||
|
||||
//=======================================================================
|
||||
//function : SignalMode
|
||||
@@ -31,6 +32,24 @@ OSD_SignalMode OSD::SignalMode()
|
||||
return OSD_WasSetSignal;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SignalStackTraceLength
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer OSD::SignalStackTraceLength()
|
||||
{
|
||||
return OSD_SignalStackTraceLength;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetSignalStackTraceLength
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OSD::SetSignalStackTraceLength (Standard_Integer theLength)
|
||||
{
|
||||
OSD_SignalStackTraceLength = theLength;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
//---------------------------- Windows NT System --------------------------------
|
||||
|
||||
@@ -85,7 +104,7 @@ static Standard_Boolean fMsgBox;
|
||||
// used to forbid simultaneous execution of setting / executing handlers
|
||||
static Standard_Mutex THE_SIGNAL_MUTEX;
|
||||
|
||||
static LONG __fastcall _osd_raise ( DWORD, LPSTR );
|
||||
static LONG __fastcall _osd_raise (DWORD theCode, const char* theMsg, const char* theStack);
|
||||
static BOOL WINAPI _osd_ctrl_break_handler ( DWORD );
|
||||
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
@@ -96,172 +115,208 @@ static LONG _osd_debug ( void );
|
||||
# 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()
|
||||
#define THROW_OR_JUMP(Type,Message,Stack) Type::NewInstance(Message,Stack)->Jump()
|
||||
#else
|
||||
#define THROW_OR_JUMP(Type,Message) throw Type(Message)
|
||||
#define THROW_OR_JUMP(Type,Message,Stack) throw Type(Message,Stack)
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : CallHandler
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static LONG CallHandler (DWORD dwExceptionCode,
|
||||
ptrdiff_t ExceptionInformation1,
|
||||
ptrdiff_t ExceptionInformation0)
|
||||
static LONG CallHandler (DWORD theExceptionCode,
|
||||
EXCEPTION_POINTERS* theExcPtr)
|
||||
{
|
||||
ptrdiff_t ExceptionInformation1 = 0, ExceptionInformation0 = 0;
|
||||
if (theExcPtr != NULL)
|
||||
{
|
||||
ExceptionInformation1 = theExcPtr->ExceptionRecord->ExceptionInformation[1];
|
||||
ExceptionInformation0 = theExcPtr->ExceptionRecord->ExceptionInformation[0];
|
||||
}
|
||||
|
||||
Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
|
||||
static char aBuffer[2048];
|
||||
|
||||
static wchar_t buffer[2048];
|
||||
|
||||
int flterr = 0;
|
||||
|
||||
buffer[0] = '\0' ;
|
||||
|
||||
// std::cout << "CallHandler " << dwExceptionCode << std::endl ;
|
||||
switch ( dwExceptionCode ) {
|
||||
bool isFloatErr = false;
|
||||
aBuffer[0] = '\0';
|
||||
switch (theExceptionCode)
|
||||
{
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_DENORMAL_OPERAND:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT DENORMAL OPERAND");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT DENORMAL OPERAND");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_DIVIDE_BY_ZERO:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT DIVIDE BY ZERO");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT DIVIDE BY ZERO");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_INEXACT_RESULT:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT INEXACT RESULT");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT INEXACT RESULT");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_INVALID_OPERATION:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT INVALID OPERATION");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT INVALID OPERATION");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_OVERFLOW:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT OVERFLOW");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT OVERFLOW");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_STACK_CHECK:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT STACK CHECK");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT STACK CHECK");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT UNDERFLOW");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT UNDERFLOW");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT MULTIPLE TRAPS (possible overflow in conversion of double to integer)");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT MULTIPLE TRAPS (possible overflow in conversion of double to integer)");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"FLT MULTIPLE FAULTS");
|
||||
flterr = 1 ;
|
||||
break ;
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "FLT MULTIPLE FAULTS");
|
||||
isFloatErr = true;
|
||||
break;
|
||||
}
|
||||
case STATUS_NO_MEMORY:
|
||||
// std::cout << "CallHandler : STATUS_NO_MEMORY:" << std::endl ;
|
||||
THROW_OR_JUMP (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 )", NULL);
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
// std::cout << "CallHandler : EXCEPTION_ACCESS_VIOLATION:" << std::endl ;
|
||||
StringCchPrintfW (buffer, _countof(buffer), L"%s%s%s0x%.8p%s%s%s", L"ACCESS VIOLATION",
|
||||
fMsgBox ? L"\n" : L" ", L"at address ",
|
||||
ExceptionInformation1 ,
|
||||
L" during '",
|
||||
ExceptionInformation0 ? L"WRITE" : L"READ",
|
||||
L"' operation");
|
||||
{
|
||||
_snprintf_s (aBuffer, sizeof(aBuffer), _TRUNCATE, "%s%s%s0x%.8p%s%s%s", "ACCESS VIOLATION",
|
||||
fMsgBox ? "\n" : " ",
|
||||
"at address ", (void* )ExceptionInformation1,
|
||||
" during '", ExceptionInformation0 ? "WRITE" : "READ", "' operation");
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
// std::cout << "CallHandler : EXCEPTION_ARRAY_BOUNDS_EXCEEDED:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"ARRAY BOUNDS EXCEEDED");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "ARRAY BOUNDS EXCEEDED");
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
// std::cout << "CallHandler : EXCEPTION_DATATYPE_MISALIGNMENT:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"DATATYPE MISALIGNMENT");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "DATATYPE MISALIGNMENT");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
// std::cout << "CallHandler : EXCEPTION_ILLEGAL_INSTRUCTION:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"ILLEGAL INSTRUCTION");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "ILLEGAL INSTRUCTION");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
// std::cout << "CallHandler : EXCEPTION_IN_PAGE_ERROR:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"IN_PAGE ERROR");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "IN_PAGE ERROR");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
// std::cout << "CallHandler : EXCEPTION_INT_DIVIDE_BY_ZERO:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"INTEGER DIVISION BY ZERO");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "INTEGER DIVISION BY ZERO");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
// std::cout << "CallHandler : EXCEPTION_INT_OVERFLOW:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"INTEGER OVERFLOW");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "INTEGER OVERFLOW");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
// std::cout << "CallHandler : EXCEPTION_INVALID_DISPOSITION:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"INVALID DISPOSITION");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "INVALID DISPOSITION");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
// std::cout << "CallHandler : EXCEPTION_NONCONTINUABLE_EXCEPTION:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"NONCONTINUABLE EXCEPTION");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "NONCONTINUABLE EXCEPTION");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
// std::cout << "CallHandler : EXCEPTION_PRIV_INSTRUCTION:" << std::endl ;
|
||||
StringCchCopyW (buffer, _countof(buffer), L"PRIVELEGED INSTRUCTION ENCOUNTERED");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "PRIVELEGED INSTRUCTION ENCOUNTERED");
|
||||
break;
|
||||
|
||||
}
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
// std::cout << "CallHandler : EXCEPTION_STACK_OVERFLOW:" << std::endl ;
|
||||
{
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) && !defined(OCCT_UWP)
|
||||
// try recovering from stack overflow: available in MS VC++ 7.0
|
||||
// try recovering from stack overflow: available in MS VC++ 7.0
|
||||
if (!_resetstkoflw())
|
||||
StringCchCopyW (buffer, _countof(buffer), L"Unrecoverable STACK OVERFLOW");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "Unrecoverable STACK OVERFLOW");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
StringCchCopyW (buffer, _countof(buffer), L"STACK OVERFLOW");
|
||||
{
|
||||
strcat_s (aBuffer, sizeof(aBuffer), "STACK OVERFLOW");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
StringCchPrintfW (buffer, _countof(buffer), L"unknown exception code 0x%x, params 0x%p 0x%p",
|
||||
dwExceptionCode, ExceptionInformation1, ExceptionInformation0 );
|
||||
|
||||
} // end switch
|
||||
{
|
||||
_snprintf_s (aBuffer, sizeof(aBuffer), _TRUNCATE, "unknown exception code 0x%x, params 0x%p 0x%p",
|
||||
theExceptionCode, (void* )ExceptionInformation1, (void* )ExceptionInformation0);
|
||||
}
|
||||
}
|
||||
|
||||
// reset FPE state (before message box, otherwise it may fail to show up)
|
||||
if ( flterr ) {
|
||||
if (isFloatErr)
|
||||
{
|
||||
OSD::SetFloatingSignal (Standard_True);
|
||||
}
|
||||
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
// provide message to the user with possibility to stop
|
||||
size_t idx;
|
||||
StringCchLengthW (buffer, _countof(buffer),&idx);
|
||||
if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) {
|
||||
MessageBeep ( MB_ICONHAND );
|
||||
int aChoice = ::MessageBoxW (0, buffer, L"OCCT Exception Handler", MB_ABORTRETRYIGNORE | MB_ICONSTOP);
|
||||
const int aStackLength = OSD_SignalStackTraceLength;
|
||||
const int aStackBufLen = Max (aStackLength * 200, 2048);
|
||||
char* aStackBuffer = aStackLength != 0 ? (char* )alloca (aStackBufLen) : NULL;
|
||||
if (aStackBuffer != NULL)
|
||||
{
|
||||
memset (aStackBuffer, 0, aStackBufLen);
|
||||
Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength, theExcPtr->ContextRecord);
|
||||
}
|
||||
|
||||
#if !defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
// provide message to the user with possibility to stop
|
||||
if (aBuffer[0] != '\0'
|
||||
&& fMsgBox
|
||||
&& theExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION)
|
||||
{
|
||||
MessageBeep (MB_ICONHAND);
|
||||
char aMsgBoxBuffer[2048];
|
||||
strcat_s (aMsgBoxBuffer, sizeof(aMsgBoxBuffer), aBuffer);
|
||||
if (aStackBuffer != NULL)
|
||||
{
|
||||
strcat_s (aMsgBoxBuffer, sizeof(aMsgBoxBuffer), aStackBuffer);
|
||||
}
|
||||
int aChoice = ::MessageBoxA (0, aMsgBoxBuffer, "OCCT Exception Handler", MB_ABORTRETRYIGNORE | MB_ICONSTOP);
|
||||
if (aChoice == IDRETRY)
|
||||
{
|
||||
_osd_debug();
|
||||
DebugBreak();
|
||||
} else if (aChoice == IDABORT)
|
||||
exit(0xFFFF);
|
||||
}
|
||||
else if (aChoice == IDABORT)
|
||||
{
|
||||
exit (0xFFFF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
char aBufferA[2048];
|
||||
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, aBufferA, sizeof(aBufferA), NULL, NULL);
|
||||
return _osd_raise(dwExceptionCode, aBufferA);
|
||||
return _osd_raise (theExceptionCode, aBuffer, aStackBuffer);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -279,38 +334,38 @@ static void SIGWntHandler (int signum, int sub_code)
|
||||
std::cout << "signal error" << std::endl ;
|
||||
switch( sub_code ) {
|
||||
case _FPE_INVALID :
|
||||
CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_INVALID_OPERATION, NULL);
|
||||
break ;
|
||||
case _FPE_DENORMAL :
|
||||
CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_DENORMAL_OPERAND, NULL);
|
||||
break ;
|
||||
case _FPE_ZERODIVIDE :
|
||||
CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_DIVIDE_BY_ZERO, NULL);
|
||||
break ;
|
||||
case _FPE_OVERFLOW :
|
||||
CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_OVERFLOW, NULL);
|
||||
break ;
|
||||
case _FPE_UNDERFLOW :
|
||||
CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_UNDERFLOW, NULL);
|
||||
break ;
|
||||
case _FPE_INEXACT :
|
||||
CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ;
|
||||
CallHandler (EXCEPTION_FLT_INEXACT_RESULT, NULL);
|
||||
break ;
|
||||
default:
|
||||
std::cout << "SIGWntHandler(default) -> throw Standard_NumericError(\"Floating Point Error\");" << std::endl;
|
||||
THROW_OR_JUMP (Standard_NumericError, "Floating Point Error");
|
||||
THROW_OR_JUMP (Standard_NumericError, "Floating Point Error", NULL);
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case SIGSEGV :
|
||||
if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
|
||||
std::cout << "signal error" << std::endl ;
|
||||
CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ;
|
||||
CallHandler (EXCEPTION_ACCESS_VIOLATION, NULL);
|
||||
break ;
|
||||
case SIGILL :
|
||||
if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
|
||||
std::cout << "signal error" << std::endl ;
|
||||
CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ;
|
||||
CallHandler (EXCEPTION_ILLEGAL_INSTRUCTION, NULL);
|
||||
break ;
|
||||
default:
|
||||
std::cout << "SIGWntHandler unexpected signal : " << signum << std::endl ;
|
||||
@@ -337,12 +392,7 @@ static void SIGWntHandler (int signum, int sub_code)
|
||||
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];
|
||||
info0 = theExcPtr->ExceptionRecord->ExceptionInformation[0];
|
||||
}
|
||||
CallHandler(theCode, info1, info0);
|
||||
CallHandler (theCode, theExcPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -354,11 +404,8 @@ static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr )
|
||||
//=======================================================================
|
||||
static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
|
||||
{
|
||||
DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
|
||||
|
||||
return CallHandler (dwExceptionCode,
|
||||
lpXP->ExceptionRecord->ExceptionInformation[1],
|
||||
lpXP->ExceptionRecord->ExceptionInformation[0]);
|
||||
DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
|
||||
return CallHandler (dwExceptionCode, lpXP);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -422,6 +469,11 @@ void OSD::SetSignal (OSD_SignalMode theSignalMode,
|
||||
{
|
||||
std::cout << "Environment variable CSF_DEBUG_MODE setted.\n";
|
||||
fMsgBox = Standard_True;
|
||||
if (OSD_SignalStackTraceLength == 0)
|
||||
{
|
||||
// enable stack trace if CSF_DEBUG_MODE is set
|
||||
OSD_SignalStackTraceLength = 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -508,67 +560,71 @@ static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) {
|
||||
//============================================================================
|
||||
//==== _osd_raise
|
||||
//============================================================================
|
||||
static LONG __fastcall _osd_raise ( DWORD dwCode, LPSTR msg )
|
||||
static LONG __fastcall _osd_raise (DWORD theCode, const char* theMsg, const char* theStack)
|
||||
{
|
||||
if (msg[0] == '\x03') ++msg;
|
||||
const char* aMsg = theMsg;
|
||||
if (aMsg[0] == '\x03')
|
||||
{
|
||||
++aMsg;
|
||||
}
|
||||
|
||||
switch (dwCode)
|
||||
switch (theCode)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
THROW_OR_JUMP (OSD_Exception_ACCESS_VIOLATION, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ACCESS_VIOLATION, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
THROW_OR_JUMP (OSD_Exception_ARRAY_BOUNDS_EXCEEDED, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ARRAY_BOUNDS_EXCEEDED, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
THROW_OR_JUMP (Standard_ProgramError, msg);
|
||||
THROW_OR_JUMP (Standard_ProgramError, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
THROW_OR_JUMP (OSD_Exception_ILLEGAL_INSTRUCTION, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_ILLEGAL_INSTRUCTION, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
THROW_OR_JUMP (OSD_Exception_IN_PAGE_ERROR, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_IN_PAGE_ERROR, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
THROW_OR_JUMP (Standard_DivideByZero, msg);
|
||||
THROW_OR_JUMP (Standard_DivideByZero, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
THROW_OR_JUMP (OSD_Exception_INT_OVERFLOW, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_INT_OVERFLOW, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
THROW_OR_JUMP (OSD_Exception_INVALID_DISPOSITION, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_INVALID_DISPOSITION, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
THROW_OR_JUMP (OSD_Exception_NONCONTINUABLE_EXCEPTION, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_NONCONTINUABLE_EXCEPTION, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
THROW_OR_JUMP (OSD_Exception_PRIV_INSTRUCTION, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_PRIV_INSTRUCTION, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
THROW_OR_JUMP (OSD_Exception_STACK_OVERFLOW, msg);
|
||||
THROW_OR_JUMP (OSD_Exception_STACK_OVERFLOW, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
THROW_OR_JUMP (Standard_DivideByZero, msg);
|
||||
THROW_OR_JUMP (Standard_DivideByZero, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
THROW_OR_JUMP (Standard_Overflow, msg);
|
||||
THROW_OR_JUMP (Standard_Overflow, aMsg, theStack);
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
THROW_OR_JUMP (Standard_Underflow, msg);
|
||||
THROW_OR_JUMP (Standard_Underflow, aMsg, theStack);
|
||||
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_OR_JUMP (Standard_NumericError, msg);
|
||||
THROW_OR_JUMP (Standard_NumericError, aMsg, theStack);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // end switch
|
||||
}
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
} // end _osd_raise
|
||||
}
|
||||
|
||||
#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
|
||||
//============================================================================
|
||||
@@ -849,32 +905,41 @@ static void Handler (const int theSignal)
|
||||
#ifdef SA_SIGINFO
|
||||
|
||||
static void SegvHandler(const int theSignal,
|
||||
siginfo_t *ip,
|
||||
siginfo_t* theSigInfo,
|
||||
const Standard_Address theContext)
|
||||
{
|
||||
(void)theSignal; // silence GCC warnings
|
||||
(void)theSignal;
|
||||
(void)theContext;
|
||||
if (theSigInfo != NULL)
|
||||
{
|
||||
sigset_t set;
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, SIGSEGV);
|
||||
sigprocmask (SIG_UNBLOCK, &set, NULL);
|
||||
void* anAddress = theSigInfo->si_addr;
|
||||
{
|
||||
char aMsg[100];
|
||||
sprintf (aMsg, "SIGSEGV 'segmentation violation' detected. Address %lx.", (long )anAddress);
|
||||
|
||||
// std::cout << "OSD::SegvHandler activated(SA_SIGINFO)" << std::endl ;
|
||||
if ( ip != NULL ) {
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGSEGV);
|
||||
sigprocmask (SIG_UNBLOCK, &set, NULL) ;
|
||||
void *address = ip->si_addr ;
|
||||
{
|
||||
char Msg[100];
|
||||
sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",
|
||||
(long ) address ) ;
|
||||
OSD_SIGSEGV::NewInstance(Msg)->Jump();
|
||||
}
|
||||
const int aStackLength = OSD_SignalStackTraceLength;
|
||||
const int aStackBufLen = Max (aStackLength * 200, 2048);
|
||||
char* aStackBuffer = aStackLength != 0 ? (char* )alloca (aStackBufLen) : NULL;
|
||||
if (aStackBuffer != NULL)
|
||||
{
|
||||
memset (aStackBuffer, 0, aStackBufLen);
|
||||
Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength);
|
||||
}
|
||||
|
||||
OSD_SIGSEGV::NewInstance (aMsg, aStackBuffer)->Jump();
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
std::cout << "Wrong undefined address." << std::endl ;
|
||||
else
|
||||
{
|
||||
std::cout << "Wrong undefined address." << std::endl;
|
||||
}
|
||||
#endif
|
||||
exit(SIGSEGV);
|
||||
exit (SIGSEGV);
|
||||
}
|
||||
|
||||
#elif defined (_hpux) || defined(HPUX)
|
||||
@@ -882,30 +947,26 @@ static void SegvHandler(const int theSignal,
|
||||
// pour version 09.07
|
||||
|
||||
static void SegvHandler(const int theSignal,
|
||||
siginfo_t *ip,
|
||||
siginfo_t* theSigInfo,
|
||||
const Standard_Address theContext)
|
||||
{
|
||||
unsigned long Space ;
|
||||
unsigned long Offset ;
|
||||
char Msg[100] ;
|
||||
|
||||
if ( theContext != NULL ) {
|
||||
Space = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr20 ;
|
||||
Offset = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr21 ;
|
||||
// std::cout << "Wrong address = " << hex(Offset) << std::endl ;
|
||||
if (theContext != NULL)
|
||||
{
|
||||
unsigned long aSpace = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr20;
|
||||
unsigned long anOffset = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr21;
|
||||
{
|
||||
sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ;
|
||||
OSD_SIGSEGV::Jump(Msg);
|
||||
// scp->sc_pcoq_head = scp->sc_pcoq_tail ; Permettrait de continuer a
|
||||
// scp->sc_pcoq_tail = scp->sc_pcoq_tail + 0x4 ; l'intruction suivant le segv.
|
||||
char aMsg[100];
|
||||
sprintf (aMsg, "SIGSEGV 'segmentation violation' detected. Address %lx", anOffset);
|
||||
OSD_SIGSEGV::NewInstance (aMsg)->Jump();
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
std::cout << "Wrong undefined address." << std::endl ;
|
||||
else
|
||||
{
|
||||
std::cout << "Wrong undefined address." << std::endl;
|
||||
}
|
||||
#endif
|
||||
exit(SIGSEGV);
|
||||
exit (SIGSEGV);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user