| File: Dbi\Helpers\StackWalkHandleData.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Legacy\Microsoft.Diagnostics.DataContractReader.Legacy.csproj (Microsoft.Diagnostics.DataContractReader.Legacy) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Linq; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Diagnostics.CodeAnalysis; using Microsoft.Diagnostics.DataContractReader.Contracts; namespace Microsoft.Diagnostics.DataContractReader.Legacy; internal sealed class StackWalkHandleData { private readonly IStackWalk _stackWalk; private readonly ThreadData _threadData; private IEnumerator<IStackDataFrameHandle>? _enumerator; public StackWalkHandleData(IStackWalk stackWalk, ThreadData threadData) { _stackWalk = stackWalk; _threadData = threadData; } public IStackDataFrameHandle? Current { get; private set; } [MemberNotNullWhen(true, nameof(Current))] public bool IsValid => Current is not null; public nuint LegacyHandle { get; set; } public void Reset(byte[] contextBuffer, bool isFirst) { _enumerator?.Dispose(); _enumerator = _stackWalk .CreateStackWalk(_threadData, contextBuffer, isFirst) .Where(h => h.State is not (StackWalkState.Frame or StackWalkState.SkippedFrame)) .GetEnumerator(); Current = _enumerator is not null && _enumerator.MoveNext() ? _enumerator.Current : null; if (Current is null) throw Marshal.GetExceptionForHR(HResults.E_FAIL)!; } public void Advance() { Current = _enumerator is not null && _enumerator.MoveNext() ? _enumerator.Current : null; } public nuint GetHandle() { GCHandle gcHandle = GCHandle.Alloc(this); return (nuint)GCHandle.ToIntPtr(gcHandle); } public void Dispose() => _enumerator?.Dispose(); }