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/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp index 6609dc48f9a957..ecf34810e25879 100644 --- a/src/coreclr/vm/arm/stubs.cpp +++ b/src/coreclr/vm/arm/stubs.cpp @@ -1287,14 +1287,23 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u // Update the integer registers in KNONVOLATILE_CONTEXT_POINTERS from // the exception context we have. - pRD->pCurrentContextPointers->R4 = (PDWORD)&m_ctx.R4; - pRD->pCurrentContextPointers->R5 = (PDWORD)&m_ctx.R5; - pRD->pCurrentContextPointers->R6 = (PDWORD)&m_ctx.R6; - pRD->pCurrentContextPointers->R7 = (PDWORD)&m_ctx.R7; - pRD->pCurrentContextPointers->R8 = (PDWORD)&m_ctx.R8; - pRD->pCurrentContextPointers->R9 = (PDWORD)&m_ctx.R9; - pRD->pCurrentContextPointers->R10 = (PDWORD)&m_ctx.R10; - pRD->pCurrentContextPointers->R11 = (PDWORD)&m_ctx.R11; +#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). + T_CONTEXT *pContext = pRD->pCurrentContext; +#else + T_CONTEXT *pContext = &m_ctx; +#endif + + pRD->pCurrentContextPointers->R4 = (PDWORD)&pContext->R4; + pRD->pCurrentContextPointers->R5 = (PDWORD)&pContext->R5; + pRD->pCurrentContextPointers->R6 = (PDWORD)&pContext->R6; + pRD->pCurrentContextPointers->R7 = (PDWORD)&pContext->R7; + pRD->pCurrentContextPointers->R8 = (PDWORD)&pContext->R8; + pRD->pCurrentContextPointers->R9 = (PDWORD)&pContext->R9; + pRD->pCurrentContextPointers->R10 = (PDWORD)&pContext->R10; + pRD->pCurrentContextPointers->R11 = (PDWORD)&pContext->R11; pRD->pCurrentContextPointers->Lr = NULL; pRD->IsCallerContextValid = FALSE; diff --git a/src/coreclr/vm/arm64/stubs.cpp b/src/coreclr/vm/arm64/stubs.cpp index ec6377012cef5a..527528c1bda154 100644 --- a/src/coreclr/vm/arm64/stubs.cpp +++ b/src/coreclr/vm/arm64/stubs.cpp @@ -294,18 +294,27 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u // Update the integer registers in KNONVOLATILE_CONTEXT_POINTERS from // the exception context we have. - pRD->pCurrentContextPointers->X19 = (PDWORD64)&m_ctx.X19; - pRD->pCurrentContextPointers->X20 = (PDWORD64)&m_ctx.X20; - pRD->pCurrentContextPointers->X21 = (PDWORD64)&m_ctx.X21; - pRD->pCurrentContextPointers->X22 = (PDWORD64)&m_ctx.X22; - pRD->pCurrentContextPointers->X23 = (PDWORD64)&m_ctx.X23; - pRD->pCurrentContextPointers->X24 = (PDWORD64)&m_ctx.X24; - pRD->pCurrentContextPointers->X25 = (PDWORD64)&m_ctx.X25; - pRD->pCurrentContextPointers->X26 = (PDWORD64)&m_ctx.X26; - pRD->pCurrentContextPointers->X27 = (PDWORD64)&m_ctx.X27; - pRD->pCurrentContextPointers->X28 = (PDWORD64)&m_ctx.X28; - pRD->pCurrentContextPointers->Fp = (PDWORD64)&m_ctx.Fp; - pRD->pCurrentContextPointers->Lr = (PDWORD64)&m_ctx.Lr; +#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). + T_CONTEXT *pContext = pRD->pCurrentContext; +#else + T_CONTEXT *pContext = &m_ctx; +#endif + + pRD->pCurrentContextPointers->X19 = (PDWORD64)&pContext->X19; + pRD->pCurrentContextPointers->X20 = (PDWORD64)&pContext->X20; + pRD->pCurrentContextPointers->X21 = (PDWORD64)&pContext->X21; + pRD->pCurrentContextPointers->X22 = (PDWORD64)&pContext->X22; + pRD->pCurrentContextPointers->X23 = (PDWORD64)&pContext->X23; + pRD->pCurrentContextPointers->X24 = (PDWORD64)&pContext->X24; + pRD->pCurrentContextPointers->X25 = (PDWORD64)&pContext->X25; + pRD->pCurrentContextPointers->X26 = (PDWORD64)&pContext->X26; + pRD->pCurrentContextPointers->X27 = (PDWORD64)&pContext->X27; + pRD->pCurrentContextPointers->X28 = (PDWORD64)&pContext->X28; + pRD->pCurrentContextPointers->Fp = (PDWORD64)&pContext->Fp; + pRD->pCurrentContextPointers->Lr = (PDWORD64)&pContext->Lr; ClearRegDisplayArgumentAndScratchRegisters(pRD); 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; diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index 54ff2e2cbdb85e..87333faed1f167 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -220,11 +220,20 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u pRD->SP = m_ctx.Esp; pRD->ControlPC = m_ctx.Eip; -#define ARGUMENT_AND_SCRATCH_REGISTER(regname) pRD->pCurrentContextPointers->regname = &m_ctx.regname; +#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 + +#define ARGUMENT_AND_SCRATCH_REGISTER(regname) pRD->pCurrentContextPointers->regname = &pContext->regname; ENUM_ARGUMENT_AND_SCRATCH_REGISTERS(); #undef ARGUMENT_AND_SCRATCH_REGISTER -#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = &m_ctx.regname; +#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = &pContext->regname; ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER diff --git a/src/coreclr/vm/loongarch64/stubs.cpp b/src/coreclr/vm/loongarch64/stubs.cpp index 124c0d9739aa2a..b5b8d9ef154d80 100644 --- a/src/coreclr/vm/loongarch64/stubs.cpp +++ b/src/coreclr/vm/loongarch64/stubs.cpp @@ -306,17 +306,26 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u // Update the integer registers in KNONVOLATILE_CONTEXT_POINTERS from // the exception context we have. - pRD->pCurrentContextPointers->S0 = (PDWORD64)&m_ctx.S0; - pRD->pCurrentContextPointers->S1 = (PDWORD64)&m_ctx.S1; - pRD->pCurrentContextPointers->S2 = (PDWORD64)&m_ctx.S2; - pRD->pCurrentContextPointers->S3 = (PDWORD64)&m_ctx.S3; - pRD->pCurrentContextPointers->S4 = (PDWORD64)&m_ctx.S4; - pRD->pCurrentContextPointers->S5 = (PDWORD64)&m_ctx.S5; - pRD->pCurrentContextPointers->S6 = (PDWORD64)&m_ctx.S6; - pRD->pCurrentContextPointers->S7 = (PDWORD64)&m_ctx.S7; - pRD->pCurrentContextPointers->S8 = (PDWORD64)&m_ctx.S8; - pRD->pCurrentContextPointers->Fp = (PDWORD64)&m_ctx.Fp; - pRD->pCurrentContextPointers->Ra = (PDWORD64)&m_ctx.Ra; +#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). + T_CONTEXT *pContext = pRD->pCurrentContext; +#else + T_CONTEXT *pContext = &m_ctx; +#endif + + pRD->pCurrentContextPointers->S0 = (PDWORD64)&pContext->S0; + pRD->pCurrentContextPointers->S1 = (PDWORD64)&pContext->S1; + pRD->pCurrentContextPointers->S2 = (PDWORD64)&pContext->S2; + pRD->pCurrentContextPointers->S3 = (PDWORD64)&pContext->S3; + pRD->pCurrentContextPointers->S4 = (PDWORD64)&pContext->S4; + pRD->pCurrentContextPointers->S5 = (PDWORD64)&pContext->S5; + pRD->pCurrentContextPointers->S6 = (PDWORD64)&pContext->S6; + pRD->pCurrentContextPointers->S7 = (PDWORD64)&pContext->S7; + pRD->pCurrentContextPointers->S8 = (PDWORD64)&pContext->S8; + pRD->pCurrentContextPointers->Fp = (PDWORD64)&pContext->Fp; + pRD->pCurrentContextPointers->Ra = (PDWORD64)&pContext->Ra; ClearRegDisplayArgumentAndScratchRegisters(pRD); diff --git a/src/coreclr/vm/riscv64/stubs.cpp b/src/coreclr/vm/riscv64/stubs.cpp index 0ef69ee0f10355..2fe9f65da6eb51 100644 --- a/src/coreclr/vm/riscv64/stubs.cpp +++ b/src/coreclr/vm/riscv64/stubs.cpp @@ -260,21 +260,30 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u // Update the integer registers in KNONVOLATILE_CONTEXT_POINTERS from // the exception context we have. - pRD->pCurrentContextPointers->S1 = (PDWORD64)&m_ctx.S1; - pRD->pCurrentContextPointers->S2 = (PDWORD64)&m_ctx.S2; - pRD->pCurrentContextPointers->S3 = (PDWORD64)&m_ctx.S3; - pRD->pCurrentContextPointers->S4 = (PDWORD64)&m_ctx.S4; - pRD->pCurrentContextPointers->S5 = (PDWORD64)&m_ctx.S5; - pRD->pCurrentContextPointers->S6 = (PDWORD64)&m_ctx.S6; - pRD->pCurrentContextPointers->S7 = (PDWORD64)&m_ctx.S7; - pRD->pCurrentContextPointers->S8 = (PDWORD64)&m_ctx.S8; - pRD->pCurrentContextPointers->S9 = (PDWORD64)&m_ctx.S9; - pRD->pCurrentContextPointers->S10 = (PDWORD64)&m_ctx.S10; - pRD->pCurrentContextPointers->S11 = (PDWORD64)&m_ctx.S11; - pRD->pCurrentContextPointers->Fp = (PDWORD64)&m_ctx.Fp; - pRD->pCurrentContextPointers->Gp = (PDWORD64)&m_ctx.Gp; - pRD->pCurrentContextPointers->Tp = (PDWORD64)&m_ctx.Tp; - pRD->pCurrentContextPointers->Ra = (PDWORD64)&m_ctx.Ra; +#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). + T_CONTEXT *pContext = pRD->pCurrentContext; +#else + T_CONTEXT *pContext = &m_ctx; +#endif + + pRD->pCurrentContextPointers->S1 = (PDWORD64)&pContext->S1; + pRD->pCurrentContextPointers->S2 = (PDWORD64)&pContext->S2; + pRD->pCurrentContextPointers->S3 = (PDWORD64)&pContext->S3; + pRD->pCurrentContextPointers->S4 = (PDWORD64)&pContext->S4; + pRD->pCurrentContextPointers->S5 = (PDWORD64)&pContext->S5; + pRD->pCurrentContextPointers->S6 = (PDWORD64)&pContext->S6; + pRD->pCurrentContextPointers->S7 = (PDWORD64)&pContext->S7; + pRD->pCurrentContextPointers->S8 = (PDWORD64)&pContext->S8; + pRD->pCurrentContextPointers->S9 = (PDWORD64)&pContext->S9; + pRD->pCurrentContextPointers->S10 = (PDWORD64)&pContext->S10; + pRD->pCurrentContextPointers->S11 = (PDWORD64)&pContext->S11; + pRD->pCurrentContextPointers->Fp = (PDWORD64)&pContext->Fp; + pRD->pCurrentContextPointers->Gp = (PDWORD64)&pContext->Gp; + pRD->pCurrentContextPointers->Tp = (PDWORD64)&pContext->Tp; + pRD->pCurrentContextPointers->Ra = (PDWORD64)&pContext->Ra; ClearRegDisplayArgumentAndScratchRegisters(pRD);