summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2015-04-27 07:57:57 -0700
committerJan Kotas <jkotas@microsoft.com>2015-04-27 07:57:57 -0700
commit05e2aa8577806dba3ee794555e2964be4504cd2d (patch)
tree59f2ac8412809929c42583c83a22a2f2aacef6a3
parent1883cd4a5ee07d8f5ae945ae6037d06d751c74fc (diff)
parentec2354ec577b1fbe591018aa9fff6a769e3d2df4 (diff)
downloadcoreclr-05e2aa8577806dba3ee794555e2964be4504cd2d.tar.gz
coreclr-05e2aa8577806dba3ee794555e2964be4504cd2d.tar.bz2
coreclr-05e2aa8577806dba3ee794555e2964be4504cd2d.zip
Merge pull request #829 from janvorli/fix-secondary-thread-gc
Fix GC of other thread during native frames unwinding
-rw-r--r--src/vm/exceptionhandling.cpp24
-rw-r--r--src/vm/exceptionhandling.h7
2 files changed, 25 insertions, 6 deletions
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index ed5e162e9a..5f87ccf093 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -4589,10 +4589,20 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex)
*currentFlags = firstPassFlags;
- // Pop all frames that are below the block of native frames and that would be
- // in the unwound part of the stack when UnwindManagedExceptionPass1 is resumed
- // at the next managed frame.
- UnwindFrameChain(GetThread(), (VOID*)frameContext.Rsp);
+ {
+ GCX_COOP();
+ // Pop all frames that are below the block of native frames and that would be
+ // in the unwound part of the stack when UnwindManagedExceptionPass1 is resumed
+ // at the next managed frame.
+ UnwindFrameChain(GetThread(), (VOID*)frameContext.Rsp);
+
+ // We are going to reclaim the stack range that was scanned by the exception tracker
+ // until now. We need to reset the explicit frames range so that if GC fires before
+ // we recreate the tracker at the first managed frame after unwinding the native
+ // frames, it doesn't attempt to scan the reclaimed stack range.
+ ExceptionTracker* pTracker = GetThread()->GetExceptionState()->GetCurrentExceptionTracker();
+ pTracker->ResetUnwoundExplicitFramesRange();
+ }
// Now we need to unwind the native frames until we reach managed frames again or the exception is
// handled in the native code.
@@ -4961,8 +4971,10 @@ VOID PALAPI HandleHardwareException(PAL_SEHException* ex)
#if defined(WIN64EXCEPTIONS)
*((&fef)->GetGSCookiePtr()) = GetProcessGSCookie();
#endif // WIN64EXCEPTIONS
- GCX_COOP();
- fef.InitAndLink(&ex->ContextRecord);
+ {
+ GCX_COOP(); // Must be cooperative to modify frame chain.
+ fef.InitAndLink(&ex->ContextRecord);
+ }
#ifdef _AMD64_
// It is possible that an overflow was mapped to a divide-by-zero exception.
diff --git a/src/vm/exceptionhandling.h b/src/vm/exceptionhandling.h
index c8581e3b95..72db3576a3 100644
--- a/src/vm/exceptionhandling.h
+++ b/src/vm/exceptionhandling.h
@@ -298,6 +298,13 @@ public:
return m_pInitialExplicitFrame;
}
+ // Reset the range of explicit frames that covers already unwound frames.
+ void ResetUnwoundExplicitFramesRange()
+ {
+ m_pInitialExplicitFrame = NULL;
+ m_pLimitFrame = NULL;
+ }
+
// Determines if we have unwound to the specified parent method frame.
// Currently this is only used for funclet skipping.
static bool IsUnwoundToTargetParentFrame(CrawlFrame * pCF, StackFrame sfParent);