in src/Microsoft.Diagnostics.Runtime/src/Builders/RuntimeBuilder.cs [582:648]
private IEnumerable<ClrHandle> EnumerateHandleTable(ClrRuntime runtime, HandleData[] handles)
{
CheckDisposed();
using SOSHandleEnum? handleEnum = _sos.EnumerateHandles();
if (handleEnum is null)
yield break;
ClrHeap heap = runtime.Heap;
ClrAppDomain? domain = heap.Runtime.AppDomains.Length > 0 ? heap.Runtime.AppDomains[0] : null;
int fetched;
while ((fetched = handleEnum.ReadHandles(handles)) != 0)
{
for (int i = 0; i < fetched; i++)
{
ulong objAddress = DataReader.ReadPointer(handles[i].Handle);
ClrObject clrObj = heap.GetObject(objAddress);
if (!clrObj.IsNull)
{
if (domain == null || domain.Address != handles[i].AppDomain)
domain = GetOrCreateAppDomain(null, handles[i].AppDomain);
ClrHandleKind handleKind = (ClrHandleKind)handles[i].Type;
switch (handleKind)
{
default:
yield return new ClrmdHandle(domain, handles[i].Handle, clrObj, handleKind);
break;
case ClrHandleKind.Dependent:
ClrObject dependent = heap.GetObject(handles[i].Secondary);
yield return new ClrmdDependentHandle(domain, handles[i].Handle, clrObj, dependent);
break;
case ClrHandleKind.RefCounted:
uint refCount = 0;
if (handles[i].IsPegged != 0)
refCount = handles[i].JupiterRefCount;
if (refCount < handles[i].RefCount)
refCount = handles[i].RefCount;
if (!clrObj.IsNull)
{
ComCallableWrapper? ccw = clrObj.GetComCallableWrapper();
if (ccw != null && refCount < ccw.RefCount)
{
refCount = (uint)ccw.RefCount;
}
else
{
RuntimeCallableWrapper? rcw = clrObj.GetRuntimeCallableWrapper();
if (rcw != null && refCount < rcw.RefCount)
refCount = (uint)rcw.RefCount;
}
}
yield return new ClrmdRefCountedHandle(domain, handles[i].Handle, clrObj, refCount);
break;
}
}
}
}
}