in src/Microsoft.Diagnostics.Runtime/ClrHeap.cs [672:713]
public IEnumerable<ClrRoot> EnumerateRoots()
{
// Handle table
foreach (ClrHandle handle in Runtime.EnumerateHandles())
{
if (handle.IsStrong)
yield return handle;
if (handle.RootKind == ClrRootKind.AsyncPinnedHandle && handle.Object.IsValid)
{
(ulong address, ClrObject m_userObject) = GetObjectAndAddress(handle.Object, "m_userObject");
if (address != 0 && m_userObject.IsValid)
{
yield return new ClrHandle(handle.AppDomain, address, m_userObject, handle.HandleKind);
ClrElementType? arrayElementType = m_userObject.Type?.ComponentType?.ElementType;
if (m_userObject.IsArray && arrayElementType.HasValue && arrayElementType.Value.IsObjectReference())
{
ClrArray array = m_userObject.AsArray();
for (int i = 0; i < array.Length; i++)
{
ulong innerAddress = m_userObject + (ulong)(2 * IntPtr.Size + i * IntPtr.Size);
ClrObject innerObj = array.GetObjectValue(i);
if (innerObj.IsValid)
yield return new ClrHandle(handle.AppDomain, innerAddress, innerObj, handle.HandleKind);
}
}
}
}
}
// Finalization Queue
foreach (ClrRoot root in EnumerateFinalizerRoots())
yield return root;
// Threads
foreach (ClrThread thread in Runtime.Threads.Where(t => t.IsAlive))
foreach (ClrRoot root in thread.EnumerateStackRoots())
yield return root;
}