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 | |
21 | static Standard_Boolean fSETranslator = |
22 | #ifdef _MSC_VER |
23 | Standard_True; |
24 | #else |
25 | Standard_False; |
26 | #endif |
27 | |
28 | #ifdef WNT |
29 | |
30 | //---------------------------- Windows NT System -------------------------------- |
31 | |
32 | #define STRICT |
33 | #ifdef NOUSER |
34 | #undef NOUSER |
35 | #endif |
36 | #include <windows.h> |
37 | |
38 | #include <OSD_Exception_ACCESS_VIOLATION.hxx> |
39 | #include <OSD_Exception_ARRAY_BOUNDS_EXCEEDED.hxx> |
40 | #include <OSD_Exception_ILLEGAL_INSTRUCTION.hxx> |
41 | #include <OSD_Exception_IN_PAGE_ERROR.hxx> |
42 | #include <OSD_Exception_INT_DIVIDE_BY_ZERO.hxx> |
43 | #include <OSD_Exception_INT_OVERFLOW.hxx> |
44 | #include <OSD_Exception_INVALID_DISPOSITION.hxx> |
45 | #include <OSD_Exception_NONCONTINUABLE_EXCEPTION.hxx> |
46 | #include <OSD_Exception_PRIV_INSTRUCTION.hxx> |
47 | #include <OSD_Exception_STACK_OVERFLOW.hxx> |
48 | #include <OSD_Exception_STATUS_NO_MEMORY.hxx> |
49 | #include <OSD_Exception_CTRL_BREAK.hxx> |
50 | |
51 | #include <OSD_Environment.hxx> |
52 | #include <Standard_Underflow.hxx> |
53 | #include <Standard_DivideByZero.hxx> |
54 | #include <Standard_Overflow.hxx> |
55 | #include <Standard_ProgramError.hxx> |
56 | |
57 | #include <OSD_WNT_1.hxx> |
58 | |
59 | #ifdef _MSC_VER |
60 | #include <eh.h> |
61 | #include <malloc.h> |
62 | #endif |
63 | |
64 | #include <process.h> |
65 | #include <signal.h> |
66 | #include <float.h> |
67 | |
68 | static Standard_Boolean fMsgBox; |
69 | static Standard_Boolean fFltExceptions; |
70 | static Standard_Boolean fDbgLoaded; |
71 | static Standard_Boolean fCtrlBrk; |
72 | |
73 | static LONG __fastcall _osd_raise ( DWORD, LPTSTR ); |
74 | static BOOL WINAPI _osd_ctrl_break_handler ( DWORD ); |
75 | |
76 | extern "C" Standard_EXPORT LONG _osd_debug ( void ); |
77 | extern "C" Standard_EXPORT void _debug_break ( Standard_PCharacter ); |
78 | |
79 | MB_DESC fatalErrorDesc[] = { |
80 | |
81 | { MBT_ICON, ( int )IDI_HAND }, |
82 | { MBT_BUTTON, IDYES, TEXT( "Continue" ) }, |
83 | { MBT_BUTTON, IDNO, TEXT( "Debugger" ) }, |
84 | { MBT_BUTTON, IDCANCEL, TEXT( "Stop" ) } |
85 | |
86 | }; |
87 | |
88 | static LONG CallHandler (DWORD, ptrdiff_t, ptrdiff_t); |
89 | static void SIGWntHandler (int, int); |
90 | |
91 | |
92 | //# define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW ) |
93 | # define _OSD_FPX ( _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW ) |
94 | |
95 | //============================================================================ |
96 | //==== WntHandler |
97 | //============================================================================ |
98 | |
99 | Standard_Integer OSD :: WntHandler ( const Standard_Address exceptionInfo ) |
100 | { |
101 | |
102 | LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )exceptionInfo; |
103 | DWORD dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode; |
104 | |
105 | // cout << "WntHandler " << dwExceptionCode << " " << lpXP->ExceptionRecord->ExceptionInformation[1] |
106 | // << " " <<lpXP->ExceptionRecord->ExceptionInformation[0] << endl ; |
107 | |
108 | return CallHandler( dwExceptionCode , |
109 | lpXP -> ExceptionRecord -> ExceptionInformation[ 1 ] , |
110 | lpXP -> ExceptionRecord -> ExceptionInformation[ 0 ] ) ; |
111 | |
112 | } |
113 | |
114 | //============================================================================ |
115 | //==== SIGWntHandler |
116 | //============================================================================ |
117 | |
118 | static void SIGWntHandler(int signum , int sub_code ) { |
119 | |
120 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) |
121 | |
122 | // cout << "SIGWntHandler " << signum << " subcode " << sub_code << endl ; |
123 | switch( signum ) { |
124 | case SIGFPE : |
125 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
126 | cout << "signal error" << endl ; |
127 | switch( sub_code ) { |
128 | case _FPE_INVALID : |
129 | CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ; |
130 | break ; |
131 | case _FPE_DENORMAL : |
132 | CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ; |
133 | break ; |
134 | case _FPE_ZERODIVIDE : |
135 | CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ; |
136 | break ; |
137 | case _FPE_OVERFLOW : |
138 | CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ; |
139 | break ; |
140 | case _FPE_UNDERFLOW : |
141 | CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ; |
142 | break ; |
143 | case _FPE_INEXACT : |
144 | CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ; |
145 | break ; |
146 | default: |
147 | cout << "SIGWntHandler(default) -> Standard_NumericError::Raise(\"Floating Point Error\");" |
148 | << endl ; |
149 | Standard_NumericError::Raise("Floating Point Error"); |
150 | break ; |
151 | } |
152 | break ; |
153 | case SIGSEGV : |
154 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
155 | cout << "signal error" << endl ; |
156 | CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ; |
157 | break ; |
158 | case SIGILL : |
159 | if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
160 | cout << "signal error" << endl ; |
161 | CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ; |
162 | break ; |
163 | default: |
164 | cout << "SIGWntHandler unexpected signal : " |
165 | << signum << endl ; |
166 | break ; |
167 | } |
168 | // cout << "return from SIGWntHandler -> DebugBreak " << endl ; |
169 | DebugBreak (); |
170 | |
171 | #endif |
172 | |
173 | } |
174 | |
175 | //============================================================================ |
176 | //==== CallHandler |
177 | //============================================================================ |
178 | |
179 | static LONG CallHandler (DWORD dwExceptionCode , |
180 | ptrdiff_t ExceptionInformation1 , |
181 | ptrdiff_t ExceptionInformation0) |
182 | { |
183 | |
184 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) |
185 | |
186 | static TCHAR buffer[ 2048 ]; |
187 | int flterr = 0; |
188 | |
189 | buffer[0] = '\0' ; |
190 | |
191 | // cout << "CallHandler " << dwExceptionCode << endl ; |
192 | switch ( dwExceptionCode ) { |
193 | |
194 | case EXCEPTION_FLT_DENORMAL_OPERAND: |
195 | // cout << "CallHandler : EXCEPTION_FLT_DENORMAL_OPERAND:" << endl ; |
196 | lstrcpy ( buffer, TEXT( "FLT DENORMAL OPERAND" ) ); |
197 | flterr = 1 ; |
198 | break ; |
199 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: |
200 | // cout << "CallHandler : EXCEPTION_FLT_DIVIDE_BY_ZERO:" << endl ; |
201 | lstrcpy ( buffer, TEXT( "FLT DIVIDE BY ZERO" ) ); |
202 | flterr = 1 ; |
203 | break ; |
204 | case EXCEPTION_FLT_INEXACT_RESULT: |
205 | // cout << "CallHandler : EXCEPTION_FLT_INEXACT_RESULT:" << endl ; |
206 | lstrcpy ( buffer, TEXT( "FLT INEXACT RESULT" ) ); |
207 | flterr = 1 ; |
208 | break ; |
209 | case EXCEPTION_FLT_INVALID_OPERATION: |
210 | // cout << "CallHandler : EXCEPTION_FLT_INVALID_OPERATION:" << endl ; |
211 | lstrcpy ( buffer, TEXT( "FLT INVALID OPERATION" ) ); |
212 | flterr = 1 ; |
213 | break ; |
214 | case EXCEPTION_FLT_OVERFLOW: |
215 | // cout << "CallHandler : EXCEPTION_FLT_OVERFLOW:" << endl ; |
216 | lstrcpy ( buffer, TEXT( "FLT OVERFLOW" ) ); |
217 | flterr = 1 ; |
218 | break ; |
219 | case EXCEPTION_FLT_STACK_CHECK: |
220 | // cout << "CallHandler : EXCEPTION_FLT_STACK_CHECK:" << endl ; |
221 | lstrcpy ( buffer, TEXT( "FLT STACK CHECK" ) ); |
222 | flterr = 1 ; |
223 | break ; |
224 | case EXCEPTION_FLT_UNDERFLOW: |
225 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; |
226 | lstrcpy ( buffer, TEXT( "FLT UNDERFLOW" ) ); |
227 | flterr = 1 ; |
228 | break ; |
229 | case STATUS_FLOAT_MULTIPLE_TRAPS: |
230 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; |
231 | lstrcpy ( buffer, TEXT( "FLT MULTIPLE TRAPS (possible overflow in conversion of double to integer)" ) ); |
232 | flterr = 1 ; |
233 | break ; |
234 | case STATUS_FLOAT_MULTIPLE_FAULTS: |
235 | // cout << "CallHandler : EXCEPTION_FLT_UNDERFLOW:" << endl ; |
236 | lstrcpy ( buffer, TEXT( "FLT MULTIPLE FAULTS" ) ); |
237 | flterr = 1 ; |
238 | break ; |
239 | |
240 | case STATUS_NO_MEMORY: |
241 | // cout << "CallHandler : STATUS_NO_MEMORY:" << endl ; |
242 | OSD_Exception_STATUS_NO_MEMORY :: |
243 | Raise ( TEXT( "MEMORY ALLOCATION ERROR ( no room in the process heap )" ) ); |
244 | |
245 | case EXCEPTION_ACCESS_VIOLATION: |
246 | // cout << "CallHandler : EXCEPTION_ACCESS_VIOLATION:" << endl ; |
247 | wsprintf ( buffer, TEXT( "%s%s%s0x%.8p%s%s%s" ), TEXT( "ACCESS VIOLATION" ), |
248 | fMsgBox ? "\n" : " ", TEXT( "at address " ), |
249 | ExceptionInformation1 , |
250 | TEXT( " during '" ), |
251 | ExceptionInformation0 ? TEXT( "WRITE" ) : TEXT( "READ" ), |
252 | TEXT( "' operation" )); |
253 | break; |
254 | |
255 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: |
256 | // cout << "CallHandler : EXCEPTION_ARRAY_BOUNDS_EXCEEDED:" << endl ; |
257 | lstrcpy ( buffer, TEXT( "ARRAY BOUNDS EXCEEDED" ) ); |
258 | break; |
259 | |
260 | case EXCEPTION_DATATYPE_MISALIGNMENT: |
261 | // cout << "CallHandler : EXCEPTION_DATATYPE_MISALIGNMENT:" << endl ; |
262 | lstrcpy ( buffer, TEXT( "DATATYPE MISALIGNMENT" ) ); |
263 | break; |
264 | |
265 | case EXCEPTION_ILLEGAL_INSTRUCTION: |
266 | // cout << "CallHandler : EXCEPTION_ILLEGAL_INSTRUCTION:" << endl ; |
267 | lstrcpy ( buffer, TEXT( "ILLEGAL INSTRUCTION" ) ); |
268 | break; |
269 | |
270 | case EXCEPTION_IN_PAGE_ERROR: |
271 | // cout << "CallHandler : EXCEPTION_IN_PAGE_ERROR:" << endl ; |
272 | lstrcpy ( buffer, TEXT( "IN_PAGE ERROR" ) ); |
273 | break; |
274 | |
275 | case EXCEPTION_INT_DIVIDE_BY_ZERO: |
276 | // cout << "CallHandler : EXCEPTION_INT_DIVIDE_BY_ZERO:" << endl ; |
277 | lstrcpy ( buffer, TEXT( "INTEGER DIVISION BY ZERO" ) ); |
278 | break; |
279 | |
280 | case EXCEPTION_INT_OVERFLOW: |
281 | // cout << "CallHandler : EXCEPTION_INT_OVERFLOW:" << endl ; |
282 | lstrcpy ( buffer, TEXT( "INTEGER OVERFLOW" ) ); |
283 | break; |
284 | |
285 | case EXCEPTION_INVALID_DISPOSITION: |
286 | // cout << "CallHandler : EXCEPTION_INVALID_DISPOSITION:" << endl ; |
287 | lstrcpy ( buffer, TEXT( "INVALID DISPOSITION" ) ); |
288 | break; |
289 | |
290 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: |
291 | // cout << "CallHandler : EXCEPTION_NONCONTINUABLE_EXCEPTION:" << endl ; |
292 | lstrcpy ( buffer, TEXT( "NONCONTINUABLE EXCEPTION" ) ); |
293 | break; |
294 | |
295 | case EXCEPTION_PRIV_INSTRUCTION: |
296 | // cout << "CallHandler : EXCEPTION_PRIV_INSTRUCTION:" << endl ; |
297 | lstrcpy ( buffer, TEXT( "PRIVELEGED INSTRUCTION ENCOUNTERED" ) ); |
298 | break; |
299 | |
300 | case EXCEPTION_STACK_OVERFLOW: |
301 | // cout << "CallHandler : EXCEPTION_STACK_OVERFLOW:" << endl ; |
302 | #if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) |
303 | // try recovering from stack overflow: available in MS VC++ 7.0 |
304 | if (!_resetstkoflw()) |
305 | lstrcpy ( buffer, TEXT( "Unrecoverable STACK OVERFLOW" ) ); |
306 | else |
307 | #endif |
308 | lstrcpy ( buffer, TEXT( "STACK OVERFLOW" ) ); |
309 | break; |
310 | |
311 | default: |
312 | wsprintf( buffer, TEXT("unknown exception code 0x%x, params 0x%p 0x%p"), |
313 | dwExceptionCode, ExceptionInformation1, ExceptionInformation0 ); |
314 | |
315 | } // end switch |
316 | |
317 | int idx = lstrlen ( buffer ); |
318 | |
319 | |
320 | if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) { |
321 | MessageBeep ( MB_ICONHAND ); |
322 | int msgID = MsgBox ( NULL, buffer, TEXT( "Error detected" ), 4, fatalErrorDesc ); |
323 | // cout << "flterr" << flterr << " fFltExceptions " << fFltExceptions << endl ; |
324 | if ( flterr ) { |
325 | if ( !fFltExceptions ) |
326 | return EXCEPTION_EXECUTE_HANDLER; |
327 | _fpreset () ; |
328 | _clearfp() ; |
329 | _controlfp ( 0, _OSD_FPX ) ; // JR add : |
330 | // cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ; |
331 | } |
332 | buffer[ idx ] = 0; |
333 | switch ( msgID ) { |
334 | case IDYES: { |
335 | PTCHAR ptr = _tcschr ( buffer, TEXT( '\n' ) ); |
336 | if ( ptr != NULL ) |
337 | *ptr = TEXT( ' ' ); |
338 | // cout << "CallHandler " << dwExceptionCode << endl ; |
339 | _osd_raise ( dwExceptionCode, buffer ); |
340 | } // IDYES |
341 | case IDNO: |
342 | LONG action ; |
343 | action = _osd_debug (); |
344 | // cout << "return from CallHandler -> DebugBreak " << endl ; |
345 | DebugBreak (); |
346 | _osd_raise ( dwExceptionCode, buffer ); |
347 | // cout << "CallHandler return : " << action << endl ; |
348 | return action ; |
349 | case IDCANCEL: |
350 | exit ( 0xFFFF ); |
351 | } // end switch |
352 | } |
353 | else { |
354 | if ( flterr ) { |
355 | if ( !fFltExceptions ) |
356 | return EXCEPTION_EXECUTE_HANDLER; |
357 | _fpreset () ; |
358 | _clearfp() ; |
359 | _controlfp ( 0, _OSD_FPX ) ; // JR add : |
360 | // cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ; |
361 | } |
362 | } |
363 | |
364 | return _osd_raise ( dwExceptionCode, buffer ); |
365 | |
366 | #else |
367 | return 0; |
368 | #endif |
369 | |
370 | } // end OSD :: WntHandler |
371 | |
372 | //======================================================================= |
373 | //function : TranslateSE |
374 | //purpose : Translate Structural Exceptions into C++ exceptions |
375 | //======================================================================= |
376 | |
377 | #ifdef _MSC_VER |
378 | static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr ) |
379 | { |
380 | ptrdiff_t info1 = 0, info0 = 0; |
381 | if ( theExcPtr ) { |
382 | info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1]; |
383 | info0 = theExcPtr->ExceptionRecord->ExceptionInformation[0]; |
384 | } |
385 | CallHandler(theCode, info1, info0); |
386 | } |
387 | #endif |
388 | |
389 | //============================================================================ |
390 | //==== SetSignal |
391 | //============================================================================ |
392 | |
393 | #ifdef _MSC_VER |
394 | // MSV 31.08.2005 |
395 | // If we compile this file under MSVC 7.1 with the default options for |
396 | // exception handling (/GX or /EHsc) then the following warning is issued: |
397 | // warning C4535: calling _set_se_translator() requires /EHa |
398 | // Till now all worked with the default options, and there was no difference |
399 | // found in exception handling behaviour between /EHa and /EHs options. |
400 | // So, here we disable the warning, and leave the default compiler options. |
401 | // If some reason appears to turn to /EHa option this pragma can be removed. |
402 | #pragma warning (disable:4535) |
403 | #endif |
404 | |
405 | void OSD :: SetSignal ( const Standard_Boolean aFloatingSignal ) { |
406 | |
407 | #if !defined(__CYGWIN32__) && !defined(__MINGW32__) |
408 | |
409 | static int first_time = 1 ; |
410 | LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter ; |
411 | |
412 | if ( first_time ) { |
413 | // OSD_Environment env ( TEXT( "CSF_EXCEPTION_PROMPT" ) ); |
414 | OSD_Environment env ( TEXT( "CSF_DEBUG_MODE" ) ); |
415 | TCollection_AsciiString val; |
416 | |
417 | val = env.Value (); |
418 | |
419 | if ( !env.Failed () ) { |
420 | cout << "Environment variable CSF_DEBUG_MODE setted." << endl ; |
421 | fMsgBox = Standard_True; |
422 | } |
423 | else { |
424 | // cout << "Environment variable CSF_DEBUG_MODE not setted." << endl ; |
425 | fMsgBox = Standard_False; |
426 | } |
427 | |
428 | if (!fSETranslator) { |
429 | aPreviousFilter = |
430 | SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER)&OSD::WntHandler); |
431 | // cout << "SetUnhandledExceptionFilter previous filer : " << hex << aPreviousFilter << dec << endl ; |
432 | |
433 | if ( signal( SIGSEGV , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
434 | cout << "signal(OSD::SetSignal) error" << endl ; |
435 | if ( signal( SIGFPE , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
436 | cout << "signal(OSD::SetSignal) error" << endl ; |
437 | if ( signal( SIGILL , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR ) |
438 | cout << "signal(OSD::SetSignal) error" << endl ; |
439 | } |
440 | |
441 | fCtrlBrk = Standard_False; |
442 | SetConsoleCtrlHandler ( &_osd_ctrl_break_handler, TRUE ); |
443 | } |
444 | |
445 | #ifdef _MSC_VER |
446 | if (fSETranslator) { |
447 | // use Structural Exception translator (one per thread) |
448 | _se_translator_function pOldSeFunc = _set_se_translator( TranslateSE ); |
449 | } |
450 | #endif |
451 | |
452 | fFltExceptions = aFloatingSignal; |
453 | if ( aFloatingSignal ) { |
454 | _controlfp ( 0, _OSD_FPX ); // JR add : |
455 | if ( first_time ) { |
456 | // cout << "SetSignal with floating point traps : " << hex << _controlfp(0,0) << dec << endl ; |
457 | first_time = 0 ; |
458 | } |
459 | } |
460 | else { |
461 | _controlfp ( _OSD_FPX , _OSD_FPX ); // JR add : |
462 | if ( first_time ) { |
463 | // cout << "SetSignal without floating point traps : " << hex << _controlfp(0,0) << dec << endl ; |
464 | first_time = 0 ; |
465 | } |
466 | } |
467 | |
468 | #endif |
469 | |
470 | } // end OSD :: SetSignal |
471 | |
472 | //============================================================================ |
473 | //==== ControlBreak |
474 | //============================================================================ |
475 | |
476 | void OSD :: ControlBreak () { |
477 | |
478 | if ( fCtrlBrk ) { |
479 | |
480 | fCtrlBrk = Standard_False; |
481 | OSD_Exception_CTRL_BREAK :: Raise ( TEXT( "*** INTERRUPT ***" ) ); |
482 | |
483 | } // end if |
484 | |
485 | } // end OSD :: ControlBreak |
486 | |
487 | //============================================================================ |
488 | //==== _osd_ctrl_break_handler |
489 | //============================================================================ |
490 | |
491 | static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) { |
492 | |
493 | if ( dwCode == CTRL_C_EVENT || dwCode == CTRL_BREAK_EVENT ) { |
494 | |
495 | MessageBeep ( MB_ICONEXCLAMATION ); |
496 | fCtrlBrk = Standard_True; |
497 | |
498 | } else |
499 | |
500 | exit ( 254 ); |
501 | |
502 | return TRUE; |
503 | |
504 | } // end _osd_ctrl_break_handler |
505 | |
506 | //============================================================================ |
507 | //==== _osd_raise |
508 | //============================================================================ |
509 | |
510 | static LONG __fastcall _osd_raise ( DWORD dwCode, LPTSTR msg ) |
511 | { |
512 | if ( msg[ 0 ] == TEXT( '\x03' ) ) ++msg; |
513 | |
514 | switch ( dwCode ) { |
515 | |
516 | case EXCEPTION_ACCESS_VIOLATION: |
517 | |
518 | OSD_Exception_ACCESS_VIOLATION :: Raise ( msg ); |
519 | |
520 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: |
521 | |
522 | OSD_Exception_ARRAY_BOUNDS_EXCEEDED :: Raise ( msg ); |
523 | |
524 | case EXCEPTION_DATATYPE_MISALIGNMENT: |
525 | |
526 | Standard_ProgramError :: Raise ( msg ); |
527 | |
528 | case EXCEPTION_ILLEGAL_INSTRUCTION: |
529 | |
530 | OSD_Exception_ILLEGAL_INSTRUCTION :: Raise ( msg ); |
531 | |
532 | case EXCEPTION_IN_PAGE_ERROR: |
533 | |
534 | OSD_Exception_IN_PAGE_ERROR :: Raise ( msg ); |
535 | |
536 | case EXCEPTION_INT_DIVIDE_BY_ZERO: |
537 | |
538 | Standard_DivideByZero :: Raise ( msg ); |
539 | |
540 | case EXCEPTION_INT_OVERFLOW: |
541 | |
542 | OSD_Exception_INT_OVERFLOW :: Raise ( msg ); |
543 | |
544 | case EXCEPTION_INVALID_DISPOSITION: |
545 | |
546 | OSD_Exception_INVALID_DISPOSITION :: Raise ( msg ); |
547 | |
548 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: |
549 | |
550 | OSD_Exception_NONCONTINUABLE_EXCEPTION :: Raise ( msg ); |
551 | |
552 | case EXCEPTION_PRIV_INSTRUCTION: |
553 | |
554 | OSD_Exception_PRIV_INSTRUCTION :: Raise ( msg ); |
555 | |
556 | case EXCEPTION_STACK_OVERFLOW: |
557 | |
558 | OSD_Exception_STACK_OVERFLOW :: Raise ( msg ); |
559 | |
560 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: |
561 | Standard_DivideByZero :: Raise ( msg ); |
562 | case EXCEPTION_FLT_STACK_CHECK: |
563 | case EXCEPTION_FLT_OVERFLOW: |
564 | Standard_Overflow :: Raise ( msg ); |
565 | case EXCEPTION_FLT_UNDERFLOW: |
566 | Standard_Underflow :: Raise ( msg ); |
567 | case EXCEPTION_FLT_INVALID_OPERATION: |
568 | case EXCEPTION_FLT_DENORMAL_OPERAND: |
569 | case EXCEPTION_FLT_INEXACT_RESULT: |
570 | case STATUS_FLOAT_MULTIPLE_TRAPS: |
571 | case STATUS_FLOAT_MULTIPLE_FAULTS: |
572 | Standard_NumericError :: Raise ( msg ); |
573 | default: |
574 | break; |
575 | } // end switch |
576 | |
577 | return EXCEPTION_EXECUTE_HANDLER; |
578 | |
579 | } // end _osd_raise |
580 | |
581 | //============================================================================ |
582 | //==== _osd_debug |
583 | //============================================================================ |
584 | |
585 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
586 | #define __try |
587 | #define __finally |
588 | #define __leave return 0 |
589 | #endif |
590 | |
591 | LONG _osd_debug ( void ) { |
592 | |
593 | LONG action ; |
594 | |
595 | if ( !fDbgLoaded ) { |
596 | |
597 | HKEY hKey; |
598 | HANDLE hEvent = INVALID_HANDLE_VALUE; |
599 | DWORD dwKeyType; |
600 | DWORD dwValueLen; |
601 | TCHAR keyValue[ MAX_PATH ]; |
602 | TCHAR cmdLine[ MAX_PATH ]; |
603 | SECURITY_ATTRIBUTES sa; |
604 | PROCESS_INFORMATION pi; |
605 | STARTUPINFO si; |
606 | |
607 | __try { |
608 | |
609 | if ( RegOpenKey ( |
610 | HKEY_LOCAL_MACHINE, |
611 | TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" ), |
612 | &hKey |
613 | ) != ERROR_SUCCESS |
614 | ) __leave; |
615 | |
616 | dwValueLen = sizeof ( keyValue ); |
617 | |
618 | if ( RegQueryValueEx ( |
619 | hKey, TEXT( "Debugger" ), NULL, &dwKeyType, ( unsigned char* )keyValue, &dwValueLen |
620 | ) != ERROR_SUCCESS |
621 | ) __leave; |
622 | |
623 | sa.nLength = sizeof ( SECURITY_ATTRIBUTES ); |
624 | sa.lpSecurityDescriptor = NULL; |
625 | sa.bInheritHandle = TRUE; |
626 | |
627 | if ( ( hEvent = CreateEvent ( &sa, TRUE, FALSE, NULL ) ) == NULL ) __leave; |
628 | |
629 | wsprintf ( cmdLine, keyValue, GetCurrentProcessId (), hEvent ); |
630 | |
631 | ZeroMemory ( &si, sizeof ( STARTUPINFO ) ); |
632 | |
633 | si.cb = sizeof ( STARTUPINFO ); |
634 | si.dwFlags = STARTF_FORCEONFEEDBACK; |
635 | |
636 | // cout << "_osd_debug -> CreateProcess" << endl ; |
637 | if ( !CreateProcess ( |
638 | NULL, cmdLine, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE, |
639 | NULL, NULL, &si, &pi |
640 | ) |
641 | ) __leave; |
642 | |
643 | // cout << "_osd_debug -> WaitForSingleObject " << endl ; |
644 | WaitForSingleObject ( hEvent, INFINITE ); |
645 | // cout << "_osd_debug <- WaitForSingleObject -> CloseHandle " << endl ; |
646 | |
647 | CloseHandle ( pi.hProcess ); |
648 | CloseHandle ( pi.hThread ); |
649 | |
650 | // cout << "_osd_debug fDbgLoaded " << endl ; |
651 | fDbgLoaded = TRUE; |
652 | |
653 | } // end __try |
654 | |
655 | __finally { |
656 | |
657 | // cout << "_osd_debug -> CloseHandle(hKey) " << endl ; |
658 | if ( hKey != INVALID_HANDLE_VALUE ) CloseHandle ( hKey ); |
659 | // cout << "_osd_debug -> CloseHandle(hEvent) " << endl ; |
660 | if ( hEvent != INVALID_HANDLE_VALUE ) CloseHandle ( hEvent ); |
661 | // cout << "_osd_debug end __finally " << endl ; |
662 | |
663 | } // end __finally |
664 | |
665 | } /* end if */ |
666 | |
667 | action = fDbgLoaded ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER; |
668 | // cout << "_osd_debug return " << action << " EXCEPTION_CONTINUE_EXECUTION(" |
669 | // << EXCEPTION_CONTINUE_EXECUTION << ")" << endl ; |
670 | return action ; |
671 | |
672 | } // end _osd_debug |
673 | |
674 | #if defined(__CYGWIN32__) || defined(__MINGW32__) |
675 | #undef __try |
676 | #undef __finally |
677 | #undef __leave |
678 | #endif |
679 | |
680 | //============================================================================ |
681 | //==== _debug_break |
682 | //============================================================================ |
683 | |
684 | void _debug_break ( Standard_PCharacter msg ) { |
685 | |
686 | OSD_Environment env ( "CSF_DEBUG_MODE" ); |
687 | Standard_Character buff[ 2048 ]; |
688 | |
689 | env.Value (); |
690 | |
691 | if ( env.Failed () ) return; |
692 | |
693 | lstrcpy ( buff, msg ); |
694 | lstrcat ( buff, _TEXT( "\nExit to debugger ?" ) ); |
695 | |
696 | if ( MessageBox ( |
697 | NULL, buff, _TEXT( "DEBUG" ), MB_SYSTEMMODAL | MB_ICONQUESTION | MB_YESNO |
698 | ) == IDYES |
699 | ) { |
700 | |
701 | _osd_debug (); |
702 | DebugBreak (); |
703 | |
704 | } // end if |
705 | |
706 | } // end _debug_break |
707 | |
708 | // Must be there for compatibility with UNIX system code ---------------------- |
709 | |
710 | //void OSD::Handler(const OSD_Signals aSig, |
711 | // const OSD_Signals aCode){} |
712 | void OSD::Handler(const OSD_Signals theSignal, |
713 | const Standard_Address theSigInfo, |
714 | const Standard_Address theContext) {} |
715 | |
716 | void OSD::SegvHandler(const OSD_Signals aSig, |
717 | const Standard_Address code, |
718 | const Standard_Address scp){} |
719 | |
720 | #endif // WNT |
721 | |
722 | |
723 | //======================================================================= |
724 | //function : UseSETranslator |
725 | //purpose : Defines whether to use _se_translator_function or |
726 | // SetUnhandledExceptionFilter and signal to catch system exceptions |
727 | //======================================================================= |
728 | |
729 | void OSD::UseSETranslator( const Standard_Boolean |
730 | #ifdef _MSC_VER |
731 | useSE |
732 | #endif |
733 | ) |
734 | { |
735 | #ifdef _MSC_VER |
736 | fSETranslator = useSE; |
737 | #endif |
738 | } |
739 | |
740 | Standard_Boolean OSD::UseSETranslator() |
741 | { |
742 | return fSETranslator; |
743 | } |