namespace os {
-/*
- * Trick from http://locklessinc.com/articles/pthreads_on_windows/
- */
-static CRITICAL_SECTION
-criticalSection = {
- (PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0
-};
-
-
-void
-acquireMutex(void)
-{
- EnterCriticalSection(&criticalSection);
-}
-
-
-void
-releaseMutex(void)
-{
- LeaveCriticalSection(&criticalSection);
-}
-
-
String
getProcessName(void)
{
&processInformation
)) {
log("error: failed to execute %s\n", arg0);
+ return -1;
}
WaitForSingleObject(processInformation.hProcess, INFINITE);
}
-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;
}
- if (prevExceptionFilter) {
- return prevExceptionFilter(pExceptionInfo);
+ /*
+ * 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;
+ }
+
+ // 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
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;
+ }
}