summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-02-26 11:21:47 +0100
committerJan Vorlicek <janvorli@microsoft.com>2016-02-26 11:21:47 +0100
commitebc23989bd97ba2c59ecc60f308c880d93530312 (patch)
tree85feeafcd38a1e7c10ec447e45ae20653539f9f1 /src/vm
parent597fb487b5391c0c57a2cef0d51e57c840e34422 (diff)
parent12f1fcdbec8cdc862953f90b4b420d3e4e74657b (diff)
downloadcoreclr-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.h2
-rw-r--r--src/vm/exstate.cpp4
-rw-r--r--src/vm/stackwalk.cpp44
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;