0023141: Suspicious if (2)
[occt.git] / src / OSD / OSD_signal_WNT.cxx
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
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 }