public IEnumerable EnumerateStackRoots()

in src/Microsoft.Diagnostics.Runtime/DacImplementation/DacThreadHelpers.cs [30:83]


        public IEnumerable<StackRootInfo> EnumerateStackRoots(uint osThreadId, bool traceErrors)
        {
            using SOSStackRefEnum? stackRefEnum = _sos.EnumerateStackRefs(osThreadId);
            if (stackRefEnum is null)
                yield break;

            const int GCInteriorFlag = 1;
            const int GCPinnedFlag = 2;
            const int SOS_StackSourceIP = 0;
            const int SOS_StackSourceFrame = 1;
            foreach (StackRefData stackRef in stackRefEnum.ReadStackRefs())
            {
                if (stackRef.Object == 0)
                {
                    if (traceErrors)
                        Trace.TraceWarning($"EnumerateStackRoots found an unexpected entry with Object == 0, addr:{(ulong)stackRef.Address:x} srcType:{stackRef.SourceType:x}");
                    continue;
                }

                bool interior = (stackRef.Flags & GCInteriorFlag) == GCInteriorFlag;
                bool isPinned = (stackRef.Flags & GCPinnedFlag) == GCPinnedFlag;
                int regOffset = 0;
                string? regName = null;
                if (stackRef.HasRegisterInformation != 0)
                {
                    regOffset = stackRef.Offset;
                    regName = _sos.GetRegisterName(stackRef.Register);
                }

                ulong ip = 0;
                ulong frame = 0;
                if (stackRef.SourceType == SOS_StackSourceIP)
                    ip = stackRef.Source;
                else if (stackRef.SourceType == SOS_StackSourceFrame)
                    frame = stackRef.Source;

                yield return new StackRootInfo()
                {
                    InstructionPointer = ip,
                    StackPointer = stackRef.StackPointer,
                    InternalFrame = frame,

                    IsInterior = interior,
                    IsPinned = isPinned,

                    Address = stackRef.Address,
                    Object = stackRef.Object,

                    IsEnregistered = stackRef.HasRegisterInformation != 0,
                    RegisterName = regName,
                    RegisterOffset = regOffset,
                };
            }
        }