diff --git a/src/coreclr/vm/amd64/cgenamd64.cpp b/src/coreclr/vm/amd64/cgenamd64.cpp index 977c97ed77b808..3bc32bd5cb04cb 100644 --- a/src/coreclr/vm/amd64/cgenamd64.cpp +++ b/src/coreclr/vm/amd64/cgenamd64.cpp @@ -218,21 +218,30 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u pRD->SSP = m_SSP; #endif - pRD->pCurrentContextPointers->Rax = &m_ctx.Rax; - pRD->pCurrentContextPointers->Rcx = &m_ctx.Rcx; - pRD->pCurrentContextPointers->Rdx = &m_ctx.Rdx; - pRD->pCurrentContextPointers->Rbx = &m_ctx.Rbx; - pRD->pCurrentContextPointers->Rbp = &m_ctx.Rbp; - pRD->pCurrentContextPointers->Rsi = &m_ctx.Rsi; - pRD->pCurrentContextPointers->Rdi = &m_ctx.Rdi; - pRD->pCurrentContextPointers->R8 = &m_ctx.R8; - pRD->pCurrentContextPointers->R9 = &m_ctx.R9; - pRD->pCurrentContextPointers->R10 = &m_ctx.R10; - pRD->pCurrentContextPointers->R11 = &m_ctx.R11; - pRD->pCurrentContextPointers->R12 = &m_ctx.R12; - pRD->pCurrentContextPointers->R13 = &m_ctx.R13; - pRD->pCurrentContextPointers->R14 = &m_ctx.R14; - pRD->pCurrentContextPointers->R15 = &m_ctx.R15; +#ifdef DACCESS_COMPILE + // &m_ctx.Xxx resolves through the DAC cache and the entry can be evicted + // before context pointers are consumed. Point at the local copy in + // pCurrentContext instead (values were already copied above). + CONTEXT *pContext = pRD->pCurrentContext; +#else + CONTEXT *pContext = &m_ctx; +#endif + + pRD->pCurrentContextPointers->Rax = &pContext->Rax; + pRD->pCurrentContextPointers->Rcx = &pContext->Rcx; + pRD->pCurrentContextPointers->Rdx = &pContext->Rdx; + pRD->pCurrentContextPointers->Rbx = &pContext->Rbx; + pRD->pCurrentContextPointers->Rbp = &pContext->Rbp; + pRD->pCurrentContextPointers->Rsi = &pContext->Rsi; + pRD->pCurrentContextPointers->Rdi = &pContext->Rdi; + pRD->pCurrentContextPointers->R8 = &pContext->R8; + pRD->pCurrentContextPointers->R9 = &pContext->R9; + pRD->pCurrentContextPointers->R10 = &pContext->R10; + pRD->pCurrentContextPointers->R11 = &pContext->R11; + pRD->pCurrentContextPointers->R12 = &pContext->R12; + pRD->pCurrentContextPointers->R13 = &pContext->R13; + pRD->pCurrentContextPointers->R14 = &pContext->R14; + pRD->pCurrentContextPointers->R15 = &pContext->R15; pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 078536db9e10e6..9a22d3abb4af1a 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -10742,9 +10742,9 @@ void SoftwareExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER -#if defined(DACCESS_COMPILE) && defined(TARGET_X86) -// X86 unwinding always works in terms of context pointers, so they need to be in the correct address space when debugging -// This may work for other architectures as well, but that isn't tested. +#if defined(DACCESS_COMPILE) +// Context pointers in m_ContextPointers reference the target process address space and cannot be used directly. +// Point them at the local context copy instead. #define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = &pRD->pCurrentContext->regname; #else #define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = m_ContextPointers.regname;