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,132 changes: 2,399 additions & 1,733 deletions src/coreclr/debug/daccess/dacdbiimpl.cpp

Large diffs are not rendered by default.

351 changes: 124 additions & 227 deletions src/coreclr/debug/daccess/dacdbiimpl.h

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions src/coreclr/debug/daccess/dacdbiimpllocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,32 @@
#ifdef TEST_DATA_CONSISTENCY
#include "crst.h"

void DacDbiInterfaceImpl::TestCrst(VMPTR_Crst vmCrst)
HRESULT DacDbiInterfaceImpl::TestCrst(VMPTR_Crst vmCrst)
{
DD_ENTER_MAY_THROW;

DebugTryCrst(vmCrst.GetDacPtr());
HRESULT hr = S_OK;
EX_TRY
{

DebugTryCrst(vmCrst.GetDacPtr());
}
EX_CATCH_HRESULT(hr);
return hr;
}

void DacDbiInterfaceImpl::TestRWLock(VMPTR_SimpleRWLock vmRWLock)
HRESULT DacDbiInterfaceImpl::TestRWLock(VMPTR_SimpleRWLock vmRWLock)
{
DD_ENTER_MAY_THROW;

DebugTryRWLock(vmRWLock.GetDacPtr());
HRESULT hr = S_OK;
EX_TRY
{

DebugTryRWLock(vmRWLock.GetDacPtr());
}
EX_CATCH_HRESULT(hr);
return hr;
}
#endif

766 changes: 428 additions & 338 deletions src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp

Large diffs are not rendered by default.

66 changes: 41 additions & 25 deletions src/coreclr/debug/di/divalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ CordbReferenceValue* CordbValue::CreateHeapReferenceValue(CordbAppDomain* pAppDo
{
IDacDbiInterface* pDac = pAppDomain->GetProcess()->GetDAC();

TargetBuffer objBuffer = pDac->GetObjectContents(vmObj);
TargetBuffer objBuffer;
IfFailThrow(pDac->GetObjectContents(vmObj, &objBuffer));
VOID* pRemoteAddr = CORDB_ADDRESS_TO_PTR(objBuffer.pAddress);
// This creates a local reference that has a remote address in it. Ie &pRemoteAddr is an address
// in the host address space and pRemoteAddr is an address in the target.
Expand Down Expand Up @@ -1314,7 +1315,9 @@ HRESULT CordbReferenceValue::BuildFromGCHandle(
TargetBuffer remoteValue;
EX_TRY
{
remoteValue.Init(pProc->GetDAC()->GetHandleAddressFromVmHandle(gcHandle), sizeof(void *));
CORDB_ADDRESS _handleAddr;
IfFailThrow(pProc->GetDAC()->GetHandleAddressFromVmHandle(gcHandle, &_handleAddr));
remoteValue.Init(_handleAddr, sizeof(void *));
}
EX_CATCH_HRESULT(hr);
IfFailRet(hr);
Expand Down Expand Up @@ -1565,7 +1568,7 @@ void CordbReferenceValue::GetTypedByRefData(CordbProcess * pProcess,
// TypedByref objects, it is actually the address of the TypedByRef struct which contains the
// type and the object address.

pProcess->GetDAC()->GetTypedByRefInfo(pTypedByRef, vmAppDomain, pInfo);
IfFailThrow(pProcess->GetDAC()->GetTypedByRefInfo(pTypedByRef, vmAppDomain, pInfo));
} // CordbReferenceValue::GetTypedByRefData

// get the address of the object referenced
Expand Down Expand Up @@ -2452,11 +2455,12 @@ HRESULT CordbObjectValue::EnumerateExceptionCallStack(ICorDebugExceptionObjectCa
CORDB_ADDRESS objAddr = m_valueHome.GetAddress();

IDacDbiInterface* pDAC = GetProcess()->GetDAC();
VMPTR_Object vmObj = pDAC->GetObject(objAddr);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));

DacDbiArrayList<DacExceptionCallStackData> dacStackFrames;

pDAC->GetStackFramesFromException(vmObj, dacStackFrames);
IfFailThrow(pDAC->GetStackFramesFromException(vmObj, dacStackFrames));
int stackFramesLength = dacStackFrames.Count();

if (stackFramesLength > 0)
Expand Down Expand Up @@ -2508,7 +2512,8 @@ HRESULT CordbObjectValue::ForceCatchHandlerFoundEvents(BOOL enableEvents)
CORDB_ADDRESS objAddr = m_valueHome.GetAddress();

IDacDbiInterface* pDAC = GetProcess()->GetDAC();
VMPTR_Object vmObj = pDAC->GetObject(objAddr);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));

DebuggerIPCEvent event;
CordbAppDomain * pAppDomain = GetAppDomain();
Expand Down Expand Up @@ -2549,8 +2554,10 @@ HRESULT CordbObjectValue::IsExceptionObject()
{
IDacDbiInterface* pDAC = GetProcess()->GetDAC();

VMPTR_Object vmObj = pDAC->GetObject(objAddr);
BOOL fIsException = pDAC->IsExceptionObject(vmObj);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));
BOOL fIsException;
IfFailThrow(pDAC->IsExceptionObject(vmObj, &fIsException));

if (!fIsException)
hr = S_FALSE;
Expand Down Expand Up @@ -2581,8 +2588,10 @@ HRESULT CordbObjectValue::IsRcw()
{
IDacDbiInterface* pDAC = GetProcess()->GetDAC();

VMPTR_Object vmObj = pDAC->GetObject(objAddr);
BOOL fIsRcw = pDAC->IsRcw(vmObj);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));
BOOL fIsRcw;
IfFailThrow(pDAC->IsRcw(vmObj, &fIsRcw));

if (!fIsRcw)
hr = S_FALSE;
Expand Down Expand Up @@ -2613,8 +2622,10 @@ HRESULT CordbObjectValue::IsDelegate()
{
IDacDbiInterface *pDAC = GetProcess()->GetDAC();

VMPTR_Object vmObj = pDAC->GetObject(objAddr);
BOOL fIsDelegate = pDAC->IsDelegate(vmObj);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));
BOOL fIsDelegate;
IfFailThrow(pDAC->IsDelegate(vmObj, &fIsDelegate));

if (!fIsDelegate)
hr = S_FALSE;
Expand Down Expand Up @@ -2646,7 +2657,7 @@ HRESULT CordbObjectValue::GetTargetHelper(ICorDebugReferenceValue **ppTarget)
CORDB_ADDRESS delegateAddr = m_valueHome.GetAddress();

IDacDbiInterface *pDAC = GetProcess()->GetDAC();
pDelegateObj = pDAC->GetObject(delegateAddr);
IfFailThrow(pDAC->GetObject(delegateAddr, &pDelegateObj));

HRESULT hr = pDAC->GetDelegateType(pDelegateObj, &delType);
if (hr != S_OK)
Expand Down Expand Up @@ -2681,7 +2692,7 @@ HRESULT CordbObjectValue::GetFunctionHelper(ICorDebugFunction **ppFunction)
CORDB_ADDRESS delegateAddr = m_valueHome.GetAddress();

IDacDbiInterface *pDAC = GetProcess()->GetDAC();
pDelegateObj = pDAC->GetObject(delegateAddr);
IfFailThrow(pDAC->GetObject(delegateAddr, &pDelegateObj));

HRESULT hr = pDAC->GetDelegateType(pDelegateObj, &delType);
if (hr != S_OK)
Expand All @@ -2704,7 +2715,7 @@ HRESULT CordbObjectValue::GetFunctionHelper(ICorDebugFunction **ppFunction)
// TODO: How to ensure results are sanitized?
// Also, this is expensive. Do we really care that much about this?
NativeCodeFunctionData nativeCodeForDelFunc;
pDAC->GetNativeCodeInfo(functionDomainAssembly, functionMethodDef, &nativeCodeForDelFunc);
IfFailThrow(pDAC->GetNativeCodeInfo(functionDomainAssembly, functionMethodDef, &nativeCodeForDelFunc));

RSSmartPtr<CordbModule> funcModule(GetProcess()->LookupOrCreateModule(functionDomainAssembly));
func.Assign(funcModule->LookupOrCreateFunction(functionMethodDef, nativeCodeForDelFunc.encVersion));
Expand Down Expand Up @@ -2783,11 +2794,12 @@ HRESULT CordbObjectValue::GetCachedInterfaceTypes(
IDacDbiInterface* pDAC = GetProcess()->GetDAC();

CORDB_ADDRESS objAddr = m_valueHome.GetAddress();
VMPTR_Object vmObj = pDAC->GetObject(objAddr);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));

// retrieve type info from LS
pDAC->GetRcwCachedInterfaceTypes(vmObj, m_appdomain->GetADToken(),
bIInspectableOnly, &dacInterfaces);
IfFailThrow(pDAC->GetRcwCachedInterfaceTypes(vmObj, m_appdomain->GetADToken(),
bIInspectableOnly, &dacInterfaces));

// synthesize CordbType instances
int cItfs = dacInterfaces.Count();
Expand Down Expand Up @@ -2851,10 +2863,11 @@ HRESULT CordbObjectValue::GetCachedInterfacePointers(
EX_TRY
{
IDacDbiInterface* pDAC = GetProcess()->GetDAC();
VMPTR_Object vmObj = pDAC->GetObject(objAddr);
VMPTR_Object vmObj;
IfFailThrow(pDAC->GetObject(objAddr, &vmObj));

// retrieve type info from LS
pDAC->GetRcwCachedInterfacePointers(vmObj, bIInspectableOnly, &dacItfPtrs);
IfFailThrow(pDAC->GetRcwCachedInterfacePointers(vmObj, bIInspectableOnly, &dacItfPtrs));
}
EX_CATCH_HRESULT(hr);
IfFailRet(hr);
Expand Down Expand Up @@ -4307,7 +4320,7 @@ HRESULT CordbHandleValue::RefreshHandleValue()

EX_TRY
{
objectHandle = pProcess->GetDAC()->GetHandleAddressFromVmHandle(m_vmHandle);
IfFailThrow(pProcess->GetDAC()->GetHandleAddressFromVmHandle(m_vmHandle, &objectHandle));
if (type != ELEMENT_TYPE_TYPEDBYREF)
{
pProcess->SafeReadBuffer(TargetBuffer(objectHandle, sizeof(void *)), (BYTE *)&objectAddress);
Expand Down Expand Up @@ -4592,7 +4605,7 @@ HRESULT CordbHandleValue::GetAddress(CORDB_ADDRESS *pAddress)
HRESULT hr = S_OK;
EX_TRY
{
*pAddress = GetProcess()->GetDAC()->GetHandleAddressFromVmHandle(m_vmHandle);
IfFailThrow(GetProcess()->GetDAC()->GetHandleAddressFromVmHandle(m_vmHandle, pAddress));
}
EX_CATCH_HRESULT(hr);
return hr;
Expand Down Expand Up @@ -4752,8 +4765,10 @@ HRESULT CordbHeapValue3Impl::GetThreadOwningMonitorLock(CordbProcess* pProcess,
EX_TRY
{
IDacDbiInterface *pDac = pProcess->GetDAC();
VMPTR_Object vmObj = pDac->GetObject(remoteObjAddress);
MonitorLockInfo info = pDac->GetThreadOwningMonitorLock(vmObj);
VMPTR_Object vmObj;
IfFailThrow(pDac->GetObject(remoteObjAddress, &vmObj));
MonitorLockInfo info;
IfFailThrow(pDac->GetThreadOwningMonitorLock(vmObj, &info));
if(info.acquisitionCount == 0)
{
// unowned
Expand Down Expand Up @@ -4806,7 +4821,8 @@ HRESULT CordbHeapValue3Impl::GetMonitorEventWaitList(CordbProcess* pProcess,
EX_TRY
{
IDacDbiInterface *pDac = pProcess->GetDAC();
VMPTR_Object vmObj = pDac->GetObject(remoteObjAddress);
VMPTR_Object vmObj;
IfFailThrow(pDac->GetObject(remoteObjAddress, &vmObj));
CQuickArrayList<VMPTR_Thread> threads;
pDac->EnumerateMonitorEventWaitList(vmObj,
(IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK)ThreadEnumerationCallback, (VOID*)&threads);
Comment on lines 4827 to 4828
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnumerateMonitorEventWaitList now returns HRESULT, but this call site ignores the return value (and doesn’t use IfFailThrow). This will either fail to compile (if the signature changed as shown) or will silently continue after an error, leaving threads incomplete/corrupt. Capture/check the returned HRESULT (or wrap with IfFailThrow) before using threads.

Suggested change
pDac->EnumerateMonitorEventWaitList(vmObj,
(IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK)ThreadEnumerationCallback, (VOID*)&threads);
IfFailThrow(pDac->EnumerateMonitorEventWaitList(
vmObj,
(IDacDbiInterface::FP_THREAD_ENUMERATION_CALLBACK)ThreadEnumerationCallback,
(VOID*)&threads));

Copilot uses AI. Check for mistakes.
Expand Down
48 changes: 28 additions & 20 deletions src/coreclr/debug/di/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ CordbModule::CordbModule(

// Fill out properties via DAC.
ModuleInfo modInfo;
pProcess->GetDAC()->GetModuleData(vmModule, &modInfo); // throws
IfFailThrow(pProcess->GetDAC()->GetModuleData(vmModule, &modInfo)); // throws

m_PEBuffer.Init(modInfo.pPEBaseAddress, modInfo.nPESize);

Expand All @@ -62,7 +62,7 @@ CordbModule::CordbModule(
{
DomainAssemblyInfo dfInfo;

pProcess->GetDAC()->GetDomainAssemblyData(vmDomainAssembly, &dfInfo); // throws
IfFailThrow(pProcess->GetDAC()->GetDomainAssemblyData(vmDomainAssembly, &dfInfo)); // throws

m_pAppDomain = pProcess->LookupOrCreateAppDomain(dfInfo.vmAppDomain);
_ASSERTE(m_pAppDomain == pProcess->GetAppDomain());
Expand Down Expand Up @@ -117,10 +117,10 @@ void DbgAssertModuleDeletedCallback(VMPTR_DomainAssembly vmDomainAssembly, void
//
void CordbModule::DbgAssertModuleDeleted()
{
GetProcess()->GetDAC()->EnumerateAssembliesInAppDomain(
IfFailThrow(GetProcess()->GetDAC()->EnumerateAssembliesInAppDomain(
m_pAppDomain->GetADToken(),
DbgAssertModuleDeletedCallback,
this);
this));
}
#endif // _DEBUG

Expand Down Expand Up @@ -223,7 +223,7 @@ IDacDbiInterface::SymbolFormat CordbModule::GetInMemorySymbolStream(IStream ** p

TargetBuffer bufferPdb;
IDacDbiInterface::SymbolFormat symFormat;
GetProcess()->GetDAC()->GetSymbolsBuffer(m_vmModule, &bufferPdb, &symFormat);
IfFailThrow(GetProcess()->GetDAC()->GetSymbolsBuffer(m_vmModule, &bufferPdb, &symFormat));
if (bufferPdb.IsEmpty())
{
// No in-memory PDB. Common case.
Expand Down Expand Up @@ -499,7 +499,7 @@ void CordbModule::RefreshMetaData()
// We could make a reader for MDInternalRO, but no need yet. This also ensures we don't encroach into common
// scenario where we can map a file on disk.
TADDR remoteMDInternalRWAddr = (TADDR)NULL;
GetProcess()->GetDAC()->GetPEFileMDInternalRW(m_vmPEFile, &remoteMDInternalRWAddr);
IfFailThrow(GetProcess()->GetDAC()->GetPEFileMDInternalRW(m_vmPEFile, &remoteMDInternalRWAddr));
if (remoteMDInternalRWAddr != (TADDR)NULL)
{
// we should only be doing this once to initialize, we don't support reopen with this technique
Expand Down Expand Up @@ -527,7 +527,7 @@ void CordbModule::RefreshMetaData()
if(!m_fForceMetaDataSerialize) // case 1 and 2
{
LOG((LF_CORDB,LL_INFO10000, "CM::RM !m_fForceMetaDataSerialize case\n"));
GetProcess()->GetDAC()->GetMetadata(m_vmModule, &bufferMetaData); // throws
IfFailThrow(GetProcess()->GetDAC()->GetMetadata(m_vmModule, &bufferMetaData)); // throws
}
else if (GetProcess()->GetShim() == NULL) // case 3 won't work on a dump so don't try
{
Expand Down Expand Up @@ -797,10 +797,13 @@ HRESULT CordbModule::InitPublicMetaDataFromFile(const WCHAR * pszFullPathName,

_ASSERTE(!m_vmPEFile.IsNull());
// MetaData lookup favors the NGEN image, which is what we want here.
if (!this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
bool _mdFileInfoResult;
IfFailThrow(this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
dwImageTimeStamp,
dwImageSize,
&filePath))
&filePath,
&_mdFileInfoResult));
if (!_mdFileInfoResult)
{
LOG((LF_CORDB,LL_WARNING, "CM::IM: Couldn't get metadata info for file \"%s\"\n", pszFullPathName));
return CORDBG_E_MISSING_METADATA;
Expand Down Expand Up @@ -1184,10 +1187,13 @@ HRESULT CordbModule::GetName(ULONG32 cchName, ULONG32 *pcchName, _Out_writes_to_
StringCopyHolder filePath;

_ASSERTE(!m_vmPEFile.IsNull());
if (this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
bool _mdFileInfoResult;
IfFailThrow(this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
dwImageTimeStamp,
dwImageSize,
&filePath))
&filePath,
&_mdFileInfoResult));
if (_mdFileInfoResult)
{
_ASSERTE(filePath.IsSet());
hr = CopyOutString(filePath, cchName, pcchName, szName);
Expand Down Expand Up @@ -1275,7 +1281,7 @@ HRESULT CordbModule::GetNameWorker(ULONG32 cchName, ULONG32 *pcchName, _Out_writ
// Tempting to use the metadata-scope name, but that's a regression from Whidbey. For manifest modules,
// the metadata scope name is not initialized with the string the user supplied to create the
// dynamic assembly. So we call into the runtime to use CLR heuristics to get a more accurate name.
m_pProcess->GetDAC()->GetModuleSimpleName(m_vmModule, &buffer);
IfFailThrow(m_pProcess->GetDAC()->GetModuleSimpleName(m_vmModule, &buffer));
_ASSERTE(buffer.IsSet());
szTempName = buffer;
// Note that we considered returning S_FALSE for fabricated names like this, but that's a breaking
Expand Down Expand Up @@ -1308,7 +1314,8 @@ const WCHAR * CordbModule::GetModulePath()
if (!m_strModulePath.IsSet())
{
IDacDbiInterface * pDac = m_pProcess->GetDAC(); // throws
pDac->GetModulePath(m_vmModule, &m_strModulePath); // throws
BOOL fNonEmpty;
IfFailThrow(pDac->GetModulePath(m_vmModule, &m_strModulePath, &fNonEmpty)); // throws
_ASSERTE(m_strModulePath.IsSet());
}

Expand Down Expand Up @@ -1909,7 +1916,7 @@ HRESULT CordbModule::ResolveTypeRef(mdTypeRef token, CordbClass **ppClass)

{
RSLockHolder lockHolder(pProcess->GetProcessLock());
pProcess->GetDAC()->ResolveTypeReference(&inData, &outData);
IfFailThrow(pProcess->GetDAC()->ResolveTypeReference(&inData, &outData));
}

CordbModule * pModule = m_pAppDomain->LookupOrCreateModule(outData.vmDomainAssembly);
Expand Down Expand Up @@ -2377,7 +2384,8 @@ CordbAssembly * CordbModule::ResolveAssemblyInternal(mdToken tkAssemblyRef)
if (!m_vmDomainAssembly.IsNull())
{
// Get DAC to do the real work to resolve the assembly
VMPTR_DomainAssembly vmDomainAssembly = GetProcess()->GetDAC()->ResolveAssembly(m_vmDomainAssembly, tkAssemblyRef);
VMPTR_DomainAssembly vmDomainAssembly;
IfFailThrow(GetProcess()->GetDAC()->ResolveAssembly(m_vmDomainAssembly, tkAssemblyRef, &vmDomainAssembly));

// now find the ICorDebugAssembly corresponding to it
if (!vmDomainAssembly.IsNull() && m_pAppDomain != NULL)
Expand Down Expand Up @@ -2583,10 +2591,10 @@ HRESULT CordbModule::GetJITCompilerFlags(DWORD *pdwFlags )
BOOL fAllowJitOpts;
BOOL fEnableEnC;

pProcess->GetDAC()->GetCompilerFlags (
IfFailThrow(pProcess->GetDAC()->GetCompilerFlags (
GetRuntimeDomainAssembly(),
&fAllowJitOpts,
&fEnableEnC);
&fEnableEnC));

if (fEnableEnC)
{
Expand Down Expand Up @@ -5103,7 +5111,7 @@ CordbNativeCode * CordbModule::LookupOrCreateNativeCode(mdMethodDef methodToken,

if (pNativeCode == NULL)
{
GetProcess()->GetDAC()->GetNativeCodeInfoForAddr(startAddress, &codeInfo, NULL, NULL);
IfFailThrow(GetProcess()->GetDAC()->GetNativeCodeInfoForAddr(startAddress, &codeInfo, NULL, NULL));

// We didn't have an instance, so we'll build one and add it to the hash table
LOG((LF_CORDB,
Expand Down Expand Up @@ -5158,11 +5166,11 @@ void CordbNativeCode::LoadNativeInfo()
if (m_fCodeAvailable)
{
RSLockHolder lockHolder(pProcess->GetProcessLock());
pProcess->GetDAC()->GetNativeCodeSequencePointsAndVarInfo(GetVMNativeCodeMethodDescToken(),
IfFailThrow(pProcess->GetDAC()->GetNativeCodeSequencePointsAndVarInfo(GetVMNativeCodeMethodDescToken(),
GetAddress(),
m_fCodeAvailable,
&m_nativeVarData,
&m_sequencePoints);
&m_sequencePoints));
}

} // CordbNativeCode::LoadNativeInfo
Loading
Loading