Avoid re-entrancy between __sanitizer::Report, OutputDebugString, and RtlRaiseException
authorReid Kleckner <rnk@google.com>
Thu, 4 Aug 2016 20:05:13 +0000 (20:05 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 4 Aug 2016 20:05:13 +0000 (20:05 +0000)
Our Report implementation calls OutputDebugString, which calls
RtlRaiseException, which can re-enter back into the ASan runtime and
cause a hang.

Don't treat this special debugger-only exception code as a noreturn
event, since the stack won't really unwind all the way.

llvm-svn: 277763

compiler-rt/lib/asan/asan_win.cc

index cb03821..97a913e 100644 (file)
@@ -71,9 +71,12 @@ void __asan_default_on_error() {}
 }  // extern "C"
 
 // ---------------------- Windows-specific interceptors ---------------- {{{
-INTERCEPTOR_WINAPI(void, RtlRaiseException, void *ExceptionRecord) {
+INTERCEPTOR_WINAPI(void, RtlRaiseException, EXCEPTION_RECORD *ExceptionRecord) {
   CHECK(REAL(RtlRaiseException));
-  __asan_handle_no_return();
+  // This is a noreturn function, unless it's one of the exceptions raised to
+  // communicate with the debugger, such as the one from OutputDebugString.
+  if (ExceptionRecord->ExceptionCode != DBG_PRINTEXCEPTION_C)
+    __asan_handle_no_return();
   REAL(RtlRaiseException)(ExceptionRecord);
 }