コード例 #1
0
        // The function verifies that the stackwalker for this thread is "current". The stack-walker will become
        // invalid when a debugger performs an operation that invalidats active stackwalkers. Examples of such
        // operations are:
        //  - calling Continue(), calling SetIP() or calling RefreshStack() methods.
        //
        //  If the current stack-walker is not current, a new stack-walker is created for the thread. The function
        //  also sets the current frame if the stack walker is refreshed.
        //
        private void EnsureCurrentStackWalker()
        {
            lock (m_stackLock)
            {
                if (m_stackWalker != null)
                {
                    return;
                }

                m_stackWalker = new FrameCache(m_threadMgr.FrameFactory.EnumerateFrames(this), this);

                // initialize the frame index to be the invalid index. -1 is a special value here.
                m_currentFrameIndex = -1;

                int idx = 0;

                try
                {
                    while (true)
                    {
                        MDbgFrame f = null;
                        try
                        {
                            // set m_currentFrame to first non-Internal frame
                            f = m_stackWalker.GetFrame(idx);
                        }
                        catch
                        {
                            // It is acceptable that the above might throw an exception, if the
                            // reason is that the OS thread is not in the dump.  This
                            // can happen because the CLR debugging API can notify us of managed
                            // threads whose OS counterpart has already been destroyed, and is thus
                            // no longer in the dump.  In such a case, just fall through and return
                            // without having found a current frame for this thread's stack walk.
                            // Otherwise, propagate the exception.

                            if (m_threadMgr.m_process.DumpReader == null)
                            {
                                // Not debugging a dump, so we wouldn't expect an exception here.
                                // Don't swallow
                                throw;
                            }

                            if (IsOSThreadPresentInDump())
                            {
                                // Looks like we're trying to get a stackwalk of a valid thread in the dump,
                                // meaning the exception that was thrown was a bad one.  Rethrow it.
                                throw;
                            }
                        }

                        if (f == null)
                        {
                            // Hit the end of the stack without finding a frame that we can set as the
                            // current frame. Should still be set to "no current frame"
                            Debug.Assert(m_currentFrameIndex == -1);
                            return;
                        }

                        // Skip InfoOnly frames.
                        if (!f.IsInfoOnly)
                        {
                            m_currentFrameIndex = idx;
                            return;
                        }
                        idx++;
                    }
                }
                catch (NotImplementedException)
                {
                    // If any of the stackwalking APIs are not implemented, then we have no
                    // stackwalker, and act like there's no current frame.
                }
            }
        }
コード例 #2
0
ファイル: Thread.cs プロジェクト: jeswin/BigBrother
 /// <summary>
 /// Clears the stack walker's frame cache, which will force the stack
 /// to be walked again with the next call that depends on the stack.
 /// </summary>
 public void InvalidateStackWalker()
 {
     lock (m_stackLock)
     {
         if (m_stackWalker != null)
         {
             m_stackWalker.Invalidate();
         }
         m_stackWalker = null;
     }
 }
コード例 #3
0
ファイル: Thread.cs プロジェクト: jeswin/BigBrother
        // The function verifies that the stackwalker for this thread is "current". The stack-walker will become
        // invalid when a debugger performs an operation that invalidats active stackwalkers. Examples of such
        // operations are:
        //  - calling Continue(), calling SetIP() or calling RefreshStack() methods.
        //
        //  If the current stack-walker is not current, a new stack-walker is created for the thread. The function
        //  also sets the current frame if the stack walker is refreshed.
        //
        private void EnsureCurrentStackWalker()
        {
            lock (m_stackLock)
            {
                if (m_stackWalker != null)
                {
                    return;
                }

                m_stackWalker = new FrameCache(m_threadMgr.FrameFactory.EnumerateFrames(this), this);

                // initialize the frame index to be the invalid index. -1 is a special value here.
                m_currentFrameIndex = -1;

                int idx = 0;

                try
                {
                    while (true)
                    {
                        MDbgFrame f = null;
                        try
                        {
                            // set m_currentFrame to first non-Internal frame
                            f = m_stackWalker.GetFrame(idx);
                        }
                        catch
                        {
                            // It is acceptable that the above might throw an exception, if the
                            // reason is that the OS thread is not in the dump.  This
                            // can happen because the CLR debugging API can notify us of managed
                            // threads whose OS counterpart has already been destroyed, and is thus
                            // no longer in the dump.  In such a case, just fall through and return
                            // without having found a current frame for this thread's stack walk.
                            // Otherwise, propagate the exception.

                            if (m_threadMgr.m_process.DumpReader == null)
                            {
                                // Not debugging a dump, so we wouldn't expect an exception here.
                                // Don't swallow
                                throw;
                            }

                            if (IsOSThreadPresentInDump())
                            {
                                // Looks like we're trying to get a stackwalk of a valid thread in the dump,
                                // meaning the exception that was thrown was a bad one.  Rethrow it.
                                throw;
                            }
                        }

                        if (f == null)
                        {
                            // Hit the end of the stack without finding a frame that we can set as the
                            // current frame. Should still be set to "no current frame"
                            Debug.Assert(m_currentFrameIndex == -1);
                            return;
                        }

                        // Skip InfoOnly frames.
                        if (!f.IsInfoOnly)
                        {
                            m_currentFrameIndex = idx;
                            return;
                        }
                        idx++;
                    }
                }
                catch (NotImplementedException)
                {
                    // If any of the stackwalking APIs are not implemented, then we have no
                    // stackwalker, and act like there's no current frame.
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// A function that returns the new MdbgFrame. The function is expected to be overriden by derived implementations.
        /// </summary>
        /// <param name="index">0 based index from top of the stack</param>
        /// <returns>frame from the stack</returns>
        protected override MDbgFrame GetFrameImpl(int index)
        {
            if (index < FrameCache.Count)
            {
                return(FrameCache[index]);
            }

            MDbgFrame frameToReturn;

            if (index == 0)
            {
                // special case the first frame
                frameToReturn = ReturnLeafFrame();
            }
            else
            {
                // use recursion...
                MDbgFrame prevFrame = GetFrameImpl(index - 1);
                if (prevFrame == null)
                {
                    throw new ArgumentException();
                }

                frameToReturn = GetFrameCaller(prevFrame);
                if (frameToReturn == null)
                {
                    // we need to get the next frame from the following chain

                    CorChain chain = GetFrameChain(prevFrame);
                    Debug.Assert(chain != null);
                    // 1. find next chain
                    while (true)
                    {
                        chain = chain.Caller;
                        if (chain == null)
                        {
                            break;
                        }

                        if (chain.IsManaged)
                        {
                            CorFrame f = chain.ActiveFrame;
                            if (f != null)
                            {
                                frameToReturn = new MDbgILFrame(Thread, f);
                                break;
                            }
                        }
                        else
                        {
                            frameToReturn = FillAndGetLeafFrameFromNativeChain(chain);
                            if (frameToReturn != null)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            // store and return frameToReturn
            if (frameToReturn != null)
            {
                Debug.Assert(FrameCache.Count >= index);
                if (FrameCache.Count == index)
                {
                    FrameCache.Add(frameToReturn);
                }
                else
                {
                    Debug.Assert(FrameCache[index] == frameToReturn, "List of frames pre-filled with incorrect frame");
                }
            }
            return(frameToReturn);
        }