From 70960ea0d810635d3a189b326c5fbd84fba97f33 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 23 Dec 2011 03:18:27 +0000 Subject: [PATCH] Use AddVectoredExceptionHandler Unlike SetUnhandledExceptionFilter it works for all threads. --- common/os_win32.cpp | 61 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/common/os_win32.cpp b/common/os_win32.cpp index 0b72433..7e1a544 100644 --- a/common/os_win32.cpp +++ b/common/os_win32.cpp @@ -258,21 +258,54 @@ abort(void) } -static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter = NULL; +static PVOID prevExceptionFilter = NULL; static void (*gCallback)(void) = NULL; -static LONG WINAPI -unhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) +static LONG CALLBACK +unhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { - if (gCallback) { - gCallback(); + PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; + + /* + * Ignore OutputDebugStringA exception. + */ + if (pExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C) { + return EXCEPTION_CONTINUE_SEARCH; + } + + /* + * Ignore C++ exceptions + * + * http://support.microsoft.com/kb/185294 + * http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + */ + if (pExceptionRecord->ExceptionCode == 0xe06d7363) { + return EXCEPTION_CONTINUE_SEARCH; } - if (prevExceptionFilter) { - return prevExceptionFilter(pExceptionInfo); + // Clear direction flag +#ifdef _MSC_VER + __asm { + cld + }; +#else + asm("cld"); +#endif + + log("apitrace: warning: caught exception 0x%08lx\n", pExceptionRecord->ExceptionCode); + + static int recursion_count = 0; + if (recursion_count) { + fprintf(stderr, "apitrace: warning: recursion handling exception\n"); } else { - return EXCEPTION_CONTINUE_SEARCH; + if (gCallback) { + ++recursion_count; + gCallback(); + --recursion_count; + } } + + return EXCEPTION_CONTINUE_SEARCH; } void @@ -285,19 +318,17 @@ setExceptionCallback(void (*callback)(void)) assert(!prevExceptionFilter); - /* - * TODO: Unfortunately it seems that the CRT will reset the exception - * handler in certain circumnstances. See - * http://www.codeproject.com/KB/winsdk/crash_hook.aspx - */ - prevExceptionFilter = SetUnhandledExceptionFilter(unhandledExceptionFilter); + prevExceptionFilter = AddVectoredExceptionHandler(0, unhandledExceptionHandler); } } void resetExceptionCallback(void) { - gCallback = NULL; + if (gCallback) { + RemoveVectoredExceptionHandler(prevExceptionFilter); + gCallback = NULL; + } } -- 2.43.0