diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-05-06 23:43:46 -0700 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-05-07 12:03:00 -0700 |
commit | 484a2cf0b0c4e304a5093ec26e07fe41f8896c3c (patch) | |
tree | 348b56df4cdb235bb87ba9bc9118711c8db13bfd /src/vm/stackwalk.cpp | |
parent | c6efc7047edb38075310cfef8ea28b91717b8108 (diff) | |
download | coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.gz coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.bz2 coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.zip |
Merge changes from parent branch
[tfs-changeset: 1466545]
Diffstat (limited to 'src/vm/stackwalk.cpp')
-rw-r--r-- | src/vm/stackwalk.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp index d39ce06ef4..3301dec092 100644 --- a/src/vm/stackwalk.cpp +++ b/src/vm/stackwalk.cpp @@ -1510,6 +1510,7 @@ void StackFrameIterator::ResetCrawlFrame() m_crawl.isFilterFunclet = false; m_crawl.isFilterFuncletCached = false; m_crawl.fShouldParentToFuncletSkipReportingGCReferences = false; + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = false; #endif // WIN64EXCEPTIONS m_crawl.pThread = this->m_pThread; @@ -1669,6 +1670,10 @@ StackWalkAction StackFrameIterator::Filter(void) // CrawlFrame m_crawl.fShouldCrawlframeReportGCReferences = true; + // By default, assume that parent frame is going to report GC references from + // the actual location reported by the stack walk. + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = false; + if (!m_sfParent.IsNull()) { // we are now skipping frames to get to the funclet's parent @@ -1887,7 +1892,7 @@ ProcessFuncletsForGCReporting: _ASSERTE(m_fDidFuncletReportGCReferences); m_fDidFuncletReportGCReferences = false; - + STRESS_LOG0(LF_GCROOTS, LL_INFO100, "Unwound funclet will skip reporting references\n"); } } @@ -1913,6 +1918,9 @@ ProcessFuncletsForGCReporting: if (m_sfParent.IsMaxVal() || ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, m_sfParent)) { + // Reset flag as we have reached target method frame so no more skipping required + fSkippingFunclet = false; + // We've finished skipping as told. Now check again. if ((m_fProcessIntermediaryNonFilterFunclet == true) || (m_fProcessNonFilterFunclet == true)) @@ -1997,6 +2005,23 @@ ProcessFuncletsForGCReporting: // now that we've found the parent that will report roots reset our state. m_fDidFuncletReportGCReferences = true; + + // After funclet gets unwound parent will begin to report gc references. Reporting GC references + // using the IP of throw in parent method can crash application. Parent could have locals objects + // which might not have been reported by funclet as live and would have already been collected + // when funclet was on stack. Now if parent starts using IP of throw to report gc references it + // would report garbage values as live objects. So instead parent can use the IP of the resume + // address of catch funclet to report live GC references. + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = true; + // Store catch clause info. Helps retrieve IP of resume address. + m_crawl.ehClauseForCatch = pTracker->GetEHClauseForCatch(); + + STRESS_LOG3(LF_GCROOTS, LL_INFO100, + "STACKWALK: Parent of funclet which didn't report GC roots is handling an exception at 0x%p" + "(EH handler range [%x, %x) ), so we need to specially report roots to ensure variables alive" + " in its handler stay live.\n", + pTracker->GetCatchToCallPC(), m_crawl.ehClauseForCatch.HandlerStartPC, + m_crawl.ehClauseForCatch.HandlerEndPC); } else if (!m_crawl.IsFunclet()) { |