0024048: "Basic Runtime Checks" option of VS projects should be equal to "RTC1"
[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
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
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
b2d3f231 73static 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
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//=======================================================================
269static 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//=======================================================================
328Standard_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 352static 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//=======================================================================
368void 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
424void 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
439static 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
458static 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
530LONG _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){}
623void OSD::Handler(const OSD_Signals theSignal,
624 const Standard_Address theSigInfo,
625 const Standard_Address theContext) {}
626
627void OSD::SegvHandler(const OSD_Signals aSig,
628 const Standard_Address code,
629 const Standard_Address scp){}
630
631#endif // WNT