Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,15 @@ IEnumerable<IStackDataFrameHandle> 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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<IStackDataFrameHandle> _dataFrames;

public ClrDataStackWalk(TargetPointer threadAddr, uint flags, Target target, IXCLRDataStackWalk? legacyImpl)
Expand All @@ -33,25 +34,33 @@ public ClrDataStackWalk(TargetPointer threadAddr, uint flags, Target target, IXC

// IEnumerator<T> 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)
Expand All @@ -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

Expand All @@ -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)
{
Expand Down