From bd56701594ff2f4dae5766750545f6c6c690be91 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 17 Jan 2023 22:50:36 +0100 Subject: [PATCH 1/9] Add EnC support for Linux and Mac Fix build break Fix arm build break --- src/coreclr/clrdefinitions.cmake | 8 ++--- src/coreclr/inc/eetwain.h | 8 ++--- src/coreclr/jit/codegenxarch.cpp | 2 +- src/coreclr/jit/targetamd64.h | 9 +++-- src/coreclr/vm/eetwain.cpp | 59 +++++++++++++++++++------------- src/coreclr/vm/encee.cpp | 6 +++- src/coreclr/vm/encee.h | 2 ++ 7 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index df637a400259e7..00e6673561eb2e 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -56,11 +56,9 @@ endif(CLR_CMAKE_HOST_WIN32) if (NOT (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX)) add_compile_definitions(EnC_SUPPORTED) endif() -if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64) - if(CLR_CMAKE_TARGET_WIN32) - add_compile_definitions(FEATURE_ENC_SUPPORTED) - endif(CLR_CMAKE_TARGET_WIN32) -endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64) +if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_WIN32)) + add_compile_definitions(FEATURE_ENC_SUPPORTED) +endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_WIN32)) if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) add_compile_definitions(OUT_OF_PROCESS_SETTHREADCONTEXT) diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h index bb5bf893b99ee7..91bb4c85c85a4b 100644 --- a/src/coreclr/inc/eetwain.h +++ b/src/coreclr/inc/eetwain.h @@ -332,7 +332,7 @@ virtual void LeaveCatch(GCInfoToken gcInfoToken, PCONTEXT pCtx)=0; #endif // FEATURE_EH_FUNCLETS -#ifdef EnC_SUPPORTED +#ifdef FEATURE_ENC_SUPPORTED /* Last chance for the runtime support to do fixups in the context @@ -347,7 +347,7 @@ virtual HRESULT FixContextForEnC(PCONTEXT pCtx, const ICorDebugInfo::NativeVarInfo * newMethodVars, SIZE_T newMethodVarsCount) = 0; -#endif // EnC_SUPPORTED +#endif // FEATURE_ENC_SUPPORTED #endif // #ifndef DACCESS_COMPILE @@ -597,7 +597,7 @@ virtual void LeaveCatch(GCInfoToken gcInfoToken, PCONTEXT pCtx); #endif // FEATURE_EH_FUNCLETS -#ifdef EnC_SUPPORTED +#ifdef FEATURE_ENC_SUPPORTED /* Last chance for the runtime support to do fixups in the context before execution continues inside an EnC updated function. @@ -610,7 +610,7 @@ HRESULT FixContextForEnC(PCONTEXT pCtx, EECodeInfo * pNewCodeInfo, const ICorDebugInfo::NativeVarInfo * newMethodVars, SIZE_T newMethodVarsCount); -#endif // EnC_SUPPORTED +#endif // FEATURE_ENC_SUPPORTED #endif // #ifndef DACCESS_COMPILE diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 23c79087d4f8c6..5847b40ffd32e2 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -8910,7 +8910,7 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize // -saved bool for synchronized methods // slots for ret address + FP + EnC callee-saves - int preservedAreaSize = (2 + genCountBits(RBM_ENC_CALLEE_SAVED)) * REGSIZE_BYTES; + int preservedAreaSize = (2 + genCountBits((uint64_t)RBM_ENC_CALLEE_SAVED)) * REGSIZE_BYTES; if (compiler->info.compFlags & CORINFO_FLG_SYNCH) { diff --git a/src/coreclr/jit/targetamd64.h b/src/coreclr/jit/targetamd64.h index 6d3f92fb6da901..4abe71984b57cf 100644 --- a/src/coreclr/jit/targetamd64.h +++ b/src/coreclr/jit/targetamd64.h @@ -303,6 +303,9 @@ /* NOTE: Sync with variable name defined in compiler.h */ #define REG_CALLEE_SAVED_ORDER REG_EBX,REG_ETW_FRAMED_EBP_LIST REG_R12,REG_R13,REG_R14,REG_R15 #define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_ETW_FRAMED_EBP_LIST RBM_R12,RBM_R13,RBM_R14,RBM_R15 + + // For SysV we have more volatile registers so we do not save any callee saves for EnC. + #define RBM_ENC_CALLEE_SAVED 0 #else // !UNIX_AMD64_ABI #define CNT_CALLEE_SAVED (7 + REG_ETW_FRAMED_EBP_COUNT) #define CNT_CALLEE_TRASH (7) @@ -314,6 +317,9 @@ /* NOTE: Sync with variable name defined in compiler.h */ #define REG_CALLEE_SAVED_ORDER REG_EBX,REG_ESI,REG_EDI,REG_ETW_FRAMED_EBP_LIST REG_R12,REG_R13,REG_R14,REG_R15 #define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_ESI,RBM_EDI,RBM_ETW_FRAMED_EBP_LIST RBM_R12,RBM_R13,RBM_R14,RBM_R15 + + // Callee-preserved registers we always save and allow use of for EnC code, since there are quite few volatile registers. + #define RBM_ENC_CALLEE_SAVED (RBM_RSI | RBM_RDI) #endif // !UNIX_AMD64_ABI #define CNT_CALLEE_TRASH_FLOAT get_CNT_CALLEE_TRASH_FLOAT() @@ -327,9 +333,6 @@ #define CALLEE_SAVED_REG_MAXSZ (CNT_CALLEE_SAVED*REGSIZE_BYTES) #define CALLEE_SAVED_FLOAT_MAXSZ (CNT_CALLEE_SAVED_FLOAT*16) - // callee-preserved registers we always save and allow use of for EnC code - #define RBM_ENC_CALLEE_SAVED (RBM_RSI | RBM_RDI) - // register to hold shift amount #define REG_SHIFT REG_ECX #define RBM_SHIFT RBM_ECX diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 1e16cb811bc6f9..e037f575818dd2 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -792,7 +792,7 @@ bool VarIsInReg(ICorDebugInfo::VarLoc varLoc) } } -#ifdef EnC_SUPPORTED +#ifdef FEATURE_ENC_SUPPORTED /***************************************************************************** * Last chance for the runtime support to do fixups in the context * before execution continues inside an EnC updated function. @@ -831,7 +831,6 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, T_CONTEXT oldCtx = *pCtx; #if defined(TARGET_X86) - LOG((LF_CORDB, LL_INFO100, "EECM::FixContextForEnC\n")); /* Extract the necessary information from the info block header */ @@ -997,22 +996,29 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, _ASSERTE(pOldCodeInfo->HasFrameRegister()); _ASSERTE(pNewCodeInfo->HasFrameRegister()); - LOG((LF_CORDB, LL_INFO100, "EECM::FixContextForEnC: Old and new fixed stack sizes are %u and %u\n", oldFixedStackSize, newFixedStackSize)); - - // x64: SP == FP before localloc - if (oldStackBase != GetFP(&oldCtx)) - return E_FAIL; #elif defined(TARGET_ARM64) DWORD oldFixedStackSize = oldGcDecoder.GetSizeOfEditAndContinueFixedStackFrame(); DWORD newFixedStackSize = newGcDecoder.GetSizeOfEditAndContinueFixedStackFrame(); +#else + PORTABILITY_ASSERT("Edit-and-continue not enabled on this platform."); +#endif LOG((LF_CORDB, LL_INFO100, "EECM::FixContextForEnC: Old and new fixed stack sizes are %u and %u\n", oldFixedStackSize, newFixedStackSize)); - // ARM64: FP + 16 == SP + oldFixedStackSize before localloc - if (GetFP(&oldCtx) + 16 != oldStackBase + oldFixedStackSize) +#if defined(TARGET_AMD64) && defined(HOST_WINDOWS) + // win-x64: SP == FP before localloc + if (oldStackBase != GetFP(&oldCtx)) + { return E_FAIL; + } #else - PORTABILITY_ASSERT("Edit-and-continue not enabled on this platform."); + // All other 64-bit targets use frame chaining with the FP stored right below the + // return address (LR is always pushed on arm64). FP + 16 == SP + oldFixedStackSize + // gives the caller's SP before stack alloc. + if (GetFP(&oldCtx) + 16 != oldStackBase + oldFixedStackSize) + { + return E_FAIL; + } #endif // EnC remap inside handlers is not supported @@ -1028,14 +1034,15 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, TADDR callerSP = oldStackBase + oldFixedStackSize; #ifdef _DEBUG - // If the old method has a PSPSym, then its value should == FP for x64 and callerSP for arm64 + // If the old method has a PSPSym, then its value should == initial-SP (i.e. + // oldStackBase) for x64 and callerSP for arm64 INT32 nOldPspSymStackSlot = oldGcDecoder.GetPSPSymStackSlot(); if (nOldPspSymStackSlot != NO_PSP_SYM) { #if defined(TARGET_AMD64) TADDR oldPSP = *PTR_TADDR(oldStackBase + nOldPspSymStackSlot); - _ASSERTE(oldPSP == GetFP(&oldCtx)); -#elif defined(TARGET_ARM64) + _ASSERTE(oldPSP == oldStackBase); +#else TADDR oldPSP = *PTR_TADDR(callerSP + nOldPspSymStackSlot); _ASSERTE(oldPSP == callerSP); #endif @@ -1222,8 +1229,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, #if defined(TARGET_X86) // Zero out all the registers as some may hold new variables. - pCtx->Eax = pCtx->Ecx = pCtx->Edx = pCtx->Ebx = - pCtx->Esi = pCtx->Edi = 0; + pCtx->Eax = pCtx->Ecx = pCtx->Edx = pCtx->Ebx = pCtx->Esi = pCtx->Edi = 0; // 3) zero out the stack frame - this'll initialize _all_ variables @@ -1240,7 +1246,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, _ASSERTE( frameHeaderSize <= oldInfo.stackSize ); _ASSERTE( GetSizeOfFrameHeaderForEnC( &oldInfo ) == frameHeaderSize ); -#elif defined(TARGET_AMD64) +#elif defined(TARGET_AMD64) && defined(HOST_WINDOWS) // Next few statements zero out all registers that may end up holding new variables. @@ -1276,7 +1282,8 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, // For EnC-compliant x64 code, FP == SP. Since SP changed above, update FP now pCtx->Rbp = newStackBase; -#elif defined(TARGET_ARM64) +#else +#if defined(TARGET_ARM64) // Zero out volatile part of stack frame // x0-x17 memset(&pCtx->X[0], 0, sizeof(pCtx->X[0]) * 18); @@ -1284,6 +1291,15 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, memset(&pCtx->V[0], 0, sizeof(pCtx->V[0]) * 8); // v16-v31 memset(&pCtx->V[16], 0, sizeof(pCtx->V[0]) * 16); +#elif defined(TARGET_AMD64) + // SysV ABI + pCtx->Rax = pCtx->Rdi = pCtx->Rsi = pCtx->Rdx = pCtx->Rcx = pCtx->R8 = pCtx->R9 = 0; + + // volatile float registers + memset(&pCtx->Xmm0, 0, sizeof(pCtx->Xmm0) * 16); +#else + PORTABILITY_ASSERT("Edit-and-continue not enabled on this platform."); +#endif TADDR newStackBase = callerSP - newFixedStackSize; @@ -1293,12 +1309,9 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, _ASSERTE(frameHeaderSize <= oldFixedStackSize); _ASSERTE(frameHeaderSize <= newFixedStackSize); - // EnC prolog saves only fp,lr and does it at sp-16. It should already - // be set up from previous version. + // EnC prolog saves only FP (and LR on arm64), and FP points to saved FP for frame chaining. + // These should already be set up from previous version. _ASSERTE(GetFP(pCtx) == callerSP - 16); - -#else // !X86 - PORTABILITY_ASSERT("Edit-and-continue not enabled on this platform."); #endif // Perform some debug-only sanity checks on stack variables. Some checks are @@ -1416,7 +1429,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, if (nNewPspSymStackSlot != NO_PSP_SYM) { #if defined(TARGET_AMD64) - *PTR_TADDR(newStackBase + nNewPspSymStackSlot) = GetFP(pCtx); + *PTR_TADDR(newStackBase + nNewPspSymStackSlot) = newStackBase; #elif defined(TARGET_ARM64) *PTR_TADDR(callerSP + nNewPspSymStackSlot) = callerSP; #else diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 56500271314b57..1dcfb8bf091f4c 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -733,9 +733,11 @@ HRESULT EditAndContinueModule::ResumeInUpdatedFunction( // Win32 handlers on the stack so cannot ever return from this function. EEPOLICY_HANDLE_FATAL_ERROR(CORDBG_E_ENC_INTERNAL_ERROR); return E_FAIL; -#endif // #if defined(TARGET_ARM) || defined(TARGET_LOONGARCH64) +#endif // #if defined(TARGET_ARM) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) + } +#ifdef FEATURE_ENC_SUPPORTED //--------------------------------------------------------------------------------------- // // FixContextAndResume - Modify the thread context for EnC remap and resume execution @@ -871,6 +873,8 @@ NOINLINE void EditAndContinueModule::FixContextAndResume( LOG((LF_ENC, LL_ERROR, "**Error** EnCModule::ResumeInUpdatedFunction returned from ResumeAtJit")); _ASSERTE(!"Should not return from ResumeAtJit()"); } +#endif // #ifdef FEATURE_ENC_SUPPORTED + #endif // #ifndef DACCESS_COMPILE //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/encee.h b/src/coreclr/vm/encee.h index ae3ed4a0158be7..0fe0a9d8d8229b 100644 --- a/src/coreclr/vm/encee.h +++ b/src/coreclr/vm/encee.h @@ -247,12 +247,14 @@ class EditAndContinueModule : public Module SIZE_T newILOffset, T_CONTEXT *pContext); +#ifdef FEATURE_ENC_SUPPORTED // Modify the thread context for EnC remap and resume execution void FixContextAndResume(MethodDesc *pMD, void *oldDebuggerFuncHandle, T_CONTEXT *pContext, EECodeInfo *pOldCodeInfo, EECodeInfo *pNewCodeInfo); +#endif // FEATURE_ENC_SUPPORTED // Get a pointer to the value of a field added by EnC or return NULL if it doesn't exist PTR_CBYTE ResolveField(OBJECTREF thisPointer, From 91df8106fca921024a49e263cb810307df9ab1b2 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 1 Jun 2023 15:32:20 -0700 Subject: [PATCH 2/9] Attempt to add support for exception interception Fix arm build issue Fix windows build break Remove incorrect comment on exception interception --- src/coreclr/debug/di/rsthread.cpp | 6 ----- src/coreclr/pal/inc/pal.h | 5 +++++ src/coreclr/vm/excep.h | 3 --- src/coreclr/vm/exceptionhandling.cpp | 33 ++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 5edd2dbd36aa14..4cc387235910c9 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -2135,11 +2135,6 @@ HRESULT CordbThread::InterceptCurrentException(ICorDebugFrame * pFrame) FAIL_IF_NEUTERED(this); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); -#if defined(FEATURE_DBGIPC_TRANSPORT_DI) - // Continuable exceptions are not implemented on Unix-like platforms. - return E_NOTIMPL; - -#else // !FEATURE_DBGIPC_TRANSPORT_DI HRESULT hr = S_OK; EX_TRY { @@ -2216,7 +2211,6 @@ HRESULT CordbThread::InterceptCurrentException(ICorDebugFrame * pFrame) } EX_CATCH_HRESULT(hr); return hr; -#endif // FEATURE_DBGIPC_TRANSPORT_DI } //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index d5541621f1fd2e..e691ee5e06d352 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -4490,6 +4490,7 @@ struct PAL_SEHException ExceptionPointers.ExceptionRecord = ex.ExceptionPointers.ExceptionRecord; ExceptionPointers.ContextRecord = ex.ExceptionPointers.ContextRecord; TargetFrameSp = ex.TargetFrameSp; + TargetIp = ex.TargetIp; RecordsOnStack = ex.RecordsOnStack; IsExternal = ex.IsExternal; ManagedToNativeExceptionCallback = ex.ManagedToNativeExceptionCallback; @@ -4512,6 +4513,8 @@ struct PAL_SEHException EXCEPTION_POINTERS ExceptionPointers; // Target frame stack pointer set before the 2nd pass. SIZE_T TargetFrameSp; + SIZE_T TargetIp; + SIZE_T ReturnValue; bool RecordsOnStack; // The exception is a hardware exception coming from a native code out of // the well known runtime helpers @@ -4525,6 +4528,7 @@ struct PAL_SEHException ExceptionPointers.ExceptionRecord = pExceptionRecord; ExceptionPointers.ContextRecord = pContextRecord; TargetFrameSp = NoTargetFrameSp; + TargetIp = 0; RecordsOnStack = onStack; IsExternal = false; ManagedToNativeExceptionCallback = NULL; @@ -4564,6 +4568,7 @@ struct PAL_SEHException ExceptionPointers.ExceptionRecord = NULL; ExceptionPointers.ContextRecord = NULL; TargetFrameSp = NoTargetFrameSp; + TargetIp = 0; RecordsOnStack = false; IsExternal = false; ManagedToNativeExceptionCallback = NULL; diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index 9030331474c73e..88abe0d39197b5 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -710,10 +710,7 @@ bool IsInterceptableException(Thread *pThread); // perform simple checking to see if the current exception is intercepted bool CheckThreadExceptionStateForInterception(); -#ifndef TARGET_UNIX -// Currently, only Windows supports ClrUnwindEx (used inside ClrDebuggerDoUnwindAndIntercept) #define DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED -#endif // !TARGET_UNIX #ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED // Intercept the current exception and start an unwind. This function may never return. diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index cec1175c9c022e..c5293b2825c711 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -4192,6 +4192,9 @@ void ExceptionTracker::MakeCallbacksRelatedToHandler( // Notes: // If the exception is intercepted, this function never returns. // +#ifdef HOST_UNIX +VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); +#endif // HOST_UNIX EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_REGISTRATION_RECORD* pCurrentEstablisherFrame) EXCEPTION_RECORD* pExceptionRecord) @@ -4210,7 +4213,16 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE (PBYTE*)&uInterceptStackFrame, NULL, NULL); +#ifdef HOST_UNIX + CONTEXT *pContext = pThread->GetExceptionState()->GetContextRecord(); + PAL_SEHException ex(pThread->GetExceptionState()->GetExceptionRecord(), pContext, /* onStack */ false); + ex.TargetIp = INVALID_RESUME_ADDRESS; + ex.TargetFrameSp = uInterceptStackFrame; + ex.ReturnValue = (UINT_PTR)pThread; + UnwindManagedExceptionPass2(ex, pContext); +#else // HOST_UNIX ClrUnwindEx(pExceptionRecord, (UINT_PTR)pThread, INVALID_RESUME_ADDRESS, uInterceptStackFrame); +#endif // HOST_UNIX UNREACHABLE(); } @@ -4554,6 +4566,27 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte } while (Thread::IsAddressInCurrentStack(sp) && (establisherFrame != ex.TargetFrameSp)); + if ((establisherFrame == ex.TargetFrameSp) && (ex.TargetIp != 0)) + { +#ifdef HOST_AMD64 +#define RETURN_REG Rax +#elif defined(HOST_ARM64) +#define RETURN_REG X0 +#elif defined(HOST_ARM) +#define RETURN_REG R0 +#elif defined(HOST_X86) +#define RETURN_REG Eax +#else +#error Missing definition of RETURN_REG for the current architecture +#endif + currentFrameContext->RETURN_REG = ex.ReturnValue; + if (ex.GetExceptionRecord()->ExceptionCode != STATUS_UNWIND_CONSOLIDATE) + { + SetIP(currentFrameContext, ex.TargetIp); + } + ExceptionTracker::ResumeExecution(currentFrameContext); + } + _ASSERTE(!"UnwindManagedExceptionPass2: Unwinding failed. Reached the end of the stack"); EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); } From 44dd918a17ddfed2e8636203d0591419fab1989b Mon Sep 17 00:00:00 2001 From: Tom McDonald Date: Thu, 10 Aug 2023 22:05:47 -0400 Subject: [PATCH 3/9] FIx build break on non-x86/x64/arm32/arm64 architectures --- src/coreclr/vm/excep.h | 2 ++ src/coreclr/vm/exceptionhandling.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index 88abe0d39197b5..6c627b971f446a 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -710,7 +710,9 @@ bool IsInterceptableException(Thread *pThread); // perform simple checking to see if the current exception is intercepted bool CheckThreadExceptionStateForInterception(); +#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_X86) #define DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED +#endif // defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_X86) #ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED // Intercept the current exception and start an unwind. This function may never return. diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index c5293b2825c711..78070bedee9cb7 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -4566,6 +4566,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte } while (Thread::IsAddressInCurrentStack(sp) && (establisherFrame != ex.TargetFrameSp)); +#ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED if ((establisherFrame == ex.TargetFrameSp) && (ex.TargetIp != 0)) { #ifdef HOST_AMD64 @@ -4586,6 +4587,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte } ExceptionTracker::ResumeExecution(currentFrameContext); } +#endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED _ASSERTE(!"UnwindManagedExceptionPass2: Unwinding failed. Reached the end of the stack"); EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); From 73d5e2d22da58b694e53ae1ba746f7765e100c61 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Fri, 11 Aug 2023 12:22:20 -0700 Subject: [PATCH 4/9] Host to Target --- src/coreclr/vm/excep.h | 4 ++-- src/coreclr/vm/exceptionhandling.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index 6c627b971f446a..082ba7b91a4c9c 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -710,9 +710,9 @@ bool IsInterceptableException(Thread *pThread); // perform simple checking to see if the current exception is intercepted bool CheckThreadExceptionStateForInterception(); -#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_X86) +#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) || defined(TARGET_X86) #define DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED -#endif // defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_ARM) || defined(HOST_X86) +#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) || defined(TARGET_X86) #ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED // Intercept the current exception and start an unwind. This function may never return. diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 78070bedee9cb7..01629c8e6c9b86 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -4569,13 +4569,13 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte #ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED if ((establisherFrame == ex.TargetFrameSp) && (ex.TargetIp != 0)) { -#ifdef HOST_AMD64 +#ifdef TARGET_AMD64 #define RETURN_REG Rax -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) #define RETURN_REG X0 -#elif defined(HOST_ARM) +#elif defined(TARGET_ARM) #define RETURN_REG R0 -#elif defined(HOST_X86) +#elif defined(TARGET_X86) #define RETURN_REG Eax #else #error Missing definition of RETURN_REG for the current architecture From 3566cfef53e1a1e4d2a0e2acc928b748c0686403 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Fri, 11 Aug 2023 14:38:47 -0700 Subject: [PATCH 5/9] creating positional clarity --- src/coreclr/vm/eetwain.cpp | 4 ++-- src/coreclr/vm/exceptionhandling.cpp | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index e037f575818dd2..bb06173bca5237 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -1005,7 +1005,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, LOG((LF_CORDB, LL_INFO100, "EECM::FixContextForEnC: Old and new fixed stack sizes are %u and %u\n", oldFixedStackSize, newFixedStackSize)); -#if defined(TARGET_AMD64) && defined(HOST_WINDOWS) +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) // win-x64: SP == FP before localloc if (oldStackBase != GetFP(&oldCtx)) { @@ -1246,7 +1246,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, _ASSERTE( frameHeaderSize <= oldInfo.stackSize ); _ASSERTE( GetSizeOfFrameHeaderForEnC( &oldInfo ) == frameHeaderSize ); -#elif defined(TARGET_AMD64) && defined(HOST_WINDOWS) +#elif defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI) // Next few statements zero out all registers that may end up holding new variables. diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 01629c8e6c9b86..59a2e1b60ce1ea 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -38,13 +38,15 @@ #define ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP #endif // TARGET_ARM || TARGET_ARM64 || TARGET_X86 || TARGET_LOONGARCH64 || TARGET_RISCV64 -#ifndef TARGET_UNIX +#ifdef TARGET_UNIX +VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); +#else void NOINLINE ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR ReturnValue, UINT_PTR TargetIP, UINT_PTR TargetFrameSp); -#endif // !TARGET_UNIX +#endif // TARGET_UNIX #ifdef USE_CURRENT_CONTEXT_IN_FILTER inline void CaptureNonvolatileRegisters(PKNONVOLATILE_CONTEXT pNonvolatileContext, PCONTEXT pContext) @@ -4192,9 +4194,6 @@ void ExceptionTracker::MakeCallbacksRelatedToHandler( // Notes: // If the exception is intercepted, this function never returns. // -#ifdef HOST_UNIX -VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); -#endif // HOST_UNIX EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_REGISTRATION_RECORD* pCurrentEstablisherFrame) EXCEPTION_RECORD* pExceptionRecord) @@ -4213,7 +4212,7 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE (PBYTE*)&uInterceptStackFrame, NULL, NULL); -#ifdef HOST_UNIX +#ifdef TARGET_UNIX CONTEXT *pContext = pThread->GetExceptionState()->GetContextRecord(); PAL_SEHException ex(pThread->GetExceptionState()->GetExceptionRecord(), pContext, /* onStack */ false); ex.TargetIp = INVALID_RESUME_ADDRESS; From 71b2cb5574f668bd20ae320dbd7f421ddbb609ec Mon Sep 17 00:00:00 2001 From: Mikelle Date: Fri, 11 Aug 2023 15:42:27 -0700 Subject: [PATCH 6/9] fixing build errors --- src/coreclr/vm/exceptionhandling.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 59a2e1b60ce1ea..d5aa466f7b09af 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -38,15 +38,17 @@ #define ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP #endif // TARGET_ARM || TARGET_ARM64 || TARGET_X86 || TARGET_LOONGARCH64 || TARGET_RISCV64 -#ifdef TARGET_UNIX -VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); -#else +#ifndef TARGET_UNIX void NOINLINE ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR ReturnValue, UINT_PTR TargetIP, UINT_PTR TargetFrameSp); -#endif // TARGET_UNIX +#endif // !TARGET_UNIX + +#ifdef HOST_UNIX +VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); +#endif // HOST_UNIX #ifdef USE_CURRENT_CONTEXT_IN_FILTER inline void CaptureNonvolatileRegisters(PKNONVOLATILE_CONTEXT pNonvolatileContext, PCONTEXT pContext) From 49ec2da5018406996d921ef84290e39dc080eef6 Mon Sep 17 00:00:00 2001 From: mikelle-rogers <45022607+mikelle-rogers@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:36:55 -0700 Subject: [PATCH 7/9] Update src/coreclr/vm/exceptionhandling.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/exceptionhandling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index d5aa466f7b09af..0c6450e20b4373 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -4221,7 +4221,7 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE ex.TargetFrameSp = uInterceptStackFrame; ex.ReturnValue = (UINT_PTR)pThread; UnwindManagedExceptionPass2(ex, pContext); -#else // HOST_UNIX +#else // TARGET_UNIX ClrUnwindEx(pExceptionRecord, (UINT_PTR)pThread, INVALID_RESUME_ADDRESS, uInterceptStackFrame); #endif // HOST_UNIX From 599432f5c45336da424c0bd5c12d74bc712a8760 Mon Sep 17 00:00:00 2001 From: mikelle-rogers <45022607+mikelle-rogers@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:37:08 -0700 Subject: [PATCH 8/9] Update src/coreclr/vm/exceptionhandling.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/exceptionhandling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 0c6450e20b4373..b36e0c2d78e6bc 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -4223,7 +4223,7 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE UnwindManagedExceptionPass2(ex, pContext); #else // TARGET_UNIX ClrUnwindEx(pExceptionRecord, (UINT_PTR)pThread, INVALID_RESUME_ADDRESS, uInterceptStackFrame); -#endif // HOST_UNIX +#endif // TARGET_UNIX UNREACHABLE(); } From eb8d5fc793ea02c9f36512a1b3073b525f999045 Mon Sep 17 00:00:00 2001 From: mikelle-rogers <45022607+mikelle-rogers@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:37:25 -0700 Subject: [PATCH 9/9] Update src/coreclr/vm/exceptionhandling.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/exceptionhandling.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index b36e0c2d78e6bc..0621ae03efe4f4 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -46,9 +46,9 @@ ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR TargetFrameSp); #endif // !TARGET_UNIX -#ifdef HOST_UNIX +#if defined(TARGET_UNIX) && !defined(DACCESS_COMPILE) VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); -#endif // HOST_UNIX +#endif // TARGET_UNIX && !DACCESS_COMPILE #ifdef USE_CURRENT_CONTEXT_IN_FILTER inline void CaptureNonvolatileRegisters(PKNONVOLATILE_CONTEXT pNonvolatileContext, PCONTEXT pContext)