Beispiel #1
0
        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;
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        // 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);
            }
        }