From 593fb383e0b1cb5b124f5254929789adf84e956a Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 12 Nov 2015 17:05:27 +0100 Subject: Fix processing of unhandled exception in exception filter This change fixes processing of unhandled exceptions in exception filter on Unix. Before this fix, such exception leads to assert in the exception handling code due to the fact that the exception tracker of the unhandled exception is not popped from the exception tracker stack of the thread. Although the PopTrackers method was being called, it bailed out due to the fact that the exception tracker belonging to the unhandled exception has empty scanned stack range. The fix is to explicitly pop the tracker in the EX_CATCH that catches the exception from the filter. I have also re-enabled the JIT test b68872 that has uncovered the issue. --- src/vm/exceptionhandling.cpp | 29 ++++++++++++++++++++++++++++- tests/testsFailingOutsideWindows.txt | 1 - 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp index 0cb1f2367e..d6c551cdce 100644 --- a/src/vm/exceptionhandling.cpp +++ b/src/vm/exceptionhandling.cpp @@ -2944,6 +2944,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( } EX_CATCH { + // We had an exception in filter invocation that remained unhandled. #ifndef FEATURE_PAL if (impersonating) { @@ -2952,9 +2953,35 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( COMPrincipal::CLR_ImpersonateLoggedOnUser(m_hImpersonationToken); impersonating = FALSE; } +#else // !FEATURE_PAL + { + // Since we have caught the exception from the filter here in the native code, + // the exception tracker is still in the cleaned up state that we've created + // before starting native frames unwind in the UnwindManagedExceptionPass2. + // We can remove the tracker since we don't need any of the information that + // it contains anymore. + + // To be safe to pop the tracker, we need to be in cooperative mode to make sure + // the GC won't get triggered in the middle of the tracker removal. + GCX_COOP(); + ExceptionTracker* pTrackerToFree = pThread->GetExceptionState()->m_pCurrentTracker; + CONSISTENCY_CHECK(pTrackerToFree->IsValid()); + _ASSERTE(pTrackerToFree->m_ScannedStackRange.IsEmpty()); + + EH_LOG((LL_INFO100, "Unlinking ExceptionTracker object 0x%p, thread = 0x%p\n", pTrackerToFree, pTrackerToFree->m_pThread)); + + // free managed tracker resources causing notification -- do this before unlinking the tracker + // this is necessary so that we know an exception is still in flight while we give the notification + FreeTrackerMemory(pTrackerToFree, memManaged); + + // unlink the tracker from the thread + pThread->GetExceptionState()->m_pCurrentTracker = pTrackerToFree->m_pPrevNestedInfo; + + // free unmanaged tracker resources + FreeTrackerMemory(pTrackerToFree, memUnmanaged); + } #endif // !FEATURE_PAL - // We had an exception in filter invocation that remained unhandled. // Sync managed exception state, for the managed thread, based upon the active exception tracker. pThread->SyncManagedExceptionState(false); diff --git a/tests/testsFailingOutsideWindows.txt b/tests/testsFailingOutsideWindows.txt index 113a3e6cc7..769ace21d2 100644 --- a/tests/testsFailingOutsideWindows.txt +++ b/tests/testsFailingOutsideWindows.txt @@ -76,7 +76,6 @@ JIT/Regression/CLR-x86-JIT/V1-M12-Beta2/b31746/b31746/b31746.sh JIT/Regression/CLR-x86-JIT/V1-M12-Beta2/b37646/b37646/b37646.sh JIT/Regression/CLR-x86-JIT/V1-M12-Beta2/b41852/b41852/b41852.sh JIT/Regression/CLR-x86-JIT/V1-M12-Beta2/b51575/b51575/b51575.sh -JIT/Regression/CLR-x86-JIT/V1-M12-Beta2/b68872/b68872/b68872.sh JIT/Regression/CLR-x86-JIT/V1-M13-RTM/b88793/b88793/b88793.sh JIT/Regression/CLR-x86-JIT/V1-M13-RTM/b91248/b91248/b91248.sh JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b409748/b409748/b409748.sh -- cgit v1.2.3