From 520f689f0ba2e21c4a2c81852836ecb1982389bc Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 16 Apr 2026 23:20:12 -0400 Subject: [PATCH] Fix cDAC stack walker infinite loop on InlinedCallFrame with missing JIT code When an InlinedCallFrame has an active P/Invoke call, the walker sets the context IP to CallerReturnAddress and does not advance the frame iterator (expecting the next iteration to process the managed caller). If IsManaged() returns false (e.g. partial dump without JIT code heaps), the walker stays in SW_FRAME state and re-processes the same InlinedCallFrame indefinitely. Fix: when the InlinedCallFrame has an active call but the caller IP is not in a known managed code range, advance past the frame. This only affects scenarios where JIT code ranges are unreadable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Contracts/StackWalk/StackWalk_1.cs | 9 +++++++++ 1 file changed, 9 insertions(+) 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 281bf58b6d3fe3..efdbbd7041a5c6 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 @@ -97,6 +97,15 @@ private bool Next(StackWalkData handle) { handle.FrameIter.Next(); } + else if (!IsManaged(handle.Context.InstructionPointer, out _)) + { + // The InlinedCallFrame has an active call but the caller's IP is not + // in a known managed code range (e.g. partial dump without JIT code + // heaps). Advance past the frame to prevent an infinite loop — without + // managed code range data the walker would repeatedly re-process the + // same InlinedCallFrame. + handle.FrameIter.Next(); + } break; case StackWalkState.SW_ERROR: case StackWalkState.SW_COMPLETE: