Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f60b349
remove dt context
rcj1 Jul 8, 2026
764ab1e
merge
rcj1 Jul 8, 2026
b259616
add untracked files
rcj1 Jul 8, 2026
4b72f50
fix build
rcj1 Jul 8, 2026
b1cfa55
fix build
rcj1 Jul 8, 2026
b85b41a
code review
rcj1 Jul 8, 2026
057d5fa
fix build
rcj1 Jul 8, 2026
d7bdaf4
merge
rcj1 Jul 8, 2026
2974b57
fix crossdac
rcj1 Jul 8, 2026
aee5d91
sig
rcj1 Jul 14, 2026
9534815
fix build
rcj1 Jul 14, 2026
3e3816b
Merge
rcj1 Jul 16, 2026
9aea595
code review
rcj1 Jul 17, 2026
f838fb3
merge
rcj1 Jul 17, 2026
6a5e27c
ccr
rcj1 Jul 17, 2026
a4d9bb8
code review
rcj1 Jul 17, 2026
9ba5f91
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rcj1 Jul 18, 2026
f75cbfb
Add GetTargetInfo DacDbi API
rcj1 Jul 8, 2026
c4e0eba
codE review
rcj1 Jul 21, 2026
fd0b7b2
Merge branch 'main' into sw-stuff-2
rcj1 Jul 22, 2026
171a628
fix merge
rcj1 Jul 22, 2026
c117f11
fix loong and riscv
rcj1 Jul 22, 2026
f445952
Update src/coreclr/debug/inc/dacdbistructures.h
rcj1 Jul 22, 2026
24b52fd
only copy part of context that is required by the context flags
rcj1 Jul 22, 2026
ee43cdc
Potential fix for pull request finding
rcj1 Jul 22, 2026
18e4aba
Update IDacDbiInterface.cs
rcj1 Jul 23, 2026
0c59041
Update dacdbiinterface.h
rcj1 Jul 23, 2026
6334ea1
Update dacdbi.idl
rcj1 Jul 23, 2026
e287b49
Update src/coreclr/debug/inc/dacdbistructures.h
rcj1 Jul 23, 2026
45920f1
E
rcj1 Jul 23, 2026
945bb4b
Potential fix for pull request finding
rcj1 Jul 24, 2026
1a090da
Merge branch 'main' into sw-stuff-2
rcj1 Jul 24, 2026
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
731 changes: 722 additions & 9 deletions src/coreclr/debug/daccess/dacdbiimpl.cpp

Large diffs are not rendered by default.

37 changes: 29 additions & 8 deletions src/coreclr/debug/daccess/dacdbiimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,28 @@ class DacDbiInterfaceImpl :
HRESULT STDMETHODCALLTYPE EnumerateAsyncLocals(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeAddr, UINT32 state, FP_ASYNC_LOCAL_CALLBACK fpCallback, CALLBACK_DATA pUserData);
HRESULT STDMETHODCALLTYPE GetGenericArgTokenIndex(VMPTR_MethodDesc vmMethod, OUT UINT32* pIndex);

HRESULT STDMETHODCALLTYPE GetTargetContextSize(ULONG32 contextFlags, OUT ULONG32 * pSize);

HRESULT STDMETHODCALLTYPE WriteRegistersToContext(IN ContextBuffer contextBuffer, IN const CorDebugRegister * regs, IN ULONG32 nRegs, IN const TADDR * values);
HRESULT STDMETHODCALLTYPE ReadRegistersFromContext(IN ContextBuffer contextBuffer, IN const CorDebugRegister * regs, IN ULONG32 nRegs, OUT CORDB_REGISTER * pValues);
HRESULT STDMETHODCALLTYPE GetAvailableRegistersMask(IN BOOL fActive, IN BOOL fQuickUnwind, IN ULONG32 regCount, OUT BYTE pAvailable[]);
HRESULT STDMETHODCALLTYPE ConvertJitRegNumToCorDebugRegister(IN ULONG32 jitRegNum, OUT CorDebugRegister * pReg);
HRESULT STDMETHODCALLTYPE WriteFloatRegisterToContext(
IN ContextBuffer contextBuffer,
IN CorDebugRegister reg,
IN const BYTE * pValue,
IN ULONG32 valueSize);

HRESULT STDMETHODCALLTYPE ContextHasExtendedRegisters(IN ContextBuffer contextBuffer, OUT BOOL * pResult);

HRESULT STDMETHODCALLTYPE CompareControlRegisters(IN ContextBuffer contextBuffer1, IN ContextBuffer contextBuffer2, OUT BOOL * pResult);

HRESULT STDMETHODCALLTYPE CopyContext(
IN ContextBuffer destinationContext,
IN ContextBuffer sourceContext,
IN ContextCopyMode copyMode,
IN ULONG32 flags);

private:
void TypeHandleToExpandedTypeInfoImpl(AreValueTypesBoxed boxed,
TypeHandle typeHandle,
Expand Down Expand Up @@ -667,27 +689,26 @@ class DacDbiInterfaceImpl :
HRESULT STDMETHODCALLTYPE Hijack(VMPTR_Thread vmThread, ULONG32 dwThreadId, const EXCEPTION_RECORD * pRecord, T_CONTEXT * pOriginalContext, ULONG32 cbSizeContext, EHijackReason::EHijackReason reason, void * pUserData, CORDB_ADDRESS * pRemoteContextAddr);

// Return the filter CONTEXT on the LS.
HRESULT STDMETHODCALLTYPE GetManagedStoppedContext(VMPTR_Thread vmThread, OUT VMPTR_CONTEXT * pRetVal);
HRESULT STDMETHODCALLTYPE GetManagedStoppedContext(VMPTR_Thread vmThread, OUT CORDB_ADDRESS * pRetVal);

// Create and return a stackwalker on the specified thread.
HRESULT STDMETHODCALLTYPE CreateStackWalk(VMPTR_Thread vmThread, DT_CONTEXT * pInternalContextBuffer, OUT StackWalkHandle * ppSFIHandle);
HRESULT STDMETHODCALLTYPE CreateStackWalk(VMPTR_Thread vmThread, ContextBuffer contextBuffer, OUT StackWalkHandle * ppSFIHandle);

// Delete the stackwalk object
HRESULT STDMETHODCALLTYPE DeleteStackWalk(StackWalkHandle ppSFIHandle);

// Get the CONTEXT of the current frame at which the stackwalker is stopped.
HRESULT STDMETHODCALLTYPE GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, DT_CONTEXT * pContext);
HRESULT STDMETHODCALLTYPE GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, ContextBuffer contextBuffer);

void GetStackWalkCurrentContext(StackFrameIterator * pIter, DT_CONTEXT * pContext);

// Set the stackwalker to the specified CONTEXT.
HRESULT STDMETHODCALLTYPE SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, DT_CONTEXT * pContext);
HRESULT STDMETHODCALLTYPE SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, ContextBuffer contextBuffer);

// Unwind the stackwalker to the next frame.
HRESULT STDMETHODCALLTYPE UnwindStackWalkFrame(StackWalkHandle pSFIHandle, OUT BOOL * pResult);

HRESULT STDMETHODCALLTYPE CheckContext(VMPTR_Thread vmThread,
const DT_CONTEXT * pContext);
HRESULT STDMETHODCALLTYPE CheckContext(VMPTR_Thread vmThread, ContextBuffer contextBuffer);

// Retrieve information about the current frame from the stackwalker.
HRESULT STDMETHODCALLTYPE GetStackWalkCurrentFrameInfo(StackWalkHandle pSFIHandle, OPTIONAL Debugger_STRData * pFrameData, OUT FrameType * pRetVal);
Expand All @@ -708,10 +729,10 @@ class DacDbiInterfaceImpl :

// Return TRUE if the specified CONTEXT is the CONTEXT of the leaf frame.
// @dbgtodo filter CONTEXT - Currently we check for the filter CONTEXT first.
HRESULT STDMETHODCALLTYPE IsLeafFrame(VMPTR_Thread vmThread, const DT_CONTEXT * pContext, OUT BOOL * pResult);
HRESULT STDMETHODCALLTYPE IsLeafFrame(VMPTR_Thread vmThread, ContextBuffer contextBuffer, OUT BOOL * pResult);

// DacDbi API: Get the context for a particular thread of the target process
HRESULT STDMETHODCALLTYPE GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContextBuffer);
HRESULT STDMETHODCALLTYPE GetContext(VMPTR_Thread vmThread, ContextBuffer contextBuffer);

// Check if the given method is a DiagnosticHidden or an LCG method.
HRESULT STDMETHODCALLTYPE IsDiagnosticsHiddenOrLCGMethod(VMPTR_MethodDesc vmMethodDesc, OUT DynamicMethodType * pRetVal);
Expand Down
74 changes: 57 additions & 17 deletions src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,20 @@ T_CONTEXT * GetContextBufferFromHandle(StackWalkHandle pSFIHandle)


// Create and return a stackwalker on the specified thread.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::CreateStackWalk(VMPTR_Thread vmThread, DT_CONTEXT * pInternalContextBuffer, OUT StackWalkHandle * ppSFIHandle)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::CreateStackWalk(VMPTR_Thread vmThread, ContextBuffer contextBuffer, OUT StackWalkHandle * ppSFIHandle)
{
DD_ENTER_MAY_THROW;

if (ppSFIHandle == NULL)
{
return E_INVALIDARG;
}
*ppSFIHandle = NULL;
if ((contextBuffer.pContextBytes == NULL) || (contextBuffer.contextSize < sizeof(DT_CONTEXT)))
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
EX_TRY
{
Expand All @@ -131,13 +141,13 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::CreateStackWalk(VMPTR_Thread vmTh

// initialize the CONTEXT.
// SetStackWalk will initial the RegDisplay from this context.
IfFailThrow(GetContext(vmThread, pInternalContextBuffer));
IfFailThrow(GetContext(vmThread, contextBuffer));

// initialize the stackwalker
IfFailThrow(SetStackWalkCurrentContext(vmThread,
*ppSFIHandle,
SET_CONTEXT_FLAG_ACTIVE_FRAME,
pInternalContextBuffer));
contextBuffer));
}
EX_CATCH_HRESULT(hr);
return hr;
Expand All @@ -156,17 +166,22 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::DeleteStackWalk(StackWalkHandle p
}

// Get the CONTEXT of the current frame at which the stackwalker is stopped.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, DT_CONTEXT * pContext)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetStackWalkCurrentContext(StackWalkHandle pSFIHandle, ContextBuffer contextBuffer)
{
DD_ENTER_MAY_THROW;

if ((contextBuffer.pContextBytes == NULL) || (contextBuffer.contextSize < sizeof(DT_CONTEXT)))
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
EX_TRY
{

StackFrameIterator * pIter = GetIteratorFromHandle(pSFIHandle);

GetStackWalkCurrentContext(pIter, pContext);
GetStackWalkCurrentContext(pIter, reinterpret_cast<DT_CONTEXT *>(contextBuffer.pContextBytes));
}
EX_CATCH_HRESULT(hr);
return hr;
Expand All @@ -189,20 +204,27 @@ void DacDbiInterfaceImpl::GetStackWalkCurrentContext(StackFrameIterator * pIter,


// Set the stackwalker to the specified CONTEXT.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, DT_CONTEXT * pContext)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::SetStackWalkCurrentContext(VMPTR_Thread vmThread, StackWalkHandle pSFIHandle, CorDebugSetContextFlag flag, ContextBuffer contextBuffer)
{
DD_ENTER_MAY_THROW;

if ((contextBuffer.pContextBytes == NULL) || (contextBuffer.contextSize < sizeof(DT_CONTEXT)))
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
EX_TRY
{

DT_CONTEXT * pContext = reinterpret_cast<DT_CONTEXT *>(contextBuffer.pContextBytes);

StackFrameIterator * pIter = GetIteratorFromHandle(pSFIHandle);
REGDISPLAY * pRD = GetRegDisplayFromHandle(pSFIHandle);

#if defined(_DEBUG)
// The caller should have checked this already.
_ASSERTE(CheckContext(vmThread, pContext) == S_OK);
_ASSERTE(CheckContext(vmThread, contextBuffer) == S_OK);
#endif // _DEBUG

// DD can't keep pointers back into the RS address space.
Expand Down Expand Up @@ -341,11 +363,17 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::UnwindStackWalkFrame(StackWalkHan

// Check whether the specified CONTEXT is valid. The only check we perform right now is whether the
// SP in the specified CONTEXT is in the stack range of the thread.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::CheckContext(VMPTR_Thread vmThread,
const DT_CONTEXT * pContext)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::CheckContext(VMPTR_Thread vmThread, ContextBuffer contextBuffer)
{
DD_ENTER_MAY_THROW;

if ((contextBuffer.pContextBytes == NULL) || (contextBuffer.contextSize < sizeof(DT_CONTEXT)))
{
return E_INVALIDARG;
}

const DT_CONTEXT * pContext = reinterpret_cast<const DT_CONTEXT *>(contextBuffer.pContextBytes);

// If the SP in the CONTEXT isn't valid, then there's no point in checking.
if ((pContext->ContextFlags & CONTEXT_CONTROL) == 0)
{
Expand Down Expand Up @@ -551,9 +579,9 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thr
Frame * pFrame = pThread->GetFrame();
AppDomain * pAppDomain = AppDomain::GetCurrentDomain();

// cStubFrame entries have no DT_CONTEXT buffer; leave ctx as NULL so consumers
// cStubFrame entries have no DT_CONTEXT buffer; leave ctx empty so consumers
// (and the cDAC cross-check, which sets ctx = 0) don't observe a garbage value.
frameData.ctx = NULL;
frameData.ctx = {};
frameData.eType = Debugger_STRData::cStubFrame;

while (pFrame != FRAME_TOP)
Expand Down Expand Up @@ -722,14 +750,26 @@ FramePointer DacDbiInterfaceImpl::GetFramePointerWorker(StackFrameIterator * pIt
}

// Return TRUE if the specified CONTEXT is the CONTEXT of the leaf frame.
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::IsLeafFrame(VMPTR_Thread vmThread, const DT_CONTEXT * pContext, OUT BOOL * pResult)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::IsLeafFrame(VMPTR_Thread vmThread, ContextBuffer contextBuffer, OUT BOOL * pResult)
{
DD_ENTER_MAY_THROW;

if (pResult == NULL)
{
return E_INVALIDARG;
}
*pResult = FALSE;
if ((contextBuffer.pContextBytes == NULL) || (contextBuffer.contextSize < sizeof(DT_CONTEXT)))
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
EX_TRY
{

const DT_CONTEXT * pContext = reinterpret_cast<const DT_CONTEXT *>(contextBuffer.pContextBytes);

DT_CONTEXT ctxLeaf;
Thread * pThread = vmThread.GetDacPtr();
ctxLeaf.ContextFlags = DT_CONTEXT_ALL;
Expand All @@ -739,7 +779,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::IsLeafFrame(VMPTR_Thread vmThread
reinterpret_cast<BYTE *>(&ctxLeaf)));

// Call a platform-specific helper to compare the two contexts.
*pResult = CompareControlRegisters(pContext, &ctxLeaf);
*pResult = ::CompareControlRegisters(pContext, &ctxLeaf);
}
EX_CATCH_HRESULT(hr);
return hr;
Expand Down Expand Up @@ -772,8 +812,8 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,
{
pFrameData->eType = Debugger_STRData::cRuntimeNativeFrame;

_ASSERTE(pFrameData->ctx != NULL);
GetStackWalkCurrentContext(pIter, pFrameData->ctx);
_ASSERTE(pFrameData->ctx.pContextBytes != NULL);
GetStackWalkCurrentContext(pIter, reinterpret_cast<DT_CONTEXT *>(pFrameData->ctx.pContextBytes));
}
else if (ft == kManagedStackFrame)
{
Expand Down Expand Up @@ -803,8 +843,8 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,

pFrameData->eType = Debugger_STRData::cMethodFrame;

_ASSERTE(pFrameData->ctx != NULL);
GetStackWalkCurrentContext(pIter, pFrameData->ctx);
_ASSERTE(pFrameData->ctx.pContextBytes != NULL);
GetStackWalkCurrentContext(pIter, reinterpret_cast<DT_CONTEXT *>(pFrameData->ctx.pContextBytes));

//
// initialize the fields in Debugger_STRData::v
Expand Down
21 changes: 1 addition & 20 deletions src/coreclr/debug/di/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(CORDBDI_SOURCES
shimstackwalk.cpp
breakpoint.cpp
cordb.cpp
cordbregisterset.cpp
divalue.cpp
dbgtransportmanager.cpp
hash.cpp
Expand Down Expand Up @@ -50,33 +51,13 @@ set(CORDBDI_HEADERS
if(CLR_CMAKE_HOST_WIN32)
#use static crt
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)

if (CLR_CMAKE_TARGET_ARCH_AMD64 OR ((CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM)
AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD))
set(CORDBDI_SOURCES_ASM_FILE ${ARCH_SOURCES_DIR}/floatconversion.asm)
endif()

if ((CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64) AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
convert_to_absolute_path(CORDBDI_SOURCES_ASM_FILE ${CORDBDI_SOURCES_ASM_FILE})
preprocess_files(CORDBDI_SOURCES_ASM_FILE ${CORDBDI_SOURCES_ASM_FILE})
endif()
elseif(CLR_CMAKE_HOST_UNIX)

if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
set(CORDBDI_SOURCES_ASM_FILE
${ARCH_SOURCES_DIR}/floatconversion.S
)
endif()

endif(CLR_CMAKE_HOST_WIN32)

if (CLR_CMAKE_TARGET_WIN32)
convert_to_absolute_path(CORDBDI_HEADERS ${CORDBDI_HEADERS})
list(APPEND CORDBDI_SOURCES ${CORDBDI_HEADERS})
endif (CLR_CMAKE_TARGET_WIN32)

list(APPEND CORDBDI_SOURCES ${CORDBDI_SOURCES_ASM_FILE})

add_library_clr(cordbdi STATIC ${CORDBDI_SOURCES})
target_precompile_headers(cordbdi PRIVATE stdafx.h)
add_dependencies(cordbdi eventing_headers)
19 changes: 0 additions & 19 deletions src/coreclr/debug/di/amd64/FloatConversion.asm

This file was deleted.

Loading