diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-02-26 11:21:47 +0100 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-02-26 11:21:47 +0100 |
commit | ebc23989bd97ba2c59ecc60f308c880d93530312 (patch) | |
tree | 85feeafcd38a1e7c10ec447e45ae20653539f9f1 /src/vm | |
parent | 597fb487b5391c0c57a2cef0d51e57c840e34422 (diff) | |
parent | 12f1fcdbec8cdc862953f90b4b420d3e4e74657b (diff) | |
download | coreclr-ebc23989bd97ba2c59ecc60f308c880d93530312.tar.gz coreclr-ebc23989bd97ba2c59ecc60f308c880d93530312.tar.bz2 coreclr-ebc23989bd97ba2c59ecc60f308c880d93530312.zip |
Merge pull request #3357 from janvorli/fix-stackwalk
Fix stack walker on Unix
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/exceptionhandling.h | 2 | ||||
-rw-r--r-- | src/vm/exstate.cpp | 4 | ||||
-rw-r--r-- | src/vm/stackwalk.cpp | 44 |
3 files changed, 27 insertions, 23 deletions
diff --git a/src/vm/exceptionhandling.h b/src/vm/exceptionhandling.h index 9acebc2767..d5dd4807ce 100644 --- a/src/vm/exceptionhandling.h +++ b/src/vm/exceptionhandling.h @@ -565,7 +565,7 @@ public: return m_EnclosingClauseInfoOfCollapsedTracker.GetEnclosingClauseCallerSP(); } -#ifndef FEATURE_PAL +#ifndef FEATURE_PAL private: EHWatsonBucketTracker m_WatsonBucketTracker; public: diff --git a/src/vm/exstate.cpp b/src/vm/exstate.cpp index ca0ac61b0a..bde71db884 100644 --- a/src/vm/exstate.cpp +++ b/src/vm/exstate.cpp @@ -538,6 +538,8 @@ BOOL DebuggerExState::SetDebuggerInterceptInfo(IJitManager *pJitManager, } #endif // DEBUGGING_SUPPORTED +#endif // DACCESS_COMPILE + EHClauseInfo* ThreadExceptionState::GetCurrentEHClauseInfo() { #ifdef WIN64EXCEPTIONS @@ -565,8 +567,6 @@ EHClauseInfo* ThreadExceptionState::GetCurrentEHClauseInfo() #endif // WIN64EXCEPTIONS } -#endif // DACCESS_COMPILE - void ThreadExceptionState::SetThreadExceptionFlag(ThreadExceptionFlag flag) { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp index 7c0fbb121d..ec9acfbac2 100644 --- a/src/vm/stackwalk.cpp +++ b/src/vm/stackwalk.cpp @@ -1753,36 +1753,40 @@ ProcessFuncletsForGCReporting: // and so we can detect it just from walking the stack. if (!fSkippingFunclet && (pTracker != NULL)) { - bool fFoundFuncletParent = false; - - // First check if the current frame is a caller of a funclet of a collapsed exception tracker - StackFrame sfFuncletParent = pTracker->GetCallerOfCollapsedActualHandlingFrame(); - if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent)) + // 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 + // frame matching the current frame, it means that the funclet stack frame was reclaimed. + StackFrame sfFuncletParent; + ExceptionTracker* pCurrTracker = pTracker; + bool hasFuncletStarted = m_crawl.pThread->GetExceptionState()->GetCurrentEHClauseInfo()->IsManagedCodeEntered(); + + while (pCurrTracker != NULL) { - fFoundFuncletParent = true; - } - else - { - ExceptionTracker* pCurrTracker = pTracker; - - // Scan all previous trackers and see if the current frame is a caller of any of - // the handling frames. - while ((pCurrTracker = pCurrTracker->GetPreviousExceptionTracker()) != NULL) + if (hasFuncletStarted) { sfFuncletParent = pCurrTracker->GetCallerOfActualHandlingFrame(); - if (ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent)) + if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent)) { - pTracker = pCurrTracker; - fFoundFuncletParent = true; - break; } } + + sfFuncletParent = pCurrTracker->GetCallerOfCollapsedActualHandlingFrame(); + if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent)) + { + break; + } + + // Funclets handling exception for trackers older than the current one were always started, + // since the current tracker was created due to an exception in the funclet belonging to + // the previous tracker. + hasFuncletStarted = true; + pCurrTracker = pCurrTracker->GetPreviousExceptionTracker(); } - if (fFoundFuncletParent) + if (pCurrTracker != NULL) { - // We have found that the current frame is a caller of a handling frame. + // The current frame is a parent of a funclet that was already unwound and removed from the stack // Set the members the same way we would set them on Windows when we // would detect this just from stack walking. m_sfParent = sfFuncletParent; |