Beispiel #1
0
        void UpdateFrames_DbgThread()
        {
            dbgManager.Dispatcher.VerifyAccess();
            bool           raiseActiveFrameIndexChanged, raiseFramesChanged;
            DbgStackWalker stackWalker = null;

            DbgStackFrame[] newFrames = null;
            try {
                var thread = dbgManager.CurrentThread.Current;
                if (thread == null || thread.Process.State != DbgProcessState.Paused)
                {
                    newFrames = Array.Empty <DbgStackFrame>();
                }
                else
                {
                    stackWalker = thread.CreateStackWalker();
                    newFrames   = stackWalker.GetNextStackFrames(MaxShownFrames + 1);
                }
                lock (lockObj) {
                    if (frames.Length > 0)
                    {
                        dbgManager.Close(frames);
                    }
                    int newActiveFrameIndex = GetFrameIndex(newFrames);
                    // Always raise frames-changed event even if old and new arrays have 0 length.
                    raiseFramesChanged           = true;
                    raiseActiveFrameIndexChanged = newActiveFrameIndex != activeFrameIndex;

                    // Note that we keep the extra frame so we don't have to create a new array with one less
                    // frame. If we got MaxShownFrames+1 frames, it's not very likely that the last one in the
                    // array is actually the last frame.
                    // Another solution is to create a custom IList<DbgStackFrame> that hides the last one
                    // but that's not worth it.
                    frames           = newFrames;
                    readOnlyFrames   = newFrames.Length == 0 ? emptyFrames : new ReadOnlyCollection <DbgStackFrame>(newFrames);
                    activeFrameIndex = newActiveFrameIndex;
                    framesTruncated  = newFrames.Length > MaxShownFrames;
                }
            }
            finally {
                stackWalker?.Close();
                if (newFrames != null && frames != newFrames && newFrames.Length > 0)
                {
                    dbgManager.Close(newFrames);
                }
            }
            if (raiseFramesChanged || raiseActiveFrameIndexChanged)
            {
                FramesChanged?.Invoke(this, new FramesChangedEventArgs(raiseFramesChanged, raiseActiveFrameIndexChanged));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets the top stack frame or null if there's none
        /// </summary>
        /// <returns></returns>
        public DbgStackFrame GetTopStackFrame()
        {
            DbgStackWalker stackWalker = null;

            try {
                stackWalker = CreateStackWalker();
                var frames = stackWalker.GetNextStackFrames(1);
                Debug.Assert(frames.Length <= 1);
                return(frames.Length == 0 ? null : frames[0]);
            }
            finally {
                stackWalker?.Close();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Gets the first <paramref name="count"/> frames.
        /// The returned frame count can be less than <paramref name="count"/> if there's not enough frames available.
        /// </summary>
        /// <param name="count">Max number of frames to return</param>
        /// <returns></returns>
        public DbgStackFrame[] GetFrames(int count)
        {
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (count == 0)
            {
                return(Array.Empty <DbgStackFrame>());
            }
            DbgStackWalker stackWalker = null;

            try {
                stackWalker = CreateStackWalker();
                var frames = stackWalker.GetNextStackFrames(count);
                Debug.Assert(frames.Length <= count);
                return(frames);
            }
            finally {
                stackWalker?.Close();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Gets the first non-null frame location. This location must be <see cref="DbgCodeLocation.Close"/>'d
        /// by the caller.
        /// </summary>
        /// <param name="thread">Thread</param>
        /// <returns></returns>
        public static (DbgCodeLocation location, int frameIndex) GetFirstFrameLocation(DbgThread thread)
        {
            DbgStackWalker stackWalker = null;
            var            objsToFree  = new List <DbgObject>();

            try {
                stackWalker = thread.CreateStackWalker();
                objsToFree.Add(stackWalker);
                int frameIndex = 0;
                while (frameIndex < 20)
                {
                    // Usually the first frame contains a location and if not, the one after that.
                    var frames = stackWalker.GetNextStackFrames(2);
                    objsToFree.AddRange(frames);
                    if (frames.Length == 0)
                    {
                        break;
                    }
                    foreach (var frame in frames)
                    {
                        var location = frame.Location;
                        if (location != null)
                        {
                            return(location.Clone(), frameIndex);
                        }
                        frameIndex++;
                    }
                }
            }
            finally {
                if (objsToFree.Count > 0)
                {
                    thread.Process.DbgManager.Close(objsToFree);
                }
            }
            return(null, -1);
        }