Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // | |
3 | // The content of this file is subject to the Open CASCADE Technology Public | |
4 | // License Version 6.5 (the "License"). You may not use the content of this file | |
5 | // except in compliance with the License. Please obtain a copy of the License | |
6 | // at http://www.opencascade.org and read it completely before using this file. | |
7 | // | |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
10 | // | |
11 | // The Original Code and all software distributed under the License is | |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
13 | // Initial Developer hereby disclaims all such warranties, including without | |
14 | // limitation, any warranties of merchantability, fitness for a particular | |
15 | // purpose or non-infringement. Please see the License for the specific terms | |
16 | // and conditions governing the rights and limitations under the License. | |
17 | ||
7fd59977 | 18 | |
19 | #include <OSD.ixx> | |
20 | ||
b2d3f231 | 21 | #ifdef _WIN32 |
7fd59977 | 22 | |
23 | //---------------------------- Windows NT System -------------------------------- | |
24 | ||
25 | #define STRICT | |
26 | #ifdef NOUSER | |
27 | #undef NOUSER | |
28 | #endif | |
29 | #include <windows.h> | |
30 | ||
31 | #include <OSD_Exception_ACCESS_VIOLATION.hxx> | |
32 | #include <OSD_Exception_ARRAY_BOUNDS_EXCEEDED.hxx> | |
33 | #include <OSD_Exception_ILLEGAL_INSTRUCTION.hxx> | |
34 | #include <OSD_Exception_IN_PAGE_ERROR.hxx> | |
35 | #include <OSD_Exception_INT_DIVIDE_BY_ZERO.hxx> | |
36 | #include <OSD_Exception_INT_OVERFLOW.hxx> | |
37 | #include <OSD_Exception_INVALID_DISPOSITION.hxx> | |
38 | #include <OSD_Exception_NONCONTINUABLE_EXCEPTION.hxx> | |
39 | #include <OSD_Exception_PRIV_INSTRUCTION.hxx> | |
40 | #include <OSD_Exception_STACK_OVERFLOW.hxx> | |
41 | #include <OSD_Exception_STATUS_NO_MEMORY.hxx> | |
42 | #include <OSD_Exception_CTRL_BREAK.hxx> | |
43 | ||
44 | #include <OSD_Environment.hxx> | |
45 | #include <Standard_Underflow.hxx> | |
46 | #include <Standard_DivideByZero.hxx> | |
47 | #include <Standard_Overflow.hxx> | |
48 | #include <Standard_ProgramError.hxx> | |
0ac0c8b4 | 49 | #include <Standard_Mutex.hxx> |
7fd59977 | 50 | |
51 | #include <OSD_WNT_1.hxx> | |
52 | ||
53 | #ifdef _MSC_VER | |
54 | #include <eh.h> | |
55 | #include <malloc.h> | |
56 | #endif | |
57 | ||
58 | #include <process.h> | |
59 | #include <signal.h> | |
60 | #include <float.h> | |
61 | ||
62 | static Standard_Boolean fMsgBox; | |
63 | static Standard_Boolean fFltExceptions; | |
64 | static Standard_Boolean fDbgLoaded; | |
65 | static Standard_Boolean fCtrlBrk; | |
66 | ||
0ac0c8b4 RL |
67 | // used to forbid simultaneous execution of setting / executing handlers |
68 | static Standard_Mutex THE_SIGNAL_MUTEX; | |
69 | ||
7fd59977 | 70 | static LONG __fastcall _osd_raise ( DWORD, LPTSTR ); |
71 | static BOOL WINAPI _osd_ctrl_break_handler ( DWORD ); | |
72 | ||
b2d3f231 | 73 | static LONG _osd_debug ( void ); |
7fd59977 | 74 | |
75 | MB_DESC fatalErrorDesc[] = { | |
0ac0c8b4 | 76 | |
7fd59977 | 77 | { MBT_ICON, ( int )IDI_HAND }, |
78 | { MBT_BUTTON, IDYES, TEXT( "Continue" ) }, | |
79 | { MBT_BUTTON, IDNO, TEXT( "Debugger" ) }, | |
80 | { MBT_BUTTON, IDCANCEL, TEXT( "Stop" ) } | |
81 | ||
82 | }; | |
83 | ||
7fd59977 | 84 | //# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW ) |
85 | # define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW ) | |
86 | ||
0ac0c8b4 RL |
87 | //======================================================================= |
88 | //function : CallHandler | |
89 | //purpose : | |
90 | //======================================================================= | |
91 | static LONG CallHandler (DWORD dwExceptionCode, | |
92 | ptrdiff_t ExceptionInformation1, | |
93 | ptrdiff_t ExceptionInformation0) | |
7fd59977 | 94 | { |
95 | ||
96 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) | |
97 | ||
0ac0c8b4 | 98 | Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling |
7fd59977 | 99 | static TCHAR buffer[ 2048 ]; |
100 | int flterr = 0; | |
101 | ||
102 | buffer[0] = '\0' ; | |
103 | ||
104 | // cout << "CallHandler " << dwExceptionCode << endl ; | |
105 | switch ( dwExceptionCode ) { | |
106 | ||
107 | case EXCEPTION_FLT_DENORMAL_OPERAND: | |
108 | // cout << "CallHandler : EXCEPTION_FLT_DENORMAL_OPERAND:" << endl ; | |
109 | lstrcpy ( buffer, TEXT( "FLT DENORMAL OPERAND" ) ); | |
110 | flterr = 1 ; | |
111 | break ; | |
112 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: | |
113 | // cout << "CallHandler : EXCEPTION_FLT_DIVIDE_BY_ZERO:" << endl ; | |
114 | lstrcpy ( buffer, TEXT( "FLT DIVIDE BY ZERO" ) ); | |
115 | flterr = 1 ; | |
116 | break ; | |
117 | case EXCEPTION_FLT_INEXACT_RESULT: | |
118 | // cout << "CallHandler : EXCEPTION_FLT_INEXACT_RESULT:" << endl ; | |
119 | lstrcpy ( buffer, TEXT( "FLT INEXACT RESULT" ) ); | |
120 | flterr = 1 ; | |
121 | break ; | |
122 | case EXCEPTION_FLT_INVALID_OPERATION: | |
123 | // cout << "CallHandler : EXCEPTION_FLT_INVALID_OPERATION:" << endl ; | |
124 | lstrcpy ( buffer, TEXT( "FLT INVALID OPERATION" ) ); | |
125 | flterr = 1 ; | |
126 | break ; | |
127 | case EXCEPTION_FLT_OVERFLOW: | |
128 | // cout << "CallHandler : EXCEPTION_FLT_OVERFLOW:" << endl ; | |
129 | lstrcpy ( buffer, TEXT( "FLT OVERFLOW" ) ); | |
130 | flterr = 1 ; | |
131 | break ; | |
132 | case EXCEPTION_FLT_STACK_CHECK: | |
133 | // cout << "CallHandler : EXCEPTION_FLT_STACK_CHECK:" << endl ; | |
134 | lstrcpy ( buffer, TEXT( "FLT STACK CHECK" ) ); | |
135 | flterr = 1 ; | |
136 | break ; | |
137 | case EXCEPTION_FLT_UNDERFLOW: | |
138 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; | |
139 | lstrcpy ( buffer, TEXT( "FLT UNDERFLOW" ) ); | |
140 | flterr = 1 ; | |
141 | break ; | |
142 | case STATUS_FLOAT_MULTIPLE_TRAPS: | |
143 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; | |
144 | lstrcpy ( buffer, TEXT( "FLT MULTIPLE TRAPS (possible overflow in conversion of double to integer)" ) ); | |
145 | flterr = 1 ; | |
146 | break ; | |
147 | case STATUS_FLOAT_MULTIPLE_FAULTS: | |
148 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; | |
149 | lstrcpy ( buffer, TEXT( "FLT MULTIPLE FAULTS" ) ); | |
150 | flterr = 1 ; | |
151 | break ; | |
152 | ||
153 | case STATUS_NO_MEMORY: | |
154 | // cout << "CallHandler : STATUS_NO_MEMORY:" << endl ; | |
155 | OSD_Exception_STATUS_NO_MEMORY :: | |
156 | Raise ( TEXT( "MEMORY ALLOCATION ERROR ( no room in the process heap )" ) ); | |
157 | ||
158 | case EXCEPTION_ACCESS_VIOLATION: | |
159 | // cout << "CallHandler : EXCEPTION_ACCESS_VIOLATION:" << endl ; | |
160 | wsprintf ( buffer, TEXT( "%s%s%s0x%.8p%s%s%s" ), TEXT( "ACCESS VIOLATION" ), | |
161 | fMsgBox ? "\n" : " ", TEXT( "at address " ), | |
162 | ExceptionInformation1 , | |
163 | TEXT( " during '" ), | |
164 | ExceptionInformation0 ? TEXT( "WRITE" ) : TEXT( "READ" ), | |
165 | TEXT( "' operation" )); | |
166 | break; | |
167 | ||
168 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | |
169 | // cout << "CallHandler : EXCEPTION_ARRAY_BOUNDS_EXCEEDED:" << endl ; | |
170 | lstrcpy ( buffer, TEXT( "ARRAY BOUNDS EXCEEDED" ) ); | |
171 | break; | |
172 | ||
173 | case EXCEPTION_DATATYPE_MISALIGNMENT: | |
174 | // cout << "CallHandler : EXCEPTION_DATATYPE_MISALIGNMENT:" << endl ; | |
175 | lstrcpy ( buffer, TEXT( "DATATYPE MISALIGNMENT" ) ); | |
176 | break; | |
177 | ||
178 | case EXCEPTION_ILLEGAL_INSTRUCTION: | |
179 | // cout << "CallHandler : EXCEPTION_ILLEGAL_INSTRUCTION:" << endl ; | |
180 | lstrcpy ( buffer, TEXT( "ILLEGAL INSTRUCTION" ) ); | |
181 | break; | |
182 | ||
183 | case EXCEPTION_IN_PAGE_ERROR: | |
184 | // cout << "CallHandler : EXCEPTION_IN_PAGE_ERROR:" << endl ; | |
185 | lstrcpy ( buffer, TEXT( "IN_PAGE ERROR" ) ); | |
186 | break; | |
187 | ||
188 | case EXCEPTION_INT_DIVIDE_BY_ZERO: | |
189 | // cout << "CallHandler : EXCEPTION_INT_DIVIDE_BY_ZERO:" << endl ; | |
190 | lstrcpy ( buffer, TEXT( "INTEGER DIVISION BY ZERO" ) ); | |
191 | break; | |
192 | ||
193 | case EXCEPTION_INT_OVERFLOW: | |
194 | // cout << "CallHandler : EXCEPTION_INT_OVERFLOW:" << endl ; | |
195 | lstrcpy ( buffer, TEXT( "INTEGER OVERFLOW" ) ); | |
196 | break; | |
197 | ||
198 | case EXCEPTION_INVALID_DISPOSITION: | |
199 | // cout << "CallHandler : EXCEPTION_INVALID_DISPOSITION:" << endl ; | |
200 | lstrcpy ( buffer, TEXT( "INVALID DISPOSITION" ) ); | |
201 | break; | |
202 | ||
203 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: | |
204 | // cout << "CallHandler : EXCEPTION_NONCONTINUABLE_EXCEPTION:" << endl ; | |
205 | lstrcpy ( buffer, TEXT( "NONCONTINUABLE EXCEPTION" ) ); | |
206 | break; | |
207 | ||
208 | case EXCEPTION_PRIV_INSTRUCTION: | |
209 | // cout << "CallHandler : EXCEPTION_PRIV_INSTRUCTION:" << endl ; | |
210 | lstrcpy ( buffer, TEXT( "PRIVELEGED INSTRUCTION ENCOUNTERED" ) ); | |
211 | break; | |
212 | ||
213 | case EXCEPTION_STACK_OVERFLOW: | |
214 | // cout << "CallHandler : EXCEPTION_STACK_OVERFLOW:" << endl ; | |
215 | #if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) | |
216 | // try recovering from stack overflow: available in MS VC++ 7.0 | |
217 | if (!_resetstkoflw()) | |
218 | lstrcpy ( buffer, TEXT( "Unrecoverable STACK OVERFLOW" ) ); | |
219 | else | |
220 | #endif | |
221 | lstrcpy ( buffer, TEXT( "STACK OVERFLOW" ) ); | |
222 | break; | |
223 | ||
224 | default: | |
225 | wsprintf( buffer, TEXT("unknown exception code 0x%x, params 0x%p 0x%p"), | |
226 | dwExceptionCode, ExceptionInformation1, ExceptionInformation0 ); | |
227 | ||
228 | } // end switch | |
229 | ||
b2d3f231 | 230 | // provide message to the user with possibility to stop |
7fd59977 | 231 | int idx = lstrlen ( buffer ); |
7fd59977 | 232 | if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) { |
0ac0c8b4 RL |
233 | // reset FP operations before message box, otherwise it may fail to show up |
234 | _fpreset(); | |
235 | _clearfp(); | |
236 | ||
b2d3f231 | 237 | MessageBeep ( MB_ICONHAND ); |
238 | int aChoice = ::MessageBox (0, buffer, "OCCT Exception Handler", MB_ABORTRETRYIGNORE | MB_ICONSTOP); | |
239 | if (aChoice == IDRETRY) | |
240 | { | |
241 | _osd_debug(); | |
242 | DebugBreak(); | |
243 | } | |
244 | else if (aChoice == IDABORT) | |
245 | exit(0xFFFF); | |
7fd59977 | 246 | } |
b2d3f231 | 247 | |
248 | // reset FPE state | |
249 | if ( flterr ) { | |
250 | if ( !fFltExceptions ) | |
251 | return EXCEPTION_EXECUTE_HANDLER; | |
252 | _fpreset () ; | |
253 | _clearfp() ; | |
254 | _controlfp ( 0, _OSD_FPX ) ; // JR add : | |
7fd59977 | 255 | // cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ; |
7fd59977 | 256 | } |
7fd59977 | 257 | return _osd_raise ( dwExceptionCode, buffer ); |
7fd59977 | 258 | #else |
259 | return 0; | |
260 | #endif | |
0ac0c8b4 RL |
261 | } |
262 | ||
263 | //======================================================================= | |
264 | //function : SIGWntHandler | |
265 | //purpose : Will only be used if user calls ::raise() function with | |
266 | // signal type set in OSD::SetSignal() - SIGSEGV, SIGFPE, SIGILL | |
267 | // (the latter will likely be removed in the future) | |
268 | //======================================================================= | |
269 | static void SIGWntHandler (int signum, int sub_code) | |
270 | { | |
271 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) | |
272 | Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling | |
273 | switch( signum ) { | |
274 | case SIGFPE : | |
275 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) | |
276 | cout << "signal error" << endl ; | |
277 | switch( sub_code ) { | |
278 | case _FPE_INVALID : | |
279 | CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ; | |
280 | break ; | |
281 | case _FPE_DENORMAL : | |
282 | CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ; | |
283 | break ; | |
284 | case _FPE_ZERODIVIDE : | |
285 | CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ; | |
286 | break ; | |
287 | case _FPE_OVERFLOW : | |
288 | CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ; | |
289 | break ; | |
290 | case _FPE_UNDERFLOW : | |
291 | CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ; | |
292 | break ; | |
293 | case _FPE_INEXACT : | |
294 | CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ; | |
295 | break ; | |
296 | default: | |
297 | cout << "SIGWntHandler(default) -> Standard_NumericError::Raise(\"Floating Point Error\");" | |
298 | << endl ; | |
299 | Standard_NumericError::Raise("Floating Point Error"); | |
300 | break ; | |
301 | } | |
302 | break ; | |
303 | case SIGSEGV : | |
304 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) | |
305 | cout << "signal error" << endl ; | |
306 | CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ; | |
307 | break ; | |
308 | case SIGILL : | |
309 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) | |
310 | cout << "signal error" << endl ; | |
311 | CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ; | |
312 | break ; | |
313 | default: | |
314 | cout << "SIGWntHandler unexpected signal : " | |
315 | << signum << endl ; | |
316 | break ; | |
317 | } | |
318 | DebugBreak (); | |
319 | #endif | |
320 | } | |
321 | ||
322 | //======================================================================= | |
323 | //function : WntHandler | |
324 | //purpose : Will be used when user's code is compiled with /EHs | |
325 | // option and unless user sets his own exception handler with | |
326 | // ::SetUnhandledExceptionFilter(). | |
327 | //======================================================================= | |
328 | Standard_Integer OSD::WntHandler (const Standard_Address theExceptionInfo) | |
329 | { | |
330 | LPEXCEPTION_POINTERS lpXP = (LPEXCEPTION_POINTERS )theExceptionInfo; | |
331 | DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode; | |
7fd59977 | 332 | |
0ac0c8b4 RL |
333 | return CallHandler (dwExceptionCode, |
334 | lpXP->ExceptionRecord->ExceptionInformation[1], | |
335 | lpXP->ExceptionRecord->ExceptionInformation[0]); | |
336 | } | |
7fd59977 | 337 | |
338 | //======================================================================= | |
339 | //function : TranslateSE | |
340 | //purpose : Translate Structural Exceptions into C++ exceptions | |
0ac0c8b4 | 341 | // Will be used when user's code is compiled with /EHa option |
7fd59977 | 342 | //======================================================================= |
7fd59977 | 343 | #ifdef _MSC_VER |
0ac0c8b4 RL |
344 | |
345 | // If this file compiled with the default MSVC options for exception | |
346 | // handling (/GX or /EHsc) then the following warning is issued: | |
347 | // warning C4535: calling _set_se_translator() requires /EHa | |
348 | // However it is correctly inserted and used when user's code compiled with /EHa. | |
349 | // So, here we disable the warning. | |
350 | #pragma warning (disable:4535) | |
351 | ||
7fd59977 | 352 | static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr ) |
353 | { | |
0ac0c8b4 | 354 | Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling |
7fd59977 | 355 | ptrdiff_t info1 = 0, info0 = 0; |
356 | if ( theExcPtr ) { | |
357 | info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1]; | |
358 | info0 = theExcPtr->ExceptionRecord->ExceptionInformation[0]; | |
359 | } | |
360 | CallHandler(theCode, info1, info0); | |
361 | } | |
362 | #endif | |
363 | ||
0ac0c8b4 RL |
364 | //======================================================================= |
365 | //function : SetSignal | |
366 | //purpose : | |
367 | //======================================================================= | |
368 | void OSD::SetSignal (const Standard_Boolean theFloatingSignal) | |
369 | { | |
7fd59977 | 370 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) |
0ac0c8b4 RL |
371 | Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling |
372 | LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter; | |
373 | ||
374 | OSD_Environment env (TEXT("CSF_DEBUG_MODE")); | |
375 | TCollection_AsciiString val = env.Value(); | |
376 | if (!env.Failed()) | |
377 | { | |
378 | cout << "Environment variable CSF_DEBUG_MODE setted.\n"; | |
379 | fMsgBox = Standard_True; | |
380 | } | |
381 | else | |
382 | { | |
383 | fMsgBox = Standard_False; | |
384 | } | |
7fd59977 | 385 | |
0ac0c8b4 RL |
386 | // Set exception handler (ignored when running under debugger). It will be used in most cases |
387 | // when user's code is compiled with /EHs | |
388 | // Replaces the existing top-level exception filter for all existing and all future threads | |
389 | // in the calling process | |
390 | aPreviousFilter = ::SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER )&OSD::WntHandler); | |
391 | ||
392 | // Signal handlers will only be used when the method ::raise() will be used | |
393 | // Handlers must be set for every thread | |
394 | if (signal (SIGSEGV, (void (*)(int ) )&SIGWntHandler) == SIG_ERR) | |
395 | cout << "signal(OSD::SetSignal) error\n"; | |
396 | if (signal (SIGFPE, (void (*)(int ) )&SIGWntHandler) == SIG_ERR) | |
397 | cout << "signal(OSD::SetSignal) error\n"; | |
398 | if (signal (SIGILL, (void (*)(int ) )&SIGWntHandler) == SIG_ERR) | |
399 | cout << "signal(OSD::SetSignal) error\n"; | |
400 | ||
401 | // Set Ctrl-C and Ctrl-Break handler | |
402 | fCtrlBrk = Standard_False; | |
403 | SetConsoleCtrlHandler (&_osd_ctrl_break_handler, TRUE); | |
7fd59977 | 404 | |
405 | #ifdef _MSC_VER | |
0ac0c8b4 | 406 | _se_translator_function pOldSeFunc = _set_se_translator (TranslateSE); |
7fd59977 | 407 | #endif |
408 | ||
0ac0c8b4 RL |
409 | fFltExceptions = theFloatingSignal; |
410 | if (theFloatingSignal) | |
411 | { | |
412 | _controlfp (0, _OSD_FPX); // JR add : | |
413 | } | |
414 | else { | |
415 | _controlfp (_OSD_FPX, _OSD_FPX); // JR add : | |
416 | } | |
7fd59977 | 417 | #endif |
7fd59977 | 418 | } // end OSD :: SetSignal |
419 | ||
420 | //============================================================================ | |
421 | //==== ControlBreak | |
422 | //============================================================================ | |
423 | ||
424 | void OSD :: ControlBreak () { | |
425 | ||
426 | if ( fCtrlBrk ) { | |
427 | ||
428 | fCtrlBrk = Standard_False; | |
429 | OSD_Exception_CTRL_BREAK :: Raise ( TEXT( "*** INTERRUPT ***" ) ); | |
430 | ||
431 | } // end if | |
432 | ||
433 | } // end OSD :: ControlBreak | |
434 | ||
435 | //============================================================================ | |
436 | //==== _osd_ctrl_break_handler | |
437 | //============================================================================ | |
438 | ||
439 | static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) { | |
440 | ||
441 | if ( dwCode == CTRL_C_EVENT || dwCode == CTRL_BREAK_EVENT ) { | |
442 | ||
443 | MessageBeep ( MB_ICONEXCLAMATION ); | |
444 | fCtrlBrk = Standard_True; | |
445 | ||
446 | } else | |
447 | ||
448 | exit ( 254 ); | |
449 | ||
450 | return TRUE; | |
451 | ||
452 | } // end _osd_ctrl_break_handler | |
453 | ||
454 | //============================================================================ | |
455 | //==== _osd_raise | |
456 | //============================================================================ | |
457 | ||
458 | static LONG __fastcall _osd_raise ( DWORD dwCode, LPTSTR msg ) | |
459 | { | |
0ac0c8b4 RL |
460 | if (msg[0] == TEXT('\x03')) ++msg; |
461 | ||
462 | switch (dwCode) | |
463 | { | |
464 | case EXCEPTION_ACCESS_VIOLATION: | |
465 | OSD_Exception_ACCESS_VIOLATION::Raise (msg); | |
466 | break; | |
467 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | |
468 | OSD_Exception_ARRAY_BOUNDS_EXCEEDED::Raise (msg); | |
469 | break; | |
470 | case EXCEPTION_DATATYPE_MISALIGNMENT: | |
471 | Standard_ProgramError::Raise (msg); | |
472 | break; | |
473 | case EXCEPTION_ILLEGAL_INSTRUCTION: | |
474 | OSD_Exception_ILLEGAL_INSTRUCTION::Raise (msg); | |
475 | break; | |
476 | case EXCEPTION_IN_PAGE_ERROR: | |
477 | OSD_Exception_IN_PAGE_ERROR::Raise (msg); | |
478 | break; | |
479 | case EXCEPTION_INT_DIVIDE_BY_ZERO: | |
480 | Standard_DivideByZero::Raise (msg); | |
481 | break; | |
482 | case EXCEPTION_INT_OVERFLOW: | |
483 | OSD_Exception_INT_OVERFLOW::Raise (msg); | |
484 | break; | |
485 | case EXCEPTION_INVALID_DISPOSITION: | |
486 | OSD_Exception_INVALID_DISPOSITION::Raise (msg); | |
487 | break; | |
488 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: | |
489 | OSD_Exception_NONCONTINUABLE_EXCEPTION::Raise (msg); | |
490 | break; | |
491 | case EXCEPTION_PRIV_INSTRUCTION: | |
492 | OSD_Exception_PRIV_INSTRUCTION::Raise (msg); | |
493 | break; | |
494 | case EXCEPTION_STACK_OVERFLOW: | |
495 | OSD_Exception_STACK_OVERFLOW::Raise (msg); | |
496 | break; | |
497 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: | |
498 | Standard_DivideByZero::Raise (msg); | |
499 | break; | |
500 | case EXCEPTION_FLT_STACK_CHECK: | |
501 | case EXCEPTION_FLT_OVERFLOW: | |
502 | Standard_Overflow::Raise (msg); | |
503 | break; | |
504 | case EXCEPTION_FLT_UNDERFLOW: | |
505 | Standard_Underflow::Raise (msg); | |
506 | break; | |
507 | case EXCEPTION_FLT_INVALID_OPERATION: | |
508 | case EXCEPTION_FLT_DENORMAL_OPERAND: | |
509 | case EXCEPTION_FLT_INEXACT_RESULT: | |
510 | case STATUS_FLOAT_MULTIPLE_TRAPS: | |
511 | case STATUS_FLOAT_MULTIPLE_FAULTS: | |
512 | Standard_NumericError::Raise (msg); | |
513 | break; | |
514 | default: | |
515 | break; | |
516 | } // end switch | |
517 | return EXCEPTION_EXECUTE_HANDLER; | |
7fd59977 | 518 | } // end _osd_raise |
519 | ||
520 | //============================================================================ | |
521 | //==== _osd_debug | |
522 | //============================================================================ | |
523 | ||
524 | #if defined(__CYGWIN32__) || defined(__MINGW32__) | |
525 | #define __try | |
526 | #define __finally | |
527 | #define __leave return 0 | |
528 | #endif | |
529 | ||
530 | LONG _osd_debug ( void ) { | |
531 | ||
532 | LONG action ; | |
533 | ||
534 | if ( !fDbgLoaded ) { | |
535 | ||
536 | HKEY hKey; | |
537 | HANDLE hEvent = INVALID_HANDLE_VALUE; | |
538 | DWORD dwKeyType; | |
539 | DWORD dwValueLen; | |
540 | TCHAR keyValue[ MAX_PATH ]; | |
541 | TCHAR cmdLine[ MAX_PATH ]; | |
542 | SECURITY_ATTRIBUTES sa; | |
543 | PROCESS_INFORMATION pi; | |
544 | STARTUPINFO si; | |
545 | ||
546 | __try { | |
547 | ||
548 | if ( RegOpenKey ( | |
549 | HKEY_LOCAL_MACHINE, | |
550 | TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" ), | |
551 | &hKey | |
552 | ) != ERROR_SUCCESS | |
553 | ) __leave; | |
554 | ||
555 | dwValueLen = sizeof ( keyValue ); | |
556 | ||
557 | if ( RegQueryValueEx ( | |
558 | hKey, TEXT( "Debugger" ), NULL, &dwKeyType, ( unsigned char* )keyValue, &dwValueLen | |
559 | ) != ERROR_SUCCESS | |
560 | ) __leave; | |
561 | ||
562 | sa.nLength = sizeof ( SECURITY_ATTRIBUTES ); | |
563 | sa.lpSecurityDescriptor = NULL; | |
564 | sa.bInheritHandle = TRUE; | |
565 | ||
566 | if ( ( hEvent = CreateEvent ( &sa, TRUE, FALSE, NULL ) ) == NULL ) __leave; | |
567 | ||
568 | wsprintf ( cmdLine, keyValue, GetCurrentProcessId (), hEvent ); | |
569 | ||
570 | ZeroMemory ( &si, sizeof ( STARTUPINFO ) ); | |
571 | ||
572 | si.cb = sizeof ( STARTUPINFO ); | |
573 | si.dwFlags = STARTF_FORCEONFEEDBACK; | |
574 | ||
575 | // cout << "_osd_debug -> CreateProcess" << endl ; | |
576 | if ( !CreateProcess ( | |
577 | NULL, cmdLine, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE, | |
578 | NULL, NULL, &si, &pi | |
579 | ) | |
580 | ) __leave; | |
581 | ||
582 | // cout << "_osd_debug -> WaitForSingleObject " << endl ; | |
583 | WaitForSingleObject ( hEvent, INFINITE ); | |
584 | // cout << "_osd_debug <- WaitForSingleObject -> CloseHandle " << endl ; | |
585 | ||
586 | CloseHandle ( pi.hProcess ); | |
587 | CloseHandle ( pi.hThread ); | |
588 | ||
589 | // cout << "_osd_debug fDbgLoaded " << endl ; | |
590 | fDbgLoaded = TRUE; | |
591 | ||
592 | } // end __try | |
593 | ||
594 | __finally { | |
595 | ||
596 | // cout << "_osd_debug -> CloseHandle(hKey) " << endl ; | |
597 | if ( hKey != INVALID_HANDLE_VALUE ) CloseHandle ( hKey ); | |
598 | // cout << "_osd_debug -> CloseHandle(hEvent) " << endl ; | |
599 | if ( hEvent != INVALID_HANDLE_VALUE ) CloseHandle ( hEvent ); | |
600 | // cout << "_osd_debug end __finally " << endl ; | |
601 | ||
602 | } // end __finally | |
603 | ||
604 | } /* end if */ | |
605 | ||
606 | action = fDbgLoaded ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER; | |
607 | // cout << "_osd_debug return " << action << " EXCEPTION_CONTINUE_EXECUTION(" | |
608 | // << EXCEPTION_CONTINUE_EXECUTION << ")" << endl ; | |
609 | return action ; | |
610 | ||
611 | } // end _osd_debug | |
612 | ||
613 | #if defined(__CYGWIN32__) || defined(__MINGW32__) | |
614 | #undef __try | |
615 | #undef __finally | |
616 | #undef __leave | |
617 | #endif | |
618 | ||
7fd59977 | 619 | // Must be there for compatibility with UNIX system code ---------------------- |
620 | ||
621 | //void OSD::Handler(const OSD_Signals aSig, | |
622 | // const OSD_Signals aCode){} | |
623 | void OSD::Handler(const OSD_Signals theSignal, | |
624 | const Standard_Address theSigInfo, | |
625 | const Standard_Address theContext) {} | |
626 | ||
627 | void OSD::SegvHandler(const OSD_Signals aSig, | |
628 | const Standard_Address code, | |
629 | const Standard_Address scp){} | |
630 | ||
631 | #endif // WNT |