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