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