diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 655a102407c119..4cf461f2b0acc5 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -818,6 +818,8 @@ UINT_PTR ExceptionTracker::FinishSecondPass( return uResumePC; } +void CleanUpForSecondPass(Thread* pThread, bool fIsSO, LPVOID MemoryStackFpForFrameChain, LPVOID MemoryStackFp); + // On CoreARM, the MemoryStackFp is ULONG when passed by RtlDispatchException, // unlike its 64bit counterparts. EXTERN_C EXCEPTION_DISPOSITION @@ -1262,6 +1264,22 @@ lExit: ; if ((ExceptionContinueSearch == returnDisposition)) { + if (dwExceptionFlags & EXCEPTION_UNWINDING) + { + EECodeInfo codeInfo(pDispatcherContext->ControlPc); + if (codeInfo.IsValid()) + { + GcInfoDecoder gcInfoDecoder(codeInfo.GetGCInfoToken(), DECODE_REVERSE_PINVOKE_VAR); + if (gcInfoDecoder.GetReversePInvokeFrameStackSlot() != NO_REVERSE_PINVOKE_FRAME) + { + // Exception is being propagated from a native callable method into its native caller. + // The explicit frame chain needs to be unwound at this boundary. + bool fIsSO = pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW; + CleanUpForSecondPass(pThread, fIsSO, (void*)MemoryStackFp, (void*)MemoryStackFp); + } + } + } + GCX_PREEMP_NO_DTOR(); } @@ -5824,7 +5842,7 @@ BOOL IsSafeToUnwindFrameChain(Thread* pThread, LPVOID MemoryStackFpForFrameChain // We're safe only if the managed method will be unwound also LPVOID managedSP = dac_cast(GetRegdisplaySP(&rd)); - if (managedSP < MemoryStackFpForFrameChain) + if (managedSP <= MemoryStackFpForFrameChain) { return TRUE; }