diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs index 00705d5adf78db..633283e91de529 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs @@ -53,7 +53,15 @@ IEnumerable IStackWalk.CreateStackWalk(ThreadData threadD IPlatformAgnosticContext context = IPlatformAgnosticContext.GetContextForPlatform(_target); FillContextFromThread(context, threadData); StackWalkState state = IsManaged(context.InstructionPointer, out _) ? StackWalkState.SW_FRAMELESS : StackWalkState.SW_FRAME; - StackWalkData stackWalkData = new(context, state, new(_target, threadData)); + FrameIterator frameIterator = new(_target, threadData); + + // if the next Frame is not valid and we are not in managed code, there is nothing to return + if (state == StackWalkState.SW_FRAME && !frameIterator.IsValid()) + { + yield break; + } + + StackWalkData stackWalkData = new(context, state, frameIterator); yield return stackWalkData.ToDataFrame(); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs index 615e7123029a82..8440611106be13 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataStackWalk.cs @@ -19,6 +19,7 @@ internal sealed unsafe partial class ClrDataStackWalk : IXCLRDataStackWalk private readonly Target _target; private readonly IXCLRDataStackWalk? _legacyImpl; + private bool _currentFrameIsValid; private readonly IEnumerator _dataFrames; public ClrDataStackWalk(TargetPointer threadAddr, uint flags, Target target, IXCLRDataStackWalk? legacyImpl) @@ -33,25 +34,33 @@ public ClrDataStackWalk(TargetPointer threadAddr, uint flags, Target target, IXC // IEnumerator begins before the first element. // Call MoveNext() to set _dataFrames.Current to the first element. - _dataFrames.MoveNext(); + _currentFrameIsValid = _dataFrames.MoveNext(); } int IXCLRDataStackWalk.GetContext(uint contextFlags, uint contextBufSize, uint* contextSize, [MarshalUsing(CountElementName = "contextBufSize"), Out] byte[] contextBuf) { int hr = HResults.S_OK; - IStackWalk sw = _target.Contracts.StackWalk; - IStackDataFrameHandle dataFrame = _dataFrames.Current; - byte[] context = sw.GetRawContext(dataFrame); - if (context.Length > contextBufSize) - hr = HResults.E_INVALIDARG; + if (_currentFrameIsValid) + { + IStackWalk sw = _target.Contracts.StackWalk; + IStackDataFrameHandle dataFrame = _dataFrames.Current; + byte[] context = sw.GetRawContext(dataFrame); + if (context.Length > contextBufSize) + hr = HResults.E_INVALIDARG; + + if (contextSize is not null) + { + *contextSize = (uint)context.Length; + } - if (contextSize is not null) + context.CopyTo(contextBuf); + } + else { - *contextSize = (uint)context.Length; + hr = HResults.S_FALSE; } - context.CopyTo(contextBuf); #if DEBUG if (_legacyImpl is not null) @@ -60,12 +69,15 @@ int IXCLRDataStackWalk.GetContext(uint contextFlags, uint contextBufSize, uint* int hrLocal = _legacyImpl.GetContext(contextFlags, contextBufSize, null, localContextBuf); Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); - IPlatformAgnosticContext contextStruct = IPlatformAgnosticContext.GetContextForPlatform(_target); - IPlatformAgnosticContext localContextStruct = IPlatformAgnosticContext.GetContextForPlatform(_target); - contextStruct.FillFromBuffer(contextBuf); - localContextStruct.FillFromBuffer(localContextBuf); + if (hr == HResults.S_OK) + { + IPlatformAgnosticContext contextStruct = IPlatformAgnosticContext.GetContextForPlatform(_target); + IPlatformAgnosticContext localContextStruct = IPlatformAgnosticContext.GetContextForPlatform(_target); + contextStruct.FillFromBuffer(contextBuf); + localContextStruct.FillFromBuffer(localContextBuf); - Debug.Assert(contextStruct.Equals(localContextStruct)); + Debug.Assert(contextStruct.Equals(localContextStruct)); + } } #endif @@ -83,7 +95,8 @@ int IXCLRDataStackWalk.Next() int hr; try { - hr = _dataFrames.MoveNext() ? HResults.S_OK : HResults.S_FALSE; + _currentFrameIsValid = _dataFrames.MoveNext(); + hr = _currentFrameIsValid ? HResults.S_OK : HResults.S_FALSE; } catch (System.Exception ex) {