From c6156f4dd78de5a54ecf025870d68d75eec56b5b Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Wed, 16 Feb 2022 22:36:29 -0800 Subject: [PATCH 1/3] Use CopyContext to restore saved context on X86 --- src/coreclr/vm/threadsuspend.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index b65cd74270b23e..0efea4b94a4295 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -2577,7 +2577,13 @@ int RedirectedHandledJITCaseExceptionFilter( pFrame->Pop(); // Copy the saved context record into the EH context; - ReplaceExceptionContextRecord(pExcepPtrs->ContextRecord, pCtx); + // NB: cannot use ReplaceExceptionContextRecord here. + // these contexts may contain extended registers and may have different format + // for reasons such as alignment or context compaction + // + // REVIEW: CopyContext may fail. in theory. How should we handle that? FailFast? + CONTEXT* pTarget = pExcepPtrs->ContextRecord; + CopyContext(pTarget, pTarget->ContextFlags, pCtx); DWORD espValue = pCtx->Esp; From 0e124a36ec846782ad42164d1f8c0938a275d25f Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:21:31 -0800 Subject: [PATCH 2/3] PR feedback --- src/coreclr/vm/threadsuspend.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index 0efea4b94a4295..bc9fab0a0855dd 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -2509,6 +2509,18 @@ void RedirectedThreadFrame::ExceptionUnwind() #ifndef TARGET_UNIX #ifdef TARGET_X86 + +// a helper to make sure these calls are not inlined into a filter function. +// in particular we do not want a possibility of inlined destructor calls. +NOINLINE void CopyContextHelper(CONTEXT* pTarget, CONTEXT* pCtx) +{ + if (!CopyContext(pTarget, pTarget->ContextFlags, pCtx)) + { + STRESS_LOG1(LF_SYNC, LL_ERROR, "ERROR: Could not set context record, lastError = 0x%x\n", GetLastError()); + ThrowLastError(); + } +} + //**************************************************************************************** // This will check who caused the exception. If it was caused by the the redirect function, // the reason is to resume the thread back at the point it was redirected in the first @@ -2580,10 +2592,8 @@ int RedirectedHandledJITCaseExceptionFilter( // NB: cannot use ReplaceExceptionContextRecord here. // these contexts may contain extended registers and may have different format // for reasons such as alignment or context compaction - // - // REVIEW: CopyContext may fail. in theory. How should we handle that? FailFast? CONTEXT* pTarget = pExcepPtrs->ContextRecord; - CopyContext(pTarget, pTarget->ContextFlags, pCtx); + CopyContextHelper(pTarget, pCtx); DWORD espValue = pCtx->Esp; From bae2f4526bd5fe253ca68d876ddbd76f6f760083 Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Thu, 17 Feb 2022 21:06:55 -0800 Subject: [PATCH 3/3] more PR feedback --- src/coreclr/vm/threadsuspend.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index bc9fab0a0855dd..3c6f46b4932bbe 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -2510,17 +2510,6 @@ void RedirectedThreadFrame::ExceptionUnwind() #ifdef TARGET_X86 -// a helper to make sure these calls are not inlined into a filter function. -// in particular we do not want a possibility of inlined destructor calls. -NOINLINE void CopyContextHelper(CONTEXT* pTarget, CONTEXT* pCtx) -{ - if (!CopyContext(pTarget, pTarget->ContextFlags, pCtx)) - { - STRESS_LOG1(LF_SYNC, LL_ERROR, "ERROR: Could not set context record, lastError = 0x%x\n", GetLastError()); - ThrowLastError(); - } -} - //**************************************************************************************** // This will check who caused the exception. If it was caused by the the redirect function, // the reason is to resume the thread back at the point it was redirected in the first @@ -2593,7 +2582,11 @@ int RedirectedHandledJITCaseExceptionFilter( // these contexts may contain extended registers and may have different format // for reasons such as alignment or context compaction CONTEXT* pTarget = pExcepPtrs->ContextRecord; - CopyContextHelper(pTarget, pCtx); + if (!CopyContext(pTarget, pTarget->ContextFlags, pCtx)) + { + STRESS_LOG1(LF_SYNC, LL_ERROR, "ERROR: Could not set context record, lastError = 0x%x\n", GetLastError()); + EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); + } DWORD espValue = pCtx->Esp;