diff --git a/checkin_notes b/checkin_notes index e6bb4d54c7..6443a470db 100755 --- a/checkin_notes +++ b/checkin_notes @@ -5232,3 +5232,11 @@ David 30 May 2006 wrapper.C (removed) tools/ backend_lib.C + +Rom 29 May 2006 + - Bug Fix: Wait until the exception monitor has finished initializing + before finishing boinc_diagnostics_init() in case the very next thing + the program does is throw an exception. + + lib/ + diagnostics_win.C diff --git a/lib/diagnostics_win.C b/lib/diagnostics_win.C index 1ed4d20678..f74743b230 100644 --- a/lib/diagnostics_win.C +++ b/lib/diagnostics_win.C @@ -620,18 +620,23 @@ typedef struct tagTHREADNAME_INFO { static LPTOP_LEVEL_EXCEPTION_FILTER pPreviousExceptionHandler = NULL; -LONG CALLBACK set_thread_name_exception_filter(PEXCEPTION_POINTERS pExPtrs) { +LONG WINAPI set_thread_name_exception_filter(PEXCEPTION_POINTERS pExPtrs) { if ( 0x406D1388 == pExPtrs->ExceptionRecord->ExceptionCode) { // This is the special exception code used to name threads // within a debugger. If no debugger is attached, then // continue execution of the application. return EXCEPTION_CONTINUE_EXECUTION; } + if (!pPreviousExceptionHandler) { + // This can happen if the default unhandled exception filter + // hasn't been initialized yet. No since dereferencing a + // NULL pointer. + return EXCEPTION_CONTINUE_SEARCH; + } return pPreviousExceptionHandler(pExPtrs); } -void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName ) -{ +void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName ) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; @@ -1303,6 +1308,7 @@ typedef struct _BOINC_WINDOWCAPTURE { static HANDLE hExceptionMonitorThread = NULL; static HANDLE hExceptionMonitorHalt = NULL; +static HANDLE hExceptionMonitorStartedEvent = NULL; static HANDLE hExceptionDetectedEvent = NULL; static HANDLE hExceptionQuitEvent = NULL; static HANDLE hExceptionQuitFinishedEvent = NULL; @@ -1327,6 +1333,15 @@ int diagnostics_init_unhandled_exception_monitor() { ); } + // The following event is thrown by the exception monitoring thread + // right before it waits for the hExceptionDetectedEvent event. + hExceptionMonitorStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!hExceptionMonitorStartedEvent) { + fprintf( + stderr, "diagnostics_init_unhandled_exception_monitor(): Creating hExceptionMonitorStartedEvent failed, GLE %d\n", GetLastError() + ); + } + // The following event is thrown by a thread that has experienced an // unhandled exception after storing its exception record but before // it attempts to aquire the halt mutex. @@ -1376,6 +1391,12 @@ int diagnostics_init_unhandled_exception_monitor() { stderr, "WARNING: BOINC Windows Runtime Debugger has been disabled.\n" ); retval = ERR_THREAD; + } else { + + // Wait until the exception monitor is ready for business. + // + WaitForSingleObject(hExceptionMonitorStartedEvent, INFINITE); + } return retval; @@ -1790,11 +1811,14 @@ UINT WINAPI diagnostics_unhandled_exception_monitor(LPVOID lpParameter) { // at bay until we are ready to deal with them. WaitForSingleObject(hExceptionMonitorHalt, INFINITE); - // Which events do we want to wait for? hEvents[0] = hExceptionQuitEvent; hEvents[1] = hExceptionDetectedEvent; + // Notify the initialization thread that initialization is complete and now + // we are waiting for an exception event. + SetEvent(hExceptionMonitorStartedEvent); + while (bContinue) { dwEvent = WaitForMultipleObjects( 2, // number of objects in array