Fix filter funclet handling during stack walk on Unix (#5183)
authorJan Vorlicek <janvorli@microsoft.com>
Tue, 24 May 2016 21:43:49 +0000 (23:43 +0200)
committerJan Vorlicek <janvorli@microsoft.com>
Tue, 24 May 2016 21:43:49 +0000 (23:43 +0200)
The filter funclets are not handled correctly during stack walk on Unix. When
the funclet's parent frame is reached, the filter funclet was mistakenly handled
as a non-filter funclet by the Unix specific code that is used to figure out
parent frames of funclets from exception trackers.
The fix is to skip this Unix specific code when we are looking for a parent of
a filter funclet. Filter funclet frame is always on the stack when the stack
walk reaches its parent frame.

src/vm/stackwalk.cpp

index 3c2dfd7f8430d9172847834c21afffdbd618173c..cb3c76e65199270a37ea4cfb6ca3f5a365a0bc2e 100644 (file)
@@ -1741,9 +1741,12 @@ ProcessFuncletsForGCReporting:
                         // was a caller of an already executed exception handler based on the previous exception trackers.
                         // The handler funclet frames are already gone from the stack, so the exception trackers are the
                         // only source of evidence about it.
+                        // The filter funclet is different though, its frame is always present on the stack when its parent
+                        // frame is reached by the stack walker, because no exception can escape a filter funclet.
                         // This is different from Windows where the full stack is preserved until an exception is fully handled
                         // and so we can detect it just from walking the stack.
-                        if (!fRecheckCurrentFrame && !fSkippingFunclet && (pTracker != NULL))
+                        bool fProcessingFilterFunclet = !m_sfFuncletParent.IsNull() && !(m_fProcessNonFilterFunclet || m_fProcessIntermediaryNonFilterFunclet);
+                        if (!fRecheckCurrentFrame && !fSkippingFunclet && (pTracker != NULL) && !fProcessingFilterFunclet)
                         {
                             // The stack walker is not skipping frames now, which means it didn't find a funclet frame that
                             // would require skipping the current frame. If we find a tracker with caller of actual handling