0022545: Improved exception handling
[occt.git] / src / OSD / OSD_signal_WNT.cxx
CommitLineData
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
7fd59977 21#ifdef WNT
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
62static Standard_Boolean fMsgBox;
63static Standard_Boolean fFltExceptions;
64static Standard_Boolean fDbgLoaded;
65static Standard_Boolean fCtrlBrk;
66
0ac0c8b4
RL
67// used to forbid simultaneous execution of setting / executing handlers
68static Standard_Mutex THE_SIGNAL_MUTEX;
69
7fd59977 70static LONG __fastcall _osd_raise ( DWORD, LPTSTR );
71static BOOL WINAPI _osd_ctrl_break_handler ( DWORD );
72
73extern "C" Standard_EXPORT LONG _osd_debug ( void );
7fd59977 74
75MB_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//=======================================================================
91static 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
230 int idx = lstrlen ( buffer );
231
232
233 if ( idx && fMsgBox && dwExceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION ) {
0ac0c8b4
RL
234 // reset FP operations before message box, otherwise it may fail to show up
235 _fpreset();
236 _clearfp();
237
7fd59977 238 MessageBeep ( MB_ICONHAND );
239 int msgID = MsgBox ( NULL, buffer, TEXT( "Error detected" ), 4, fatalErrorDesc );
240// cout << "flterr" << flterr << " fFltExceptions " << fFltExceptions << endl ;
241 if ( flterr ) {
242 if ( !fFltExceptions )
243 return EXCEPTION_EXECUTE_HANDLER;
244 _fpreset () ;
245 _clearfp() ;
246 _controlfp ( 0, _OSD_FPX ) ; // JR add :
247// cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ;
248 }
249 buffer[ idx ] = 0;
250 switch ( msgID ) {
251 case IDYES: {
252 PTCHAR ptr = _tcschr ( buffer, TEXT( '\n' ) );
253 if ( ptr != NULL )
254 *ptr = TEXT( ' ' );
255// cout << "CallHandler " << dwExceptionCode << endl ;
256 _osd_raise ( dwExceptionCode, buffer );
257 } // IDYES
258 case IDNO:
259 LONG action ;
260 action = _osd_debug ();
261// cout << "return from CallHandler -> DebugBreak " << endl ;
262 DebugBreak ();
263 _osd_raise ( dwExceptionCode, buffer );
264// cout << "CallHandler return : " << action << endl ;
265 return action ;
266 case IDCANCEL:
267 exit ( 0xFFFF );
268 } // end switch
269 }
270 else {
271 if ( flterr ) {
272 if ( !fFltExceptions )
273 return EXCEPTION_EXECUTE_HANDLER;
274 _fpreset () ;
275 _clearfp() ;
276 _controlfp ( 0, _OSD_FPX ) ; // JR add :
277// cout << "OSD::WntHandler _controlfp( 0, _OSD_FPX ) " << hex << _controlfp(0,0) << dec << endl ;
278 }
279 }
7fd59977 280 return _osd_raise ( dwExceptionCode, buffer );
7fd59977 281#else
282 return 0;
283#endif
0ac0c8b4
RL
284}
285
286//=======================================================================
287//function : SIGWntHandler
288//purpose : Will only be used if user calls ::raise() function with
289// signal type set in OSD::SetSignal() - SIGSEGV, SIGFPE, SIGILL
290// (the latter will likely be removed in the future)
291//=======================================================================
292static void SIGWntHandler (int signum, int sub_code)
293{
294#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
295 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
296 switch( signum ) {
297 case SIGFPE :
298 if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
299 cout << "signal error" << endl ;
300 switch( sub_code ) {
301 case _FPE_INVALID :
302 CallHandler( EXCEPTION_FLT_INVALID_OPERATION ,0,0) ;
303 break ;
304 case _FPE_DENORMAL :
305 CallHandler( EXCEPTION_FLT_DENORMAL_OPERAND ,0,0) ;
306 break ;
307 case _FPE_ZERODIVIDE :
308 CallHandler( EXCEPTION_FLT_DIVIDE_BY_ZERO ,0,0) ;
309 break ;
310 case _FPE_OVERFLOW :
311 CallHandler( EXCEPTION_FLT_OVERFLOW ,0,0) ;
312 break ;
313 case _FPE_UNDERFLOW :
314 CallHandler( EXCEPTION_FLT_UNDERFLOW ,0,0) ;
315 break ;
316 case _FPE_INEXACT :
317 CallHandler( EXCEPTION_FLT_INEXACT_RESULT ,0,0) ;
318 break ;
319 default:
320 cout << "SIGWntHandler(default) -> Standard_NumericError::Raise(\"Floating Point Error\");"
321 << endl ;
322 Standard_NumericError::Raise("Floating Point Error");
323 break ;
324 }
325 break ;
326 case SIGSEGV :
327 if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
328 cout << "signal error" << endl ;
329 CallHandler( EXCEPTION_ACCESS_VIOLATION ,0,0) ;
330 break ;
331 case SIGILL :
332 if ( signal( signum , ( void (*)(int) ) &SIGWntHandler ) == SIG_ERR )
333 cout << "signal error" << endl ;
334 CallHandler( EXCEPTION_ILLEGAL_INSTRUCTION ,0,0) ;
335 break ;
336 default:
337 cout << "SIGWntHandler unexpected signal : "
338 << signum << endl ;
339 break ;
340 }
341 DebugBreak ();
342#endif
343}
344
345//=======================================================================
346//function : WntHandler
347//purpose : Will be used when user's code is compiled with /EHs
348// option and unless user sets his own exception handler with
349// ::SetUnhandledExceptionFilter().
350//=======================================================================
351Standard_Integer OSD::WntHandler (const Standard_Address theExceptionInfo)
352{
353 LPEXCEPTION_POINTERS lpXP = (LPEXCEPTION_POINTERS )theExceptionInfo;
354 DWORD dwExceptionCode = lpXP->ExceptionRecord->ExceptionCode;
7fd59977 355
0ac0c8b4
RL
356 return CallHandler (dwExceptionCode,
357 lpXP->ExceptionRecord->ExceptionInformation[1],
358 lpXP->ExceptionRecord->ExceptionInformation[0]);
359}
7fd59977 360
361//=======================================================================
362//function : TranslateSE
363//purpose : Translate Structural Exceptions into C++ exceptions
0ac0c8b4 364// Will be used when user's code is compiled with /EHa option
7fd59977 365//=======================================================================
7fd59977 366#ifdef _MSC_VER
0ac0c8b4
RL
367
368// If this file compiled with the default MSVC options for exception
369// handling (/GX or /EHsc) then the following warning is issued:
370// warning C4535: calling _set_se_translator() requires /EHa
371// However it is correctly inserted and used when user's code compiled with /EHa.
372// So, here we disable the warning.
373#pragma warning (disable:4535)
374
7fd59977 375static void TranslateSE( unsigned int theCode, EXCEPTION_POINTERS* theExcPtr )
376{
0ac0c8b4 377 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
7fd59977 378 ptrdiff_t info1 = 0, info0 = 0;
379 if ( theExcPtr ) {
380 info1 = theExcPtr->ExceptionRecord->ExceptionInformation[1];
381 info0 = theExcPtr->ExceptionRecord->ExceptionInformation[0];
382 }
383 CallHandler(theCode, info1, info0);
384}
385#endif
386
0ac0c8b4
RL
387//=======================================================================
388//function : SetSignal
389//purpose :
390//=======================================================================
391void OSD::SetSignal (const Standard_Boolean theFloatingSignal)
392{
7fd59977 393#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
0ac0c8b4
RL
394 Standard_Mutex::Sentry aSentry (THE_SIGNAL_MUTEX); // lock the mutex to prevent simultaneous handling
395 LPTOP_LEVEL_EXCEPTION_FILTER aPreviousFilter;
396
397 OSD_Environment env (TEXT("CSF_DEBUG_MODE"));
398 TCollection_AsciiString val = env.Value();
399 if (!env.Failed())
400 {
401 cout << "Environment variable CSF_DEBUG_MODE setted.\n";
402 fMsgBox = Standard_True;
403 }
404 else
405 {
406 fMsgBox = Standard_False;
407 }
7fd59977 408
0ac0c8b4
RL
409 // Set exception handler (ignored when running under debugger). It will be used in most cases
410 // when user's code is compiled with /EHs
411 // Replaces the existing top-level exception filter for all existing and all future threads
412 // in the calling process
413 aPreviousFilter = ::SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER )&OSD::WntHandler);
414
415 // Signal handlers will only be used when the method ::raise() will be used
416 // Handlers must be set for every thread
417 if (signal (SIGSEGV, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
418 cout << "signal(OSD::SetSignal) error\n";
419 if (signal (SIGFPE, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
420 cout << "signal(OSD::SetSignal) error\n";
421 if (signal (SIGILL, (void (*)(int ) )&SIGWntHandler) == SIG_ERR)
422 cout << "signal(OSD::SetSignal) error\n";
423
424 // Set Ctrl-C and Ctrl-Break handler
425 fCtrlBrk = Standard_False;
426 SetConsoleCtrlHandler (&_osd_ctrl_break_handler, TRUE);
7fd59977 427
428#ifdef _MSC_VER
0ac0c8b4 429 _se_translator_function pOldSeFunc = _set_se_translator (TranslateSE);
7fd59977 430#endif
431
0ac0c8b4
RL
432 fFltExceptions = theFloatingSignal;
433 if (theFloatingSignal)
434 {
435 _controlfp (0, _OSD_FPX); // JR add :
436 }
437 else {
438 _controlfp (_OSD_FPX, _OSD_FPX); // JR add :
439 }
7fd59977 440#endif
7fd59977 441} // end OSD :: SetSignal
442
443//============================================================================
444//==== ControlBreak
445//============================================================================
446
447void OSD :: ControlBreak () {
448
449 if ( fCtrlBrk ) {
450
451 fCtrlBrk = Standard_False;
452 OSD_Exception_CTRL_BREAK :: Raise ( TEXT( "*** INTERRUPT ***" ) );
453
454 } // end if
455
456} // end OSD :: ControlBreak
457
458//============================================================================
459//==== _osd_ctrl_break_handler
460//============================================================================
461
462static BOOL WINAPI _osd_ctrl_break_handler ( DWORD dwCode ) {
463
464 if ( dwCode == CTRL_C_EVENT || dwCode == CTRL_BREAK_EVENT ) {
465
466 MessageBeep ( MB_ICONEXCLAMATION );
467 fCtrlBrk = Standard_True;
468
469 } else
470
471 exit ( 254 );
472
473 return TRUE;
474
475} // end _osd_ctrl_break_handler
476
477//============================================================================
478//==== _osd_raise
479//============================================================================
480
481static LONG __fastcall _osd_raise ( DWORD dwCode, LPTSTR msg )
482{
0ac0c8b4
RL
483 if (msg[0] == TEXT('\x03')) ++msg;
484
485 switch (dwCode)
486 {
487 case EXCEPTION_ACCESS_VIOLATION:
488 OSD_Exception_ACCESS_VIOLATION::Raise (msg);
489 break;
490 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
491 OSD_Exception_ARRAY_BOUNDS_EXCEEDED::Raise (msg);
492 break;
493 case EXCEPTION_DATATYPE_MISALIGNMENT:
494 Standard_ProgramError::Raise (msg);
495 break;
496 case EXCEPTION_ILLEGAL_INSTRUCTION:
497 OSD_Exception_ILLEGAL_INSTRUCTION::Raise (msg);
498 break;
499 case EXCEPTION_IN_PAGE_ERROR:
500 OSD_Exception_IN_PAGE_ERROR::Raise (msg);
501 break;
502 case EXCEPTION_INT_DIVIDE_BY_ZERO:
503 Standard_DivideByZero::Raise (msg);
504 break;
505 case EXCEPTION_INT_OVERFLOW:
506 OSD_Exception_INT_OVERFLOW::Raise (msg);
507 break;
508 case EXCEPTION_INVALID_DISPOSITION:
509 OSD_Exception_INVALID_DISPOSITION::Raise (msg);
510 break;
511 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
512 OSD_Exception_NONCONTINUABLE_EXCEPTION::Raise (msg);
513 break;
514 case EXCEPTION_PRIV_INSTRUCTION:
515 OSD_Exception_PRIV_INSTRUCTION::Raise (msg);
516 break;
517 case EXCEPTION_STACK_OVERFLOW:
518 OSD_Exception_STACK_OVERFLOW::Raise (msg);
519 break;
520 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
521 Standard_DivideByZero::Raise (msg);
522 break;
523 case EXCEPTION_FLT_STACK_CHECK:
524 case EXCEPTION_FLT_OVERFLOW:
525 Standard_Overflow::Raise (msg);
526 break;
527 case EXCEPTION_FLT_UNDERFLOW:
528 Standard_Underflow::Raise (msg);
529 break;
530 case EXCEPTION_FLT_INVALID_OPERATION:
531 case EXCEPTION_FLT_DENORMAL_OPERAND:
532 case EXCEPTION_FLT_INEXACT_RESULT:
533 case STATUS_FLOAT_MULTIPLE_TRAPS:
534 case STATUS_FLOAT_MULTIPLE_FAULTS:
535 Standard_NumericError::Raise (msg);
536 break;
537 default:
538 break;
539 } // end switch
540 return EXCEPTION_EXECUTE_HANDLER;
7fd59977 541} // end _osd_raise
542
543//============================================================================
544//==== _osd_debug
545//============================================================================
546
547#if defined(__CYGWIN32__) || defined(__MINGW32__)
548#define __try
549#define __finally
550#define __leave return 0
551#endif
552
553LONG _osd_debug ( void ) {
554
555 LONG action ;
556
557 if ( !fDbgLoaded ) {
558
559 HKEY hKey;
560 HANDLE hEvent = INVALID_HANDLE_VALUE;
561 DWORD dwKeyType;
562 DWORD dwValueLen;
563 TCHAR keyValue[ MAX_PATH ];
564 TCHAR cmdLine[ MAX_PATH ];
565 SECURITY_ATTRIBUTES sa;
566 PROCESS_INFORMATION pi;
567 STARTUPINFO si;
568
569 __try {
570
571 if ( RegOpenKey (
572 HKEY_LOCAL_MACHINE,
573 TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" ),
574 &hKey
575 ) != ERROR_SUCCESS
576 ) __leave;
577
578 dwValueLen = sizeof ( keyValue );
579
580 if ( RegQueryValueEx (
581 hKey, TEXT( "Debugger" ), NULL, &dwKeyType, ( unsigned char* )keyValue, &dwValueLen
582 ) != ERROR_SUCCESS
583 ) __leave;
584
585 sa.nLength = sizeof ( SECURITY_ATTRIBUTES );
586 sa.lpSecurityDescriptor = NULL;
587 sa.bInheritHandle = TRUE;
588
589 if ( ( hEvent = CreateEvent ( &sa, TRUE, FALSE, NULL ) ) == NULL ) __leave;
590
591 wsprintf ( cmdLine, keyValue, GetCurrentProcessId (), hEvent );
592
593 ZeroMemory ( &si, sizeof ( STARTUPINFO ) );
594
595 si.cb = sizeof ( STARTUPINFO );
596 si.dwFlags = STARTF_FORCEONFEEDBACK;
597
598// cout << "_osd_debug -> CreateProcess" << endl ;
599 if ( !CreateProcess (
600 NULL, cmdLine, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
601 NULL, NULL, &si, &pi
602 )
603 ) __leave;
604
605// cout << "_osd_debug -> WaitForSingleObject " << endl ;
606 WaitForSingleObject ( hEvent, INFINITE );
607// cout << "_osd_debug <- WaitForSingleObject -> CloseHandle " << endl ;
608
609 CloseHandle ( pi.hProcess );
610 CloseHandle ( pi.hThread );
611
612// cout << "_osd_debug fDbgLoaded " << endl ;
613 fDbgLoaded = TRUE;
614
615 } // end __try
616
617 __finally {
618
619// cout << "_osd_debug -> CloseHandle(hKey) " << endl ;
620 if ( hKey != INVALID_HANDLE_VALUE ) CloseHandle ( hKey );
621// cout << "_osd_debug -> CloseHandle(hEvent) " << endl ;
622 if ( hEvent != INVALID_HANDLE_VALUE ) CloseHandle ( hEvent );
623// cout << "_osd_debug end __finally " << endl ;
624
625 } // end __finally
626
627 } /* end if */
628
629 action = fDbgLoaded ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;
630// cout << "_osd_debug return " << action << " EXCEPTION_CONTINUE_EXECUTION("
631// << EXCEPTION_CONTINUE_EXECUTION << ")" << endl ;
632 return action ;
633
634} // end _osd_debug
635
636#if defined(__CYGWIN32__) || defined(__MINGW32__)
637#undef __try
638#undef __finally
639#undef __leave
640#endif
641
7fd59977 642// Must be there for compatibility with UNIX system code ----------------------
643
644//void OSD::Handler(const OSD_Signals aSig,
645// const OSD_Signals aCode){}
646void OSD::Handler(const OSD_Signals theSignal,
647 const Standard_Address theSigInfo,
648 const Standard_Address theContext) {}
649
650void OSD::SegvHandler(const OSD_Signals aSig,
651 const Standard_Address code,
652 const Standard_Address scp){}
653
654#endif // WNT