0030609: Coding - eliminate warnings issued by gcc 8.1.0
[occt.git] / src / OSD / OSD_signal.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
7fd59977 13
42cf5bc1 14
15#include <OSD.hxx>
536a3cb8 16#include <OSD_Exception_CTRL_BREAK.hxx>
17#include <Standard_DivideByZero.hxx>
18#include <Standard_Overflow.hxx>
44b80414 19#include <Standard_Assert.hxx>
536a3cb8 20
f4a7308f 21#include <Standard_WarningDisableFunctionCast.hxx>
22
44b80414 23static OSD_SignalMode OSD_WasSetSignal = OSD_SignalMode_AsIs;
6f498847 24
25//=======================================================================
44b80414 26//function : SignalMode
6f498847 27//purpose :
28//=======================================================================
44b80414 29OSD_SignalMode OSD::SignalMode()
6f498847 30{
44b80414 31 return OSD_WasSetSignal;
6f498847 32}
33
536a3cb8 34#ifdef _WIN32
35//---------------------------- Windows NT System --------------------------------
36
536a3cb8 37#ifdef NOUSER
38#undef NOUSER
39#endif
742cc8b0 40#ifdef NONLS
41#undef NONLS
42#endif
536a3cb8 43#include <windows.h>
44
5fecc495 45#include <strsafe.h>
742cc8b0 46
536a3cb8 47#ifndef STATUS_FLOAT_MULTIPLE_FAULTS
48 // <ntstatus.h>
49 #define STATUS_FLOAT_MULTIPLE_FAULTS (0xC00002B4L)
50 #define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L)
51#endif
52
53#include <OSD_Exception_ACCESS_VIOLATION.hxx>
54#include <OSD_Exception_ARRAY_BOUNDS_EXCEEDED.hxx>
55#include <OSD_Exception_ILLEGAL_INSTRUCTION.hxx>
56#include <OSD_Exception_IN_PAGE_ERROR.hxx>
57#include <OSD_Exception_INT_DIVIDE_BY_ZERO.hxx>
58#include <OSD_Exception_INT_OVERFLOW.hxx>
59#include <OSD_Exception_INVALID_DISPOSITION.hxx>
60#include <OSD_Exception_NONCONTINUABLE_EXCEPTION.hxx>
61#include <OSD_Exception_PRIV_INSTRUCTION.hxx>
62#include <OSD_Exception_STACK_OVERFLOW.hxx>
63#include <OSD_Exception_STATUS_NO_MEMORY.hxx>
64
65#include <OSD_Environment.hxx>
66#include <Standard_Underflow.hxx>
67#include <Standard_ProgramError.hxx>
68#include <Standard_Mutex.hxx>
69
68df8478 70#include <OSD_WNT.hxx>
536a3cb8 71
72#ifdef _MSC_VER
73#include <eh.h>
74#include <malloc.h>
75#endif
76
77#include <process.h>
78#include <signal.h>
79#include <float.h>
80
94afca11 81static Standard_Boolean fCtrlBrk;
9e479117 82
536a3cb8 83static Standard_Boolean fMsgBox;
536a3cb8 84
85// used to forbid simultaneous execution of setting / executing handlers
86static Standard_Mutex THE_SIGNAL_MUTEX;
87
88static LONG __fastcall _osd_raise ( DWORD, LPSTR );
89static BOOL WINAPI _osd_ctrl_break_handler ( DWORD );
90
9e479117 91#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
92static Standard_Boolean fDbgLoaded;
536a3cb8 93static LONG _osd_debug ( void );
742cc8b0 94#endif
536a3cb8 95
536a3cb8 96# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW )
97
9e479117 98#ifdef OCC_CONVERT_SIGNALS
99#define THROW_OR_JUMP(Type,Message) Type::NewInstance(Message)->Jump()
100#else
101#define THROW_OR_JUMP(Type,Message) throw Type(Message)
102#endif
103
536a3cb8 104//=======================================================================
105//function : CallHandler
106//purpose :
107//=======================================================================
108static LONG CallHandler (DWORD dwExceptionCode,
109 ptrdiff_t ExceptionInformation1,
110 ptrdiff_t ExceptionInformation0)
111{
536a3cb8 112 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
742cc8b0 113
114 static wchar_t buffer[2048];
115
536a3cb8 116 int flterr = 0;
117
118 buffer[0] = '\0' ;
119
04232180 120// std::cout << "CallHandler " << dwExceptionCode << std::endl ;
536a3cb8 121 switch ( dwExceptionCode ) {
122 case EXCEPTION_FLT_DENORMAL_OPERAND:
04232180 123// std::cout << "CallHandler : EXCEPTION_FLT_DENORMAL_OPERAND:" << std::endl ;
742cc8b0 124 StringCchCopyW (buffer, _countof(buffer), L"FLT DENORMAL OPERAND");
536a3cb8 125 flterr = 1 ;
126 break ;
127 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
04232180 128// std::cout << "CallHandler : EXCEPTION_FLT_DIVIDE_BY_ZERO:" << std::endl ;
742cc8b0 129 StringCchCopyW (buffer, _countof(buffer), L"FLT DIVIDE BY ZERO");
536a3cb8 130 flterr = 1 ;
131 break ;
132 case EXCEPTION_FLT_INEXACT_RESULT:
04232180 133// std::cout << "CallHandler : EXCEPTION_FLT_INEXACT_RESULT:" << std::endl ;
742cc8b0 134 StringCchCopyW (buffer, _countof(buffer), L"FLT INEXACT RESULT");
536a3cb8 135 flterr = 1 ;
136 break ;
137 case EXCEPTION_FLT_INVALID_OPERATION:
04232180 138// std::cout << "CallHandler : EXCEPTION_FLT_INVALID_OPERATION:" << std::endl ;
742cc8b0 139 StringCchCopyW (buffer, _countof(buffer), L"FLT INVALID OPERATION");
536a3cb8 140 flterr = 1 ;
141 break ;
142 case EXCEPTION_FLT_OVERFLOW:
04232180 143// std::cout << "CallHandler : EXCEPTION_FLT_OVERFLOW:" << std::endl ;
742cc8b0 144 StringCchCopyW (buffer, _countof(buffer), L"FLT OVERFLOW");
536a3cb8 145 flterr = 1 ;
146 break ;
147 case EXCEPTION_FLT_STACK_CHECK:
04232180 148// std::cout << "CallHandler : EXCEPTION_FLT_STACK_CHECK:" << std::endl ;
742cc8b0 149 StringCchCopyW (buffer, _countof(buffer), L"FLT STACK CHECK");
536a3cb8 150 flterr = 1 ;
151 break ;
152 case EXCEPTION_FLT_UNDERFLOW:
04232180 153// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
742cc8b0 154 StringCchCopyW (buffer, _countof(buffer), L"FLT UNDERFLOW");
536a3cb8 155 flterr = 1 ;
156 break ;
157 case STATUS_FLOAT_MULTIPLE_TRAPS:
04232180 158// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
742cc8b0 159 StringCchCopyW (buffer, _countof(buffer), L"FLT MULTIPLE TRAPS (possible overflow in conversion of double to integer)");
536a3cb8 160 flterr = 1 ;
161 break ;
162 case STATUS_FLOAT_MULTIPLE_FAULTS:
04232180 163// std::cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << std::endl ;
742cc8b0 164 StringCchCopyW (buffer, _countof(buffer), L"FLT MULTIPLE FAULTS");
536a3cb8 165 flterr = 1 ;
166 break ;
167 case STATUS_NO_MEMORY:
04232180 168// std::cout << "CallHandler : STATUS_NO_MEMORY:" << std::endl ;
9e479117 169 THROW_OR_JUMP (OSD_Exception_STATUS_NO_MEMORY, "MEMORY ALLOCATION ERROR ( no room in the process heap )");
170 break;
536a3cb8 171 case EXCEPTION_ACCESS_VIOLATION:
04232180 172// std::cout << "CallHandler : EXCEPTION_ACCESS_VIOLATION:" << std::endl ;
742cc8b0 173 StringCchPrintfW (buffer, _countof(buffer), L"%s%s%s0x%.8p%s%s%s", L"ACCESS VIOLATION",
174 fMsgBox ? L"\n" : L" ", L"at address ",
536a3cb8 175 ExceptionInformation1 ,
742cc8b0 176 L" during '",
177 ExceptionInformation0 ? L"WRITE" : L"READ",
178 L"' operation");
536a3cb8 179 break;
180 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
04232180 181// std::cout << "CallHandler : EXCEPTION_ARRAY_BOUNDS_EXCEEDED:" << std::endl ;
742cc8b0 182 StringCchCopyW (buffer, _countof(buffer), L"ARRAY BOUNDS EXCEEDED");
536a3cb8 183 break;
184 case EXCEPTION_DATATYPE_MISALIGNMENT:
04232180 185// std::cout << "CallHandler : EXCEPTION_DATATYPE_MISALIGNMENT:" << std::endl ;
742cc8b0 186 StringCchCopyW (buffer, _countof(buffer), L"DATATYPE MISALIGNMENT");
536a3cb8 187 break;
188
189 case EXCEPTION_ILLEGAL_INSTRUCTION:
04232180 190// std::cout << "CallHandler : EXCEPTION_ILLEGAL_INSTRUCTION:" << std::endl ;
742cc8b0 191 StringCchCopyW (buffer, _countof(buffer), L"ILLEGAL INSTRUCTION");
536a3cb8 192 break;
193
194 case EXCEPTION_IN_PAGE_ERROR:
04232180 195// std::cout << "CallHandler : EXCEPTION_IN_PAGE_ERROR:" << std::endl ;
742cc8b0 196 StringCchCopyW (buffer, _countof(buffer), L"IN_PAGE ERROR");
536a3cb8 197 break;
198
199 case EXCEPTION_INT_DIVIDE_BY_ZERO:
04232180 200// std::cout << "CallHandler : EXCEPTION_INT_DIVIDE_BY_ZERO:" << std::endl ;
742cc8b0 201 StringCchCopyW (buffer, _countof(buffer), L"INTEGER DIVISION BY ZERO");
536a3cb8 202 break;
203
204 case EXCEPTION_INT_OVERFLOW:
04232180 205// std::cout << "CallHandler : EXCEPTION_INT_OVERFLOW:" << std::endl ;
742cc8b0 206 StringCchCopyW (buffer, _countof(buffer), L"INTEGER OVERFLOW");
536a3cb8 207 break;
208
209 case EXCEPTION_INVALID_DISPOSITION:
04232180 210// std::cout << "CallHandler : EXCEPTION_INVALID_DISPOSITION:" << std::endl ;
742cc8b0 211 StringCchCopyW (buffer, _countof(buffer), L"INVALID DISPOSITION");
536a3cb8 212 break;
213
214 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
04232180 215// std::cout << "CallHandler : EXCEPTION_NONCONTINUABLE_EXCEPTION:" << std::endl ;
742cc8b0 216 StringCchCopyW (buffer, _countof(buffer), L"NONCONTINUABLE EXCEPTION");
536a3cb8 217 break;
218
219 case EXCEPTION_PRIV_INSTRUCTION:
04232180 220// std::cout << "CallHandler : EXCEPTION_PRIV_INSTRUCTION:" << std::endl ;
742cc8b0 221 StringCchCopyW (buffer, _countof(buffer), L"PRIVELEGED INSTRUCTION ENCOUNTERED");
536a3cb8 222 break;
223
224 case EXCEPTION_STACK_OVERFLOW:
04232180 225// std::cout << "CallHandler : EXCEPTION_STACK_OVERFLOW:" << std::endl ;
742cc8b0 226#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) && !defined(OCCT_UWP)
536a3cb8 227 // try recovering from stack overflow: available in MS VC++ 7.0
228 if (!_resetstkoflw())
742cc8b0 229 StringCchCopyW (buffer, _countof(buffer), L"Unrecoverable STACK OVERFLOW");
536a3cb8 230 else
231#endif
742cc8b0 232 StringCchCopyW (buffer, _countof(buffer), L"STACK OVERFLOW");
536a3cb8 233 break;
234
235 default:
742cc8b0 236 StringCchPrintfW (buffer, _countof(buffer), L"unknown exception code 0x%x, params 0x%p 0x%p",
536a3cb8 237 dwExceptionCode, ExceptionInformation1, ExceptionInformation0 );
238
239 } // end switch
240
44b80414 241 // reset FPE state (before message box, otherwise it may fail to show up)
242 if ( flterr ) {
243 OSD::SetFloatingSignal (Standard_True);
244 }
245
246#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
536a3cb8 247 // provide message to the user with possibility to stop
742cc8b0 248 size_t idx;
249 StringCchLengthW (buffer, _countof(buffer),&idx);
536a3cb8 250 if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) {
536a3cb8 251 MessageBeep ( MB_ICONHAND );
742cc8b0 252 int aChoice = ::MessageBoxW (0, buffer, L"OCCT Exception Handler", MB_ABORTRETRYIGNORE | MB_ICONSTOP);
536a3cb8 253 if (aChoice == IDRETRY)
254 {
255 _osd_debug();
256 DebugBreak();
257 } else if (aChoice == IDABORT)
258 exit(0xFFFF);
536a3cb8 259 }
44b80414 260#endif
742cc8b0 261
262 char aBufferA[2048];
263 WideCharToMultiByte(CP_UTF8, 0, buffer, -1, aBufferA, sizeof(aBufferA), NULL, NULL);
264 return _osd_raise(dwExceptionCode, aBufferA);
536a3cb8 265}
266
267//=======================================================================
268//function : SIGWntHandler
269//purpose : Will only be used if user calls ::raise() function with
270// signal type set in OSD::SetSignal() - SIGSEGV, SIGFPE, SIGILL
271// (the latter will likely be removed in the future)
272//=======================================================================
273static void SIGWntHandler (int signum, int sub_code)
274{
536a3cb8 275 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
276 switch( signum ) {
277 case SIGFPE :
278 if ( signal( signum , (void(*)(int))SIGWntHandler ) == SIG_ERR )
04232180 279 std::cout << "signal error" << std::endl ;
536a3cb8 280 switch( sub_code ) {
281 case _FPE_INVALID :
282 CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ;
283 break ;
284 case _FPE_DENORMAL :
285 CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ;
286 break ;
287 case _FPE_ZERODIVIDE :
288 CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ;
289 break ;
290 case _FPE_OVERFLOW :
291 CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ;
292 break ;
293 case _FPE_UNDERFLOW :
294 CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ;
295 break ;
296 case _FPE_INEXACT :
297 CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ;
298 break ;
299 default:
04232180 300 std::cout << "SIGWntHandler(default) -> throw Standard_NumericError(\"Floating Point Error\");" << std::endl;
9e479117 301 THROW_OR_JUMP (Standard_NumericError, "Floating Point Error");
536a3cb8 302 break ;
303 }
304 break ;
305 case SIGSEGV :
306 if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
04232180 307 std::cout << "signal error" << std::endl ;
536a3cb8 308 CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ;
309 break ;
310 case SIGILL :
311 if ( signal( signum, (void(*)(int))SIGWntHandler ) == SIG_ERR )
04232180 312 std::cout << "signal error" << std::endl ;
536a3cb8 313 CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ;
314 break ;
315 default:
04232180 316 std::cout << "SIGWntHandler unexpected signal : " << signum << std::endl ;
536a3cb8 317 break ;
318 }
742cc8b0 319#ifndef OCCT_UWP
536a3cb8 320 DebugBreak ();
742cc8b0 321#endif
536a3cb8 322}
323
324//=======================================================================
325//function : TranslateSE
326//purpose : Translate Structural Exceptions into C++ exceptions
327// Will be used when user's code is compiled with /EHa option
328//=======================================================================
329#ifdef _MSC_VER
330// If this file compiled with the default MSVC options for exception
331// handling (/GX or /EHsc) then the following warning is issued:
332// warning C4535: calling _set_se_translator() requires /EHa
333// However it is correctly inserted and used when user's code compiled with /EHa.
334// So, here we disable the warning.
335#pragma warning (disable:4535)
336
337static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr )
338{
339 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
340 ptrdiff_t info1 = 0, info0 = 0;
341 if ( theExcPtr ) {
342 info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1];
343 info0 = theExcPtr->ExceptionRecord->ExceptionInformation[0];
344 }
345 CallHandler(theCode, info1, info0);
346}
347#endif
348
349//=======================================================================
350//function : WntHandler
351//purpose : Will be used when user's code is compiled with /EHs
352// option and unless user sets his own exception handler with
353// ::SetUnhandledExceptionFilter().
354//=======================================================================
355static LONG WINAPI WntHandler (EXCEPTION_POINTERS *lpXP)
356{
357 DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
358
359 return CallHandler (dwExceptionCode,
360 lpXP->ExceptionRecord->ExceptionInformation[1],
361 lpXP->ExceptionRecord->ExceptionInformation[0]);
362}
363
44b80414 364//=======================================================================
365//function : SetFloatingSignal
366//purpose :
367//=======================================================================
368void OSD::SetFloatingSignal (Standard_Boolean theFloatingSignal)
369{
370 _fpreset();
371 _clearfp();
372
373 // Note: zero bit means exception will be raised
374 _controlfp (theFloatingSignal ? 0 : _OSD_FPX, _OSD_FPX);
375}
376
377//=======================================================================
378//function : ToCatchFloatingSignals
379//purpose :
380//=======================================================================
381Standard_Boolean OSD::ToCatchFloatingSignals()
382{
383 // return true if at least one of bits within _OSD_FPX
384 // is unset, which means relevant FPE will raise exception
385 int aControlWord = _controlfp (0, 0);
386 return (_OSD_FPX & ~aControlWord) != 0;
387}
388
389//=======================================================================
390//function : SetThreadLocalSignal
391//purpose :
392//=======================================================================
393void OSD::SetThreadLocalSignal (OSD_SignalMode theSignalMode,
394 Standard_Boolean theFloatingSignal)
395{
396#ifdef _MSC_VER
397 _se_translator_function aPreviousFunc = NULL;
398 if (theSignalMode == OSD_SignalMode_Set || theSignalMode == OSD_SignalMode_SetUnhandled)
399 aPreviousFunc = _set_se_translator(TranslateSE);
400 if (theSignalMode == OSD_SignalMode_Unset || (theSignalMode == OSD_SignalMode_SetUnhandled && aPreviousFunc != NULL))
401 _set_se_translator(aPreviousFunc);
402#else
403 (void)theSignalMode;
404#endif
405 SetFloatingSignal (theFloatingSignal);
406}
407
536a3cb8 408//=======================================================================
409//function : SetSignal
410//purpose :
411//=======================================================================
44b80414 412void OSD::SetSignal (OSD_SignalMode theSignalMode,
413 Standard_Boolean theFloatingSignal)
536a3cb8 414{
536a3cb8 415 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
44b80414 416 OSD_WasSetSignal = theSignalMode;
417
1ce0716b 418#if !defined(OCCT_UWP) || defined(NTDDI_WIN10_TH2)
742cc8b0 419 OSD_Environment env ("CSF_DEBUG_MODE");
536a3cb8 420 TCollection_AsciiString val = env.Value();
421 if (!env.Failed())
422 {
04232180 423 std::cout << "Environment variable CSF_DEBUG_MODE setted.\n";
536a3cb8 424 fMsgBox = Standard_True;
425 }
426 else
427 {
428 fMsgBox = Standard_False;
429 }
430
431 // Set exception handler (ignored when running under debugger). It will be used in most cases
432 // when user's code is compiled with /EHs
433 // Replaces the existing top-level exception filter for all existing and all future threads
434 // in the calling process
44b80414 435 {
436 LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFunc = NULL;
437 if (theSignalMode == OSD_SignalMode_Set || theSignalMode == OSD_SignalMode_SetUnhandled)
438 {
439 aPreviousFunc = ::SetUnhandledExceptionFilter(WntHandler);
440 }
441 if (theSignalMode == OSD_SignalMode_Unset || (theSignalMode == OSD_SignalMode_SetUnhandled && aPreviousFunc != NULL))
442 {
443 ::SetUnhandledExceptionFilter(aPreviousFunc);
444 }
445 }
1ce0716b 446#endif // NTDDI_WIN10_TH2
7fd59977 447
44b80414 448 // Signal handlers will only be used when function ::raise() is called
449 const int NBSIG = 3;
450 const int aSignalTypes[NBSIG] = { SIGSEGV, SIGILL, SIGFPE };
451 for (int i = 0; i < NBSIG; ++i)
452 {
453 typedef void (*SignalFuncType)(int); // same as _crt_signal_t available since vc14
454 SignalFuncType aPreviousFunc = SIG_DFL;
455 if (theSignalMode == OSD_SignalMode_Set || theSignalMode == OSD_SignalMode_SetUnhandled)
456 {
457 aPreviousFunc = signal(aSignalTypes[i], (SignalFuncType)SIGWntHandler);
458 }
459 if (theSignalMode == OSD_SignalMode_Unset ||
460 (theSignalMode == OSD_SignalMode_SetUnhandled && aPreviousFunc != SIG_DFL && aPreviousFunc != SIG_ERR))
461 {
462 aPreviousFunc = signal(aSignalTypes[i], aPreviousFunc);
463 }
464 Standard_ASSERT(aPreviousFunc != SIG_ERR, "signal() failed", std::cout << "OSD::SetSignal(): signal() returns SIG_ERR");
465 }
536a3cb8 466
467 // Set Ctrl-C and Ctrl-Break handler
468 fCtrlBrk = Standard_False;
742cc8b0 469#ifndef OCCT_UWP
44b80414 470 if (theSignalMode == OSD_SignalMode_Set || theSignalMode == OSD_SignalMode_SetUnhandled)
536a3cb8 471 {
44b80414 472 SetConsoleCtrlHandler(&_osd_ctrl_break_handler, true);
536a3cb8 473 }
44b80414 474 else if (theSignalMode == OSD_SignalMode_Unset)
475 {
476 SetConsoleCtrlHandler(&_osd_ctrl_break_handler, false);
536a3cb8 477 }
44b80414 478#endif
479
480 SetThreadLocalSignal (theSignalMode, theFloatingSignal);
481}
536a3cb8 482
483//============================================================================
484//==== ControlBreak
485//============================================================================
486void OSD::ControlBreak () {
487 if ( fCtrlBrk ) {
488 fCtrlBrk = Standard_False;
9775fa61 489 throw OSD_Exception_CTRL_BREAK ( "*** INTERRUPT ***" );
536a3cb8 490 }
491} // end OSD :: ControlBreak
9e479117 492
742cc8b0 493#ifndef OCCT_UWP
536a3cb8 494//============================================================================
495//==== _osd_ctrl_break_handler
496//============================================================================
497static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) {
498 if ( dwCode == CTRL_C_EVENT || dwCode == CTRL_BREAK_EVENT ) {
499 MessageBeep ( MB_ICONEXCLAMATION );
500 fCtrlBrk = Standard_True;
501 } else
502 exit ( 254 );
503
504 return TRUE;
505} // end _osd_ctrl_break_handler
742cc8b0 506#endif
9e479117 507
536a3cb8 508//============================================================================
509//==== _osd_raise
510//============================================================================
511static LONG __fastcall _osd_raise ( DWORD dwCode, LPSTR msg )
512{
513 if (msg[0] == '\x03') ++msg;
514
515 switch (dwCode)
516 {
517 case EXCEPTION_ACCESS_VIOLATION:
9e479117 518 THROW_OR_JUMP (OSD_Exception_ACCESS_VIOLATION, msg);
536a3cb8 519 break;
520 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
9e479117 521 THROW_OR_JUMP (OSD_Exception_ARRAY_BOUNDS_EXCEEDED, msg);
536a3cb8 522 break;
523 case EXCEPTION_DATATYPE_MISALIGNMENT:
9e479117 524 THROW_OR_JUMP (Standard_ProgramError, msg);
536a3cb8 525 break;
526 case EXCEPTION_ILLEGAL_INSTRUCTION:
9e479117 527 THROW_OR_JUMP (OSD_Exception_ILLEGAL_INSTRUCTION, msg);
536a3cb8 528 break;
529 case EXCEPTION_IN_PAGE_ERROR:
9e479117 530 THROW_OR_JUMP (OSD_Exception_IN_PAGE_ERROR, msg);
536a3cb8 531 break;
532 case EXCEPTION_INT_DIVIDE_BY_ZERO:
9e479117 533 THROW_OR_JUMP (Standard_DivideByZero, msg);
536a3cb8 534 break;
535 case EXCEPTION_INT_OVERFLOW:
9e479117 536 THROW_OR_JUMP (OSD_Exception_INT_OVERFLOW, msg);
536a3cb8 537 break;
538 case EXCEPTION_INVALID_DISPOSITION:
9e479117 539 THROW_OR_JUMP (OSD_Exception_INVALID_DISPOSITION, msg);
536a3cb8 540 break;
541 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
9e479117 542 THROW_OR_JUMP (OSD_Exception_NONCONTINUABLE_EXCEPTION, msg);
536a3cb8 543 break;
544 case EXCEPTION_PRIV_INSTRUCTION:
9e479117 545 THROW_OR_JUMP (OSD_Exception_PRIV_INSTRUCTION, msg);
536a3cb8 546 break;
547 case EXCEPTION_STACK_OVERFLOW:
9e479117 548 THROW_OR_JUMP (OSD_Exception_STACK_OVERFLOW, msg);
536a3cb8 549 break;
550 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
9e479117 551 THROW_OR_JUMP (Standard_DivideByZero, msg);
536a3cb8 552 break;
553 case EXCEPTION_FLT_STACK_CHECK:
554 case EXCEPTION_FLT_OVERFLOW:
9e479117 555 THROW_OR_JUMP (Standard_Overflow, msg);
536a3cb8 556 break;
557 case EXCEPTION_FLT_UNDERFLOW:
9e479117 558 THROW_OR_JUMP (Standard_Underflow, msg);
536a3cb8 559 break;
560 case EXCEPTION_FLT_INVALID_OPERATION:
561 case EXCEPTION_FLT_DENORMAL_OPERAND:
562 case EXCEPTION_FLT_INEXACT_RESULT:
563 case STATUS_FLOAT_MULTIPLE_TRAPS:
564 case STATUS_FLOAT_MULTIPLE_FAULTS:
9e479117 565 THROW_OR_JUMP (Standard_NumericError, msg);
536a3cb8 566 break;
567 default:
568 break;
569 } // end switch
570 return EXCEPTION_EXECUTE_HANDLER;
571} // end _osd_raise
572
9e479117 573#if ! defined(OCCT_UWP) && !defined(__MINGW32__) && !defined(__CYGWIN32__)
536a3cb8 574//============================================================================
575//==== _osd_debug
576//============================================================================
536a3cb8 577LONG _osd_debug ( void ) {
578
579 LONG action ;
580
581 if ( !fDbgLoaded ) {
582
583 HKEY hKey = NULL;
584 HANDLE hEvent = INVALID_HANDLE_VALUE;
585 DWORD dwKeyType;
586 DWORD dwValueLen;
587 TCHAR keyValue[ MAX_PATH ];
588 TCHAR cmdLine[ MAX_PATH ];
589 SECURITY_ATTRIBUTES sa;
590 PROCESS_INFORMATION pi;
591 STARTUPINFO si;
592
593 __try {
594
595 if ( RegOpenKey (
596 HKEY_LOCAL_MACHINE,
597 TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" ),
598 &hKey
599 ) != ERROR_SUCCESS
600 ) __leave;
601
602 dwValueLen = sizeof ( keyValue );
603
604 if ( RegQueryValueEx (
605 hKey, TEXT( "Debugger" ), NULL, &dwKeyType, ( unsigned char* )keyValue, &dwValueLen
606 ) != ERROR_SUCCESS
607 ) __leave;
608
609 sa.nLength = sizeof ( SECURITY_ATTRIBUTES );
610 sa.lpSecurityDescriptor = NULL;
611 sa.bInheritHandle = TRUE;
612
613 if ( ( hEvent = CreateEvent ( &sa, TRUE, FALSE, NULL ) ) == NULL ) __leave;
614
742cc8b0 615 StringCchPrintf(cmdLine, _countof(cmdLine), keyValue, GetCurrentProcessId(), hEvent);
536a3cb8 616
617 ZeroMemory ( &si, sizeof ( STARTUPINFO ) );
618
619 si.cb = sizeof ( STARTUPINFO );
620 si.dwFlags = STARTF_FORCEONFEEDBACK;
621
04232180 622 // std::cout << "_osd_debug -> CreateProcess" << std::endl ;
536a3cb8 623 if ( !CreateProcess (
624 NULL, cmdLine, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
625 NULL, NULL, &si, &pi
626 )
627 ) __leave;
628
04232180 629 // std::cout << "_osd_debug -> WaitForSingleObject " << std::endl ;
536a3cb8 630 WaitForSingleObject ( hEvent, INFINITE );
04232180 631 // std::cout << "_osd_debug <- WaitForSingleObject -> CloseHandle " << std::endl ;
536a3cb8 632
633 CloseHandle ( pi.hProcess );
634 CloseHandle ( pi.hThread );
635
04232180 636 // std::cout << "_osd_debug fDbgLoaded " << std::endl ;
536a3cb8 637 fDbgLoaded = TRUE;
638
639 } // end __try
640
641 __finally {
642
04232180 643// std::cout << "_osd_debug -> CloseHandle(hKey) " << std::endl ;
536a3cb8 644 if ( hKey != INVALID_HANDLE_VALUE ) CloseHandle ( hKey );
04232180 645// std::cout << "_osd_debug -> CloseHandle(hEvent) " << std::endl ;
536a3cb8 646 if ( hEvent != INVALID_HANDLE_VALUE ) CloseHandle ( hEvent );
04232180 647// std::cout << "_osd_debug end __finally " << std::endl ;
536a3cb8 648
649 } // end __finally
650
651 } /* end if */
652
653 action = fDbgLoaded ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;
04232180 654// std::cout << "_osd_debug return " << action << " EXCEPTION_CONTINUE_EXECUTION("
655// << EXCEPTION_CONTINUE_EXECUTION << ")" << std::endl ;
536a3cb8 656 return action ;
657
658} // end _osd_debug
9e479117 659#endif /* ! OCCT_UWP && ! __CYGWIN__ && ! __MINGW32__ */
536a3cb8 660
9e479117 661#else /* ! _WIN32 */
7fd59977 662
663//---------- All Systems except Windows NT : ----------------------------------
664
7fd59977 665# include <stdio.h>
666
667#include <OSD_WhoAmI.hxx>
668#include <OSD_SIGHUP.hxx>
669#include <OSD_SIGINT.hxx>
670#include <OSD_SIGQUIT.hxx>
671#include <OSD_SIGILL.hxx>
672#include <OSD_SIGKILL.hxx>
673#include <OSD_SIGBUS.hxx>
674#include <OSD_SIGSEGV.hxx>
675#include <OSD_SIGSYS.hxx>
676#include <Standard_NumericError.hxx>
7fd59977 677
678#include <Standard_ErrorHandler.hxx>
679
680// POSIX threads
03155c18 681#include <pthread.h>
7fd59977 682
c381fda2 683#ifdef __linux__
896faa72 684#include <cfenv>
685//#include <fenv.h>
7fd59977 686#endif
687
8a262fa1 688// variable signalling that Control-C has been pressed (SIGINT signal)
689static Standard_Boolean fCtrlBrk;
690
7fd59977 691//const OSD_WhoAmI Iam = OSD_WPackage;
692
693typedef void (ACT_SIGIO_HANDLER)(void) ;
694ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
695
7fd59977 696#ifdef __GNUC__
697# include <stdlib.h>
698# include <stdio.h>
699#else
cda06ac0 700# ifdef SA_SIGINFO
7fd59977 701# include <sys/siginfo.h>
7fd59977 702# endif
703#endif
704typedef void (* SIG_PFV) (int);
705
03155c18 706#include <signal.h>
7fd59977 707
565baee6 708#if !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
9bf6baed 709 #include <sys/signal.h>
710#endif
711
44b80414 712# define _OSD_FPX (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)
713
7fd59977 714//============================================================================
89c4bca8 715//==== Handler
7fd59977 716//==== Catche the differents signals:
717//==== 1- The Fatal signals, which cause the end of process:
718//==== 2- The exceptions which are "signaled" by Raise.
719//==== The Fatal Signals:
720//==== SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGKILL, SIGBUS, SIGSYS
721//==== The Exceptions:
722//==== SIGFPE
723//==== (SUN versions)
724//==== FPE_INTOVF_TRAP // ..... integer overflow
725//==== FPE_INTDIV_TRAP // ..... integer divide by zero
726//==== FPE_FLTINEX_TRAP // ..... [floating inexact result]
727//==== FPE_FLTDIV_TRAP // ..... [floating divide by zero]
728//==== FPE_FLTUND_TRAP // ..... [floating underflow]
729//==== FPE_FLTOPER_TRAP // ..... [floating inexact result]
730//==== FPE_FLTOVF_TRAP // ..... [floating overflow]
731//==== SIGSEGV is handled by "SegvHandler()"
732//============================================================================
7fd59977 733#ifdef SA_SIGINFO
c85385c0 734static void Handler (const int theSignal, siginfo_t */*theSigInfo*/, const Standard_Address /*theContext*/)
89c4bca8 735#else
736static void Handler (const int theSignal)
7fd59977 737#endif
7fd59977 738{
739 struct sigaction oldact, act;
7fd59977 740 // re-install the signal
7fd59977 741 if ( ! sigaction (theSignal, NULL, &oldact) ) {
04232180 742 // std::cout << " signal is " << theSignal << " handler is " << oldact.sa_handler << std::endl;
89c4bca8 743 if (sigaction (theSignal, &oldact, &act)) perror ("sigaction");
744 }
745 else {
746 perror ("sigaction");
7fd59977 747 }
7fd59977 748
04232180 749 // std::cout << "OSD::Handler: signal " << (int) theSignal << " occured inside a try block " << std::endl ;
89c4bca8 750 if ( ADR_ACT_SIGIO_HANDLER != NULL )
751 (*ADR_ACT_SIGIO_HANDLER)() ;
44b80414 752
7fd59977 753 sigset_t set;
754 sigemptyset(&set);
89c4bca8 755 switch (theSignal) {
7fd59977 756 case SIGHUP:
757 OSD_SIGHUP::NewInstance("SIGHUP 'hangup' detected.")->Jump();
758 exit(SIGHUP);
759 break;
7fd59977 760 case SIGINT:
8a262fa1 761 // For safe handling of Control-C as stop event, arm a variable but do not
762 // generate longjump (we are out of context anyway)
763 fCtrlBrk = Standard_True;
89c4bca8 764 // OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump();
765 // exit(SIGINT);
7fd59977 766 break;
7fd59977 767 case SIGQUIT:
768 OSD_SIGQUIT::NewInstance("SIGQUIT 'quit' detected.")->Jump();
769 exit(SIGQUIT);
770 break;
7fd59977 771 case SIGILL:
772 OSD_SIGILL::NewInstance("SIGILL 'illegal instruction' detected.")->Jump();
773 exit(SIGILL);
774 break;
7fd59977 775 case SIGKILL:
776 OSD_SIGKILL::NewInstance("SIGKILL 'kill' detected.")->Jump();
777 exit(SIGKILL);
778 break;
7fd59977 779 case SIGBUS:
780 sigaddset(&set, SIGBUS);
781 sigprocmask(SIG_UNBLOCK, &set, NULL) ;
782 OSD_SIGBUS::NewInstance("SIGBUS 'bus error' detected.")->Jump();
783 exit(SIGBUS);
784 break;
7fd59977 785 case SIGSEGV:
786 OSD_SIGSEGV::NewInstance("SIGSEGV 'segmentation violation' detected.")->Jump();
787 exit(SIGSEGV);
788 break;
7fd59977 789#ifdef SIGSYS
790 case SIGSYS:
791 OSD_SIGSYS::NewInstance("SIGSYS 'bad argument to system call' detected.")->Jump();
792 exit(SIGSYS);
793 break;
794#endif
89c4bca8 795 case SIGFPE:
7fd59977 796 sigaddset(&set, SIGFPE);
797 sigprocmask(SIG_UNBLOCK, &set, NULL) ;
44b80414 798#ifdef __linux__
799 OSD::SetFloatingSignal (Standard_True);
89c4bca8 800#endif
7fd59977 801#if (!defined (__sun)) && (!defined(SOLARIS))
802 Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump();
803 break;
804#else
805 // Reste SOLARIS
89c4bca8 806 if (aSigInfo) {
7fd59977 807 switch(aSigInfo->si_code) {
808 case FPE_FLTDIV_TRAP :
89c4bca8 809 Standard_DivideByZero::NewInstance("Floating Divide By Zero")->Jump();
810 break;
7fd59977 811 case FPE_INTDIV_TRAP :
89c4bca8 812 Standard_DivideByZero::NewInstance("Integer Divide By Zero")->Jump();
813 break;
7fd59977 814 case FPE_FLTOVF_TRAP :
89c4bca8 815 Standard_Overflow::NewInstance("Floating Overflow")->Jump();
816 break;
7fd59977 817 case FPE_INTOVF_TRAP :
89c4bca8 818 Standard_Overflow::NewInstance("Integer Overflow")->Jump();
819 break;
7fd59977 820 case FPE_FLTUND_TRAP :
89c4bca8 821 Standard_NumericError::NewInstance("Floating Underflow")->Jump();
822 break;
7fd59977 823 case FPE_FLTRES_TRAP:
89c4bca8 824 Standard_NumericError::NewInstance("Floating Point Inexact Result")->Jump();
825 break;
7fd59977 826 case FPE_FLTINV_TRAP :
89c4bca8 827 Standard_NumericError::NewInstance("Invalid Floating Point Operation")->Jump();
828 break;
7fd59977 829 default:
89c4bca8 830 Standard_NumericError::NewInstance("Numeric Error")->Jump();
831 break;
7fd59977 832 }
89c4bca8 833 } else {
7fd59977 834 Standard_NumericError::NewInstance("SIGFPE Arithmetic exception detected")->Jump();
835 }
836#endif
837 break;
7fd59977 838 default:
0797d9d3 839#ifdef OCCT_DEBUG
04232180 840 std::cout << "Unexpected signal " << theSignal << std::endl ;
63c629aa 841#endif
89c4bca8 842 break;
8a262fa1 843 }
844}
845
7fd59977 846//============================================================================
89c4bca8 847//==== SegvHandler
7fd59977 848//============================================================================
7fd59977 849#ifdef SA_SIGINFO
850
89c4bca8 851static void SegvHandler(const int theSignal,
852 siginfo_t *ip,
853 const Standard_Address theContext)
7fd59977 854{
04e93070 855 (void)theSignal; // silence GCC warnings
856 (void)theContext;
9775fa61 857
04232180 858// std::cout << "OSD::SegvHandler activated(SA_SIGINFO)" << std::endl ;
7fd59977 859 if ( ip != NULL ) {
860 sigset_t set;
861 sigemptyset(&set);
862 sigaddset(&set, SIGSEGV);
863 sigprocmask (SIG_UNBLOCK, &set, NULL) ;
89c4bca8 864 void *address = ip->si_addr ;
4d9421a9 865 {
7fd59977 866 char Msg[100];
867 sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",
89c4bca8 868 (long ) address ) ;
7fd59977 869 OSD_SIGSEGV::NewInstance(Msg)->Jump();
870 }
89c4bca8 871 }
0797d9d3 872#ifdef OCCT_DEBUG
89c4bca8 873 else {
04232180 874 std::cout << "Wrong undefined address." << std::endl ;
89c4bca8 875 }
63c629aa 876#endif
7fd59977 877 exit(SIGSEGV);
878}
879
89c4bca8 880#elif defined (_hpux) || defined(HPUX)
7fd59977 881// Not ACTIVE ? SA_SIGINFO is defined on SUN, OSF, SGI and HP (and Linux) !
882// pour version 09.07
89c4bca8 883
884static void SegvHandler(const int theSignal,
885 siginfo_t *ip,
886 const Standard_Address theContext)
7fd59977 887{
888 unsigned long Space ;
889 unsigned long Offset ;
890 char Msg[100] ;
891
89c4bca8 892 if ( theContext != NULL ) {
893 Space = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr20 ;
894 Offset = ((struct sigcontext *)theContext)->sc_sl.sl_ss.ss_cr21 ;
04232180 895// std::cout << "Wrong address = " << hex(Offset) << std::endl ;
4d9421a9 896 {
89c4bca8 897 sprintf(Msg,"SIGSEGV 'segmentation violation' detected. Address %lx",Offset) ;
898 OSD_SIGSEGV::Jump(Msg);
7fd59977 899// scp->sc_pcoq_head = scp->sc_pcoq_tail ; Permettrait de continuer a
900// scp->sc_pcoq_tail = scp->sc_pcoq_tail + 0x4 ; l'intruction suivant le segv.
901 }
902 }
0797d9d3 903#ifdef OCCT_DEBUG
89c4bca8 904 else {
04232180 905 std::cout << "Wrong undefined address." << std::endl ;
89c4bca8 906 }
63c629aa 907#endif
7fd59977 908 exit(SIGSEGV);
89c4bca8 909}
910
911#endif
912
44b80414 913//=======================================================================
914//function : SetFloatingSignal
915//purpose :
916//=======================================================================
917void OSD::SetFloatingSignal (Standard_Boolean theFloatingSignal)
89c4bca8 918{
44b80414 919#if defined (__linux__)
920 feclearexcept (FE_ALL_EXCEPT);
921 if (theFloatingSignal)
922 {
923 feenableexcept (_OSD_FPX);
89c4bca8 924 }
66cfcd0f 925 else
926 {
44b80414 927 fedisableexcept (_OSD_FPX);
89c4bca8 928 }
44b80414 929#elif defined (__sun) || defined (SOLARIS)
930 int aSunStat = 0;
931 sigfpe_handler_type anFpeHandler = (theFloatingSignal ? (sigfpe_handler_type)Handler : NULL);
932 aSunStat = ieee_handler ("set", "invalid", anFpeHandler);
933 aSunStat = ieee_handler ("set", "division", anFpeHandler) || aSunStat;
934 aSunStat = ieee_handler ("set", "overflow", anFpeHandler) || aSunStat;
935 if (aSunStat)
936 {
0797d9d3 937#ifdef OCCT_DEBUG
44b80414 938 std::cerr << "ieee_handler does not work !!! KO\n";
63c629aa 939#endif
89c4bca8 940 }
44b80414 941#else
942 (void)theFloatingSignal;
89c4bca8 943#endif
44b80414 944}
89c4bca8 945
44b80414 946//=======================================================================
947//function : ToCatchFloatingSignals
948//purpose :
949//=======================================================================
950Standard_Boolean OSD::ToCatchFloatingSignals()
951{
952#if defined (__linux__)
953 return (fegetexcept() & _OSD_FPX) != 0;
954#else
955 return Standard_False;
89c4bca8 956#endif
44b80414 957}
89c4bca8 958
44b80414 959//=======================================================================
960//function : SetThreadLocalSignal
961//purpose :
962//=======================================================================
963void OSD::SetThreadLocalSignal (OSD_SignalMode /*theSignalMode*/,
964 Standard_Boolean theFloatingSignal)
965{
966 SetFloatingSignal (theFloatingSignal);
967}
89c4bca8 968
44b80414 969//============================================================================
970//==== SetSignal
971//==== Set the differents signals:
972//============================================================================
89c4bca8 973
44b80414 974void OSD::SetSignal (OSD_SignalMode theSignalMode,
975 Standard_Boolean theFloatingSignal)
976{
977 SetFloatingSignal (theFloatingSignal);
89c4bca8 978
44b80414 979 OSD_WasSetSignal = theSignalMode;
980 if (theSignalMode == OSD_SignalMode_AsIs)
981 {
982 return; // nothing to be done with signal handlers
983 }
89c4bca8 984
44b80414 985 // Prepare signal descriptors
986 struct sigaction anActSet, anActDfl, anActOld;
987 sigemptyset(&anActSet.sa_mask);
988 sigemptyset(&anActDfl.sa_mask);
989 sigemptyset(&anActOld.sa_mask);
990#ifdef SA_RESTART
991 anActSet.sa_flags = anActDfl.sa_flags = anActOld.sa_flags = SA_RESTART;
992#else
993 anActSet.sa_flags = anActDfl.sa_flags = anActOld.sa_flags = 0;
89c4bca8 994#endif
89c4bca8 995#ifdef SA_SIGINFO
44b80414 996 anActSet.sa_flags = anActSet.sa_flags | SA_SIGINFO;
997 anActSet.sa_sigaction = Handler;
7fd59977 998#else
44b80414 999 anActSet.sa_handler = Handler;
89c4bca8 1000#endif
44b80414 1001 anActDfl.sa_handler = SIG_DFL;
7fd59977 1002
44b80414 1003 // Set signal handlers; NB: SIGSEGV must be the last one!
1004 const int NBSIG = 8;
1005 const int aSignalTypes[NBSIG] = { SIGFPE, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSYS, SIGSEGV };
1006 for (int i = 0; i < NBSIG; ++i)
1007 {
1008 // SIGSEGV has special handler
1009 if (aSignalTypes[i] == SIGSEGV)
1010 {
1011#ifdef SA_SIGINFO
1012 anActSet.sa_sigaction = /*(void(*)(int, siginfo_t *, void*))*/ SegvHandler;
1013#else
1014 anActSet.sa_handler = /*(SIG_PFV)*/ SegvHandler;
7fd59977 1015#endif
44b80414 1016 }
89c4bca8 1017
44b80414 1018 // set handler according to specified mode and current handler
1019 int retcode = -1;
1020 if (theSignalMode == OSD_SignalMode_Set || theSignalMode == OSD_SignalMode_SetUnhandled)
1021 {
1022 retcode = sigaction (aSignalTypes[i], &anActSet, &anActOld);
1023 }
1024 else if (theSignalMode == OSD_SignalMode_Unset)
1025 {
1026 retcode = sigaction (aSignalTypes[i], &anActDfl, &anActOld);
1027 }
1028 if (theSignalMode == OSD_SignalMode_SetUnhandled && retcode == 0 && anActOld.sa_handler != SIG_DFL)
1029 {
1030 retcode = sigaction (aSignalTypes[i], &anActOld, &anActOld);
1031 }
1032 Standard_ASSERT(retcode == 0, "sigaction() failed", std::cout << "OSD::SetSignal(): sigaction() failed for " << aSignalTypes[i] << std::endl);
1033 }
89c4bca8 1034}
1035
1036//============================================================================
cda06ac0 1037//==== ControlBreak
89c4bca8 1038//============================================================================
1039
cda06ac0 1040void OSD :: ControlBreak ()
89c4bca8 1041{
1042 if ( fCtrlBrk ) {
1043 fCtrlBrk = Standard_False;
9e479117 1044 throw OSD_Exception_CTRL_BREAK ("*** INTERRUPT ***");
89c4bca8 1045 }
1046}
1047
7fd59977 1048#endif