Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/debug/daccess/dacdbiimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7223,7 +7223,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetAssemblyFromModule(VMPTR_Modul

HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::ParseContinuation(
CORDB_ADDRESS continuationAddress,
OUT PCODE* pDiagnosticIP,
OUT CORDB_ADDRESS* pDiagnosticIP,
OUT CORDB_ADDRESS* pNextContinuation,
OUT UINT32* pState)
{
Expand Down Expand Up @@ -7274,7 +7274,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::ParseContinuation(
return E_FAIL;
}

*pDiagnosticIP = pResumeInfo->pDiagnosticIP;
*pDiagnosticIP = static_cast<CORDB_ADDRESS>(pResumeInfo->pDiagnosticIP);
*pNextContinuation = static_cast<CORDB_ADDRESS>(dac_cast<TADDR>(OBJECTREFToObject(pNext)));
*pState = state;

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/daccess/dacdbiimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class DacDbiInterfaceImpl :
HRESULT STDMETHODCALLTYPE EnableGCNotificationEvents(BOOL fEnable);
HRESULT STDMETHODCALLTYPE GetAssemblyFromModule(VMPTR_Module vmModule, OUT VMPTR_Assembly *pvmAssembly);
HRESULT STDMETHODCALLTYPE ParseContinuation(CORDB_ADDRESS continuationAddress,
OUT PCODE *pDiagnosticIP,
OUT CORDB_ADDRESS *pDiagnosticIP,
OUT CORDB_ADDRESS *pNextContinuation,
OUT UINT32 *pState);
HRESULT STDMETHODCALLTYPE EnumerateAsyncLocals(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeAddr, UINT32 state, FP_ASYNC_LOCAL_CALLBACK fpCallback, CALLBACK_DATA pUserData);
Expand Down Expand Up @@ -716,7 +716,7 @@ class DacDbiInterfaceImpl :
ULONG32 GetStackParameterSize(EECodeInfo * pCodeInfo);

// Return the FramePointer of the current frame at which the stackwalker is stopped.
HRESULT STDMETHODCALLTYPE GetFramePointer(StackWalkHandle pSFIHandle, OUT FramePointer * pRetVal);
HRESULT STDMETHODCALLTYPE GetFramePointer(StackWalkHandle pSFIHandle, OUT CORDB_ADDRESS * pRetVal);

FramePointer GetFramePointerWorker(StackFrameIterator * pIter);

Expand Down
20 changes: 10 additions & 10 deletions src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thr
frameData.stubFrame.frameType = GetInternalFrameType(pFrame);
if (frameData.stubFrame.frameType != STUBFRAME_NONE)
{
frameData.fp = FramePointer::MakeFramePointer(PTR_HOST_TO_TADDR(pFrame));
frameData.fp = PTR_TO_CORDB_ADDRESS(PTR_HOST_TO_TADDR(pFrame));

frameData.vmCurrentAppDomainToken.SetHostPtr(pAppDomain);

Expand Down Expand Up @@ -638,7 +638,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetStackParameterSize(CORDB_ADDRE
}

// Return the FramePointer of the current frame at which the stackwalker is stopped.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetFramePointer(StackWalkHandle pSFIHandle, OUT FramePointer * pRetVal)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetFramePointer(StackWalkHandle pSFIHandle, OUT CORDB_ADDRESS * pRetVal)
{
DD_ENTER_MAY_THROW;

Expand All @@ -647,7 +647,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetFramePointer(StackWalkHandle p
{

StackFrameIterator * pIter = GetIteratorFromHandle(pSFIHandle);
*pRetVal = GetFramePointerWorker(pIter);
*pRetVal = PTR_TO_CORDB_ADDRESS(GetFramePointerWorker(pIter).GetSPValue());
}
EX_CATCH_HRESULT(hr);
return hr;
Expand Down Expand Up @@ -746,16 +746,16 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,
// do common initialization of Debugger_STRData for both managed stack frames and explicit frames
//

pFrameData->fp = GetFramePointerWorker(pIter);
pFrameData->fp = PTR_TO_CORDB_ADDRESS(GetFramePointerWorker(pIter).GetSPValue());

pFrameData->vmCurrentAppDomainToken.SetHostPtr(AppDomain::GetCurrentDomain());

if (ft == kNativeRuntimeUnwindableStackFrame)
{
pFrameData->eType = Debugger_STRData::cRuntimeNativeFrame;

_ASSERTE(pFrameData->ctx != NULL);
GetStackWalkCurrentContext(pIter, pFrameData->ctx);
_ASSERTE(pFrameData->ctx != 0);
GetStackWalkCurrentContext(pIter, (DT_CONTEXT *)CORDB_ADDRESS_TO_PTR(pFrameData->ctx));
}
else if (ft == kManagedStackFrame)
{
Expand Down Expand Up @@ -785,8 +785,8 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,

pFrameData->eType = Debugger_STRData::cMethodFrame;

_ASSERTE(pFrameData->ctx != NULL);
GetStackWalkCurrentContext(pIter, pFrameData->ctx);
_ASSERTE(pFrameData->ctx != 0);
GetStackWalkCurrentContext(pIter, (DT_CONTEXT *)CORDB_ADDRESS_TO_PTR(pFrameData->ctx));

//
// initialize the fields in Debugger_STRData::v
Expand Down Expand Up @@ -948,7 +948,7 @@ void DacDbiInterfaceImpl::InitParentFrameInfo(CrawlFrame * pCF,
// to the ExInfo when we are checking if a particular frame is the parent frame.
//

pJITFuncData->fpParentOrSelf = FramePointer::MakeFramePointer(sfParent.SP);
pJITFuncData->fpParentOrSelf = PTR_TO_CORDB_ADDRESS(sfParent.SP);
pJITFuncData->parentNativeOffset = dwParentOffset;
}
else
Expand All @@ -961,7 +961,7 @@ void DacDbiInterfaceImpl::InitParentFrameInfo(CrawlFrame * pCF,
// to the ExInfo when we are checking if a particular frame is the parent frame.
//

pJITFuncData->fpParentOrSelf = FramePointer::MakeFramePointer(sfSelf.SP);
pJITFuncData->fpParentOrSelf = PTR_TO_CORDB_ADDRESS(sfSelf.SP);
pJITFuncData->parentNativeOffset = 0;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/di/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2407,7 +2407,7 @@ COM_METHOD CordbProcess::GetAsyncStack(CORDB_ADDRESS continuationAddress, ICorDe
ThrowHR(E_INVALIDARG);
}

PCODE diagnosticIP;
CORDB_ADDRESS diagnosticIP;
CORDB_ADDRESS nextContinuation;
UINT32 state;
if (FAILED(m_pDacPrimitives->ParseContinuation(
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/debug/di/rsstackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ HRESULT CordbStackWalk::GetFrameWorker(ICorDebugFrame ** ppFrame)
// populated context through this pointer.
DT_CONTEXT frameCtx;
ZeroMemory(&frameCtx, sizeof(frameCtx));
frameData.ctx = &frameCtx;
frameData.ctx = PTR_TO_CORDB_ADDRESS(&frameCtx);

IDacDbiInterface::FrameType ft = IDacDbiInterface::kInvalid;

Expand Down Expand Up @@ -686,7 +686,7 @@ HRESULT CordbStackWalk::GetFrameWorker(ICorDebugFrame ** ppFrame)

// Create the native frame.
CordbNativeFrame* pNativeFrame = new CordbNativeFrame(m_pCordbThread,
frameData.fp,
FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(frameData.fp)),
pNativeCode,
(SIZE_T)pJITFuncData->nativeOffset,
(TADDR)frameData.v.taAmbientESP,
Expand Down Expand Up @@ -829,7 +829,7 @@ HRESULT CordbStackWalk::GetFrameWorker(ICorDebugFrame ** ppFrame)
_ASSERTE(pCurrentAppDomain != NULL);

CordbRuntimeUnwindableFrame * pRuntimeFrame = new CordbRuntimeUnwindableFrame(m_pCordbThread,
frameData.fp,
FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(frameData.fp)),
pCurrentAppDomain,
&frameCtx);

Expand Down Expand Up @@ -896,7 +896,7 @@ HRESULT CordbAsyncStackWalk::PopulateFrame()

while (true)
{
PCODE diagnosticIP;
CORDB_ADDRESS diagnosticIP = 0;
CORDB_ADDRESS nextContinuation;
UINT32 state;

Expand Down Expand Up @@ -993,7 +993,7 @@ HRESULT CordbAsyncStackWalk::Next()
if (m_continuationAddress == 0)
ThrowHR(CORDBG_E_PAST_END_OF_STACK);

PCODE diagnosticIP;
CORDB_ADDRESS diagnosticIP = 0;
CORDB_ADDRESS nextContinuation;
UINT32 state;
IfFailThrow(m_pProcess->GetDAC()->ParseContinuation(
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/di/rsthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2286,7 +2286,7 @@ void CordbThread::GetActiveInternalFramesCallback(const Debugger_STRData * pFram

// Create a CordbInternalFrame.
CordbInternalFrame * pInternalFrame = new CordbInternalFrame(pThis,
pFrameData->fp,
FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(pFrameData->fp)),
pAppDomain,
pFrameData);

Expand Down Expand Up @@ -5433,7 +5433,7 @@ CordbMiscFrame::CordbMiscFrame()
CordbMiscFrame::CordbMiscFrame(Debugger_JITFuncData * pJITFuncData)
{
this->parentIP = (SIZE_T)pJITFuncData->parentNativeOffset;
this->fpParentOrSelf = pJITFuncData->fpParentOrSelf;
this->fpParentOrSelf = FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(pJITFuncData->fpParentOrSelf));
this->fIsFilterFunclet = (pJITFuncData->fIsFilterFrame == TRUE);
}

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/inc/dacdbiinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ IDacDbiInterface : public IUnknown
// The FramePointer of an explicit frame is just the stack address of the explicit frame.
//

virtual HRESULT STDMETHODCALLTYPE GetFramePointer(StackWalkHandle pSFIHandle, OUT FramePointer * pRetVal) = 0;
virtual HRESULT STDMETHODCALLTYPE GetFramePointer(StackWalkHandle pSFIHandle, OUT CORDB_ADDRESS * pRetVal) = 0;

Comment on lines 1234 to 1238
//
// Check whether the specified CONTEXT is the CONTEXT of the leaf frame. This function doesn't care
Expand Down Expand Up @@ -2195,7 +2195,7 @@ IDacDbiInterface : public IUnknown

virtual HRESULT STDMETHODCALLTYPE ParseContinuation(
CORDB_ADDRESS continuationAddress,
OUT PCODE* pDiagnosticIP,
OUT CORDB_ADDRESS* pDiagnosticIP,
OUT CORDB_ADDRESS* pNextContinuation,
OUT UINT32* pState) = 0;

Expand Down
17 changes: 14 additions & 3 deletions src/coreclr/debug/inc/dacdbistructures.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,11 @@ struct MSLAYOUT Debugger_JITFuncData

BOOL fIsFilterFrame;
ULONG64 parentNativeOffset;
FramePointer fpParentOrSelf;
// Normalized to a fixed 64-bit width (CORDB_ADDRESS) rather than a host-sized
// FramePointer so this IPC struct has an identical layout on all bitnesses,
// allowing a 64-bit DBI to consume a 32-bit target. The RS converts to/from
// FramePointer at the boundary.
CORDB_ADDRESS fpParentOrSelf;

// indicates if the MethodDesc is a generic function or a method inside a generic class (or
// both!).
Expand All @@ -538,8 +542,15 @@ struct MSLAYOUT Debugger_JITFuncData
#endif // ARM context structures have a 16-byte alignment requirement
struct MSLAYOUT Debugger_STRData
{
FramePointer fp;
DT_CONTEXT * ctx;
// fp and ctx are normalized to a fixed 64-bit width (CORDB_ADDRESS) rather than
// host-sized types (FramePointer / DT_CONTEXT*) so this IPC struct has an identical
// layout regardless of host or target bitness, allowing a 64-bit DBI to consume a
// 32-bit target. The RS converts to/from the host representation at the boundary:
// - fp carries a (target) stack/frame pointer value.
// - ctx carries the (host) address of a dbi-allocated DT_CONTEXT buffer that the
// DAC writes the populated context through.
CORDB_ADDRESS fp;
CORDB_ADDRESS ctx;
VMPTR_AppDomain vmCurrentAppDomainToken;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,14 @@ private bool Next(StackWalkData handle)
case StackWalkState.InitialNativeContext:
case StackWalkState.NativeMarker:
{
// Native UnwindStackWalkFrame captures cbStackParameterSize as a fresh
// per-step local that defaults to 0, and only sets it when the frame being
// left is a frameless managed method (SFITER_FRAMELESS_METHOD). The x86
// callee-popped-args ESP adjustment is therefore applied only at an immediate
// managed-frameless -> native-marker (M2U) transition. Leaving a native frame
// must reset the size to 0 so consecutive native-marker frames don't reuse a
// stale parameter size from an earlier managed frame.
handle.LastFramelessStackParameterSize = 0;
TargetCodePointer ip = handle.Context.InstructionPointer;
Comment on lines +862 to 866
HijackKind hijackKind = _target.Contracts.Debugger.GetHijackKind(ip);
if (hijackKind != HijackKind.None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public struct Debugger_JITFuncData
public ulong vmNativeCodeMethodDescToken;
public Interop.BOOL fIsFilterFrame;
public ulong parentNativeOffset;
public ulong fpParentOrSelf;
public ulong fpParentOrSelf; // FramePointer, normalized to a fixed 64-bit width (CORDB_ADDRESS)
public Interop.BOOL isInstantiatedGeneric;
public Interop.BOOL justAfterILThrow;
}
Expand Down Expand Up @@ -226,12 +226,18 @@ public struct DebuggerIPCE_STRData_StubFrame

// Holds data for each stack frame or chain. This data is passed from the RC to
// the DI during a stack walk. Mirrors the native Debugger_STRData struct
// defined in src/coreclr/debug/inc/dbgipcevents.h.
// defined in src/coreclr/debug/inc/dacdbistructures.h.
//
// `ctx` is a pointer into dbi-allocated memory.
// The DAC writes the populated context through this pointer rather
// than storing it inline. Code paths that do not produce a context
// (e.g. EnumerateInternalFrames for cStubFrame entries) leave it as 0.
// `fp` (a stack/frame pointer) and `ctx` (the address of a dbi-allocated
// DT_CONTEXT buffer) are normalized on the native side to a fixed 64-bit width
// (CORDB_ADDRESS), rather than host-sized FramePointer / DT_CONTEXT*, so this IPC
// struct has an identical layout regardless of host or target bitness. That lets
// a 64-bit DBI consume a 32-bit target. They are therefore modeled as ulong here,
// matching the VMPTR/CORDB_ADDRESS fields which are always 8 bytes.
//
// `ctx` addresses dbi-allocated memory: the DAC writes the populated context
// through it rather than storing it inline. Code paths that do not produce a
// context (e.g. EnumerateInternalFrames for cStubFrame entries) leave it as 0.
[StructLayout(LayoutKind.Explicit)]
public struct Debugger_STRData
{
Expand All @@ -242,10 +248,11 @@ public enum EType
cRuntimeNativeFrame = 2,
}

[FieldOffset(0)] public ulong fp; // FramePointer
[FieldOffset(8)] public ulong ctx; // DT_CONTEXT*
[FieldOffset(0)] public ulong fp; // FramePointer (normalized to CORDB_ADDRESS)
[FieldOffset(8)] public ulong ctx; // DT_CONTEXT* address (normalized to CORDB_ADDRESS)
[FieldOffset(16)] public ulong vmCurrentAppDomainToken; // VMPTR_AppDomain
[FieldOffset(24)] public EType eType;
// The v (method frame) and stubFrame variants overlap, mirroring the native anonymous union.
[FieldOffset(32)] public DebuggerIPCE_STRData_MethodFrame v;
[FieldOffset(32)] public DebuggerIPCE_STRData_StubFrame stubFrame;
}
Expand Down
Loading