1
0
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:
kgv
2019-06-03 08:06:24 +03:00
committed by bugmaster
parent 14eea8293d
commit 7fb9d6d573
16 changed files with 1167 additions and 329 deletions

View File

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

View File

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

View File

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