public override void Reset() { // There is no way to reset. Just create a new one. CorStackWalk s = m_th.CreateStackWalk(CorStackWalkType.ExtendedV3StackWalk); m_sw = s.GetInterface(); m_frame = null; }
public virtual void Reset() { // There is no way to reset. Just create a new one. CorStackWalk s = m_th.CreateStackWalk(CorStackWalkType.PureV3StackWalk); m_sw = s.GetInterface(); m_frame = null; }
// This method handles internal frames but no child frames. private bool MoveNextWorker() { if (m_bEndOfStackFrame) { return(false); } bool fIsLeafFrame = false; bool fIsFuncEvalFrame = false; int hr; if (m_init) { // this the 2nd or more call to MoveNext() and MoveNextWorker() if ((m_frame != null) && (m_frame.FrameType == CorFrameType.InternalFrame)) { // We have just handed out an internal frame, so we need to start looking at the next // internal frame AND we don't call m_sw.Next() to preserve the previous managed frame if (m_internalFrameIndex < m_internalFrames.Length) { m_internalFrameIndex++; } fIsFuncEvalFrame = (m_frame.InternalFrameType == CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL); hr = (int)HResult.S_OK; } else { // We just handed out a managed or native frame. // In any case, use the managed unwinder to unwind. hr = m_sw.Next(); // Check for end-of-stack condition. if (hr == (int)HResult.CORDBG_S_AT_END_OF_STACK) { m_bEndOfStackFrame = true; } } } else { // this is the initial call to MoveNext() and MoveNextWorker() that validates the enumeration // after we return from MoveNext(), .Current will point to the leaf-most frame m_init = true; fIsLeafFrame = true; hr = (int)HResult.S_OK; } // Check for errors. if (HRUtils.IsFailingHR(hr)) { Marshal.ThrowExceptionForHR(hr); } if (!m_bEndOfStackFrame) { // Now we need to do a comparison between the current stack frame and the internal frame (if any) // to figure out which one to give back first. ICorDebugFrame frame; m_sw.GetFrame(out frame); if (frame == null) { // this represents native frame(s) to managed code, we return true because there may be more // managed frames beneath m_frame = null; return(true); } // we compare the current managed frame with the internal frame CorFrame currentFrame = new CorFrame(frame); for (; m_internalFrameIndex < m_internalFrames.Length; m_internalFrameIndex++) { CorFrame internalFrame = m_internalFrames[m_internalFrameIndex]; // Check for internal frame types which are not exposed in V2. if (IsV3InternalFrameType(internalFrame)) { continue; } if (internalFrame.IsCloserToLeaf(currentFrame)) { currentFrame = internalFrame; } else if (internalFrame.InternalFrameType == CorDebugInternalFrameType.STUBFRAME_M2U) { // we need to look at the caller stack frame's SP INativeContext ctx = this.GetContext(); CorStackWalk tStack = m_th.CreateStackWalk(CorStackWalkType.PureV3StackWalk); CorDebugSetContextFlag flag = ((fIsFuncEvalFrame || fIsLeafFrame) ? CorDebugSetContextFlag.SET_CONTEXT_FLAG_ACTIVE_FRAME : CorDebugSetContextFlag.SET_CONTEXT_FLAG_UNWIND_FRAME); tStack.SetContext(flag, ctx); //tStack now points to the "previous" managed frame, not the managed frame we're looking at //the first MoveNext call moves the temporary stackwalker to the "current" frame and the next //MoveNext call moves the temporary stackwalker to the "caller" frame Int64 current = 0, caller = 0; if (tStack.MoveNext()) { if (tStack.Current != null) { current = tStack.GetContext().StackPointer.ToInt64(); } } if (tStack.MoveNext()) { if (tStack.Current != null) { caller = tStack.GetContext().StackPointer.ToInt64(); } } if (current == 0 || caller == 0) { //we've hit a native frame somewhere, we shouldn't be doing anything with this break; } if (current < caller && internalFrame.IsCloserToLeaf(tStack.Current)) { // if there is no caller frame or the current managed frame is closer to the leaf frame // than the next managed frame on the stack (the caller frame), then we must be in the case // where: // [IL frame without metadata] // [Internal frame, 'M --> U'] // Caller frame (managed) // We need to flip the internal and IL frames, so we hand back the internal frame first currentFrame = internalFrame; } } break; } m_frame = currentFrame; return(true); } else { // We have reached the end of the managed stack. // Check to see if we have any internal frames left. for (; m_internalFrameIndex < m_internalFrames.Length; m_internalFrameIndex++) { CorFrame internalFrame = m_internalFrames[m_internalFrameIndex]; if (IsV3InternalFrameType(internalFrame)) { continue; } m_frame = internalFrame; return(true); } return(false); } }