diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index e0863771d4588c..2fe3fba668d368 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -7360,6 +7360,12 @@ VOID DECLSPEC_NORETURN UnwindAndContinueRethrowHelperAfterCatch(Frame* pEntryFra } else { +#ifdef FEATURE_INTERPRETER + if ((pEntryFrame != FRAME_TOP) && (pEntryFrame->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) + { + ((InterpreterFrame*)pEntryFrame)->SetIsFaulting(true); + } +#endif // FEATURE_INTERPRETER DispatchManagedException(orThrowable); } } diff --git a/src/coreclr/vm/frames.cpp b/src/coreclr/vm/frames.cpp index ad434fb4464c60..53ff4599c8453c 100644 --- a/src/coreclr/vm/frames.cpp +++ b/src/coreclr/vm/frames.cpp @@ -1894,6 +1894,11 @@ void InterpreterFrame::SetContextToInterpMethodContextFrame(T_CONTEXT * pContext SetSP(pContext, dac_cast(pFrame)); SetFP(pContext, (TADDR)pFrame->pStack); SetFirstArgReg(pContext, dac_cast(this)); + pContext->ContextFlags = CONTEXT_FULL; + if (m_isFaulting) + { + pContext->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE; + } } void InterpreterFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) diff --git a/src/coreclr/vm/frames.h b/src/coreclr/vm/frames.h index 892e55586d7abd..5a7d4e70ff29c3 100644 --- a/src/coreclr/vm/frames.h +++ b/src/coreclr/vm/frames.h @@ -2417,7 +2417,8 @@ class InterpreterFrame : public FramedMethodFrame #ifndef DACCESS_COMPILE InterpreterFrame(TransitionBlock* pTransitionBlock, InterpMethodContextFrame* pContextFrame) : FramedMethodFrame(FrameIdentifier::InterpreterFrame, pTransitionBlock, NULL), - m_pTopInterpMethodContextFrame(pContextFrame) + m_pTopInterpMethodContextFrame(pContextFrame), + m_isFaulting(false) #if defined(HOST_AMD64) && defined(HOST_WINDOWS) , m_SSP(0) #endif @@ -2471,10 +2472,18 @@ class InterpreterFrame : public FramedMethodFrame } #endif // HOST_AMD64 && HOST_WINDOWS + void SetIsFaulting(bool isFaulting) + { + LIMITED_METHOD_CONTRACT; + m_isFaulting = isFaulting; + } + private: // The last known topmost interpreter frame in the InterpExecMethod belonging to // this InterpreterFrame. PTR_InterpMethodContextFrame m_pTopInterpMethodContextFrame; + // Set to true to indicate that the topmost interpreted frame has thrown an exception + bool m_isFaulting; #if defined(HOST_AMD64) && defined(HOST_WINDOWS) // Saved SSP of the InterpExecMethod for resuming after catch into interpreter frames. TADDR m_SSP; diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 372e8b2cfbafc6..bddc4b77c16237 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1737,12 +1737,14 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr { throwable = LOCAL_VAR(ip[1], OBJECTREF); } + pInterpreterFrame->SetIsFaulting(true); DispatchManagedException(throwable); UNREACHABLE(); break; } case INTOP_RETHROW: { + pInterpreterFrame->SetIsFaulting(true); DispatchRethrownManagedException(); UNREACHABLE(); break; @@ -2220,6 +2222,8 @@ do { \ pMethod = pFrame->startIp->Method; assert(pMethod->CheckIntegrity()); pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; + + pInterpreterFrame->SetIsFaulting(false); goto MAIN_LOOP; } diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index 103aa7fe0db6db..c7275c7d9cbefa 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -2860,8 +2860,12 @@ void StackFrameIterator::ProcessCurrentFrame(void) m_interpExecMethodFirstArgReg = (TADDR)GetFirstArgReg(pRD->pCurrentContext); ((PTR_InterpreterFrame)m_crawl.pFrame)->SetContextToInterpMethodContextFrame(pRD->pCurrentContext); + if (pRD->pCurrentContext->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) + { + m_crawl.isInterrupted = true; + m_crawl.hasFaulted = true; + } - pRD->pCurrentContext->ContextFlags = CONTEXT_FULL; SyncRegDisplayToCurrentContext(pRD); ProcessIp(GetControlPC(pRD)); m_walkingInterpreterFrames = m_crawl.isFrameless;