Esempio n. 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()
        {
            if (m_stackWalker != null && m_stackWalker.IsUsable)
            {
                return;
            }

            m_stackWalker = m_threadMgr.FrameFactory.CreateStackWalker(this);

            // initialize the frame index to be the invalid index
            m_currentFrameIndex = -1;

            // set m_currentFrame to first non-virtual frame
            MDbgFrame f = m_stackWalker.GetFrame(0);

            if (f == null)
            {
                return;
            }

            // we have at least one frame, so set the frame index to 0
            m_currentFrameIndex = 0;
            while (f != null &&
                   f.IsInfoOnly)
            {
                f = f.NextUp;
                if (f != null)
                {
                    ++m_currentFrameIndex;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Moves the Current Frame up or down.
        /// </summary>
        /// <param name="down">Moves frame down if true, else up.</param>
        public void MoveCurrentFrame(bool down)
        {
            lock (m_stackLock)
            {
                MDbgFrame f = CurrentFrame;
                Debug.Assert(!f.IsInfoOnly);

                bool frameCanBeMoved;
                int  idx = m_currentFrameIndex;
                if (down)
                {
                    do
                    {
                        --idx;
                    }while (idx >= 0 && m_stackWalker.GetFrame(idx).IsInfoOnly);
                    frameCanBeMoved = (idx >= 0);
                }
                else
                {
                    do
                    {
                        ++idx;
                        f = m_stackWalker.GetFrame(idx);
                    } while (f != null && f.IsInfoOnly);
                    frameCanBeMoved = f != null;
                }
                if (!frameCanBeMoved)
                {
                    throw new MDbgException("Operation hit " + (down ? "bottom" : "top") + " of the stack.");
                }

                m_currentFrameIndex = idx;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Finds the leaf-most frame in the stack.
        /// </summary>
        /// <returns>the top-most frame in the stack</returns>
        protected MDbgFrame ReturnLeafFrame()
        {
            MDbgFrame leafFrame = null;

            CorChain c = null;

            try
            {
                c = Thread.CorThread.ActiveChain;
            }
            catch (System.Runtime.InteropServices.COMException ce)
            {
                // Sometimes we cannot get the callstack.  For example, the thread
                // may not be scheduled yet (CORDBG_E_THREAD_NOT_SCHEDULED),
                // or the CLR may be corrupt (CORDBG_E_BAD_THREAD_STATE).
                // In either case, we'll ignore the problem and return an empty callstack.
                Debug.Assert(ce.ErrorCode == (int)HResult.CORDBG_E_BAD_THREAD_STATE ||
                             ce.ErrorCode == (int)HResult.CORDBG_E_THREAD_NOT_SCHEDULED);
            }

            if (c != null)
            {
                if (!c.IsManaged)
                {
                    leafFrame = FillAndGetLeafFrameFromNativeChain(c);
                }

                if (leafFrame == null)
                {
                    // if we still have no frame, we'll get one from the managed code.
                    while (c != null &&
                           (!c.IsManaged || (c.IsManaged && c.ActiveFrame == null))
                           )
                    {
                        c = c.Caller;
                    }

                    if (c == null)
                    {
                        leafFrame = null;
                    }
                    else
                    {
                        Debug.Assert(c != null && c.IsManaged);
                        leafFrame = new MDbgILFrame(Thread, c.ActiveFrame);
                    }
                }
            }
            else
            {
                leafFrame = null;
            }

            return(leafFrame);
        }
Esempio n. 4
0
        /// <summary>
        /// Returns the caller of the frame.
        /// </summary>
        /// <param name="frame">frame to return the caller of</param>
        /// <returns>the caller of the frame or null if the frame is the last frame in the chain</returns>
        protected virtual MDbgFrame GetFrameCaller(MDbgFrame frame)
        {
            Debug.Assert(frame != null);

            CorFrame f = frame.CorFrame.Caller;

            if (f == null)
            {
                return(null);
            }

            return(new MDbgILFrame(Thread, f));
        }
Esempio n. 5
0
        /// <summary>
        /// The function returns the index of the frame in the stack.
        /// </summary>
        /// <param name="frame">A frame returned with call to GetFrame.</param>
        /// <returns>an index of the frame</returns>
        /// <remarks>
        /// If the frame passed in was not created with this StackWalker object the function
        /// throws an exception.
        /// </remarks>
        public int GetFrameIndex(MDbgFrame frame)
        {
            CheckUsability();

            if (m_frameCache != null)
            {
                for (int i = 0; i < m_frameCache.Count; ++i)
                {
                    if (m_frameCache[i] == frame)
                    {
                        return(i);
                    }
                }
            }

            throw new ArgumentException("Invalid frame");
        }
Esempio n. 6
0
        /// <summary>
        /// We want to be able to interleave native and internal frames together and also minimize the exposure of internal frames.
        /// This method takes the internal frame cache and interleaves them with the native frames returned from UnwindNativeFrames.  In this
        /// case, this function will merely return all of the internal frames since the interop extension isn't loaded.
        /// <param name="thread">current thread that we're creating the stackwalker on</param>
        /// <param name="internalFrameCache">the internal frame cache</param>
        /// <param name="nativeFrames">native frames returned from UnwindNativeFrames</param>
        /// <returns>enumeration of the interleaved internal and native MDbgFrames</returns>
        /// </summary>
        protected virtual IEnumerable <MDbgFrame> StitchInternalFrames(MDbgThread thread, IEnumerator <CorFrame> internalFrameCache, IEnumerable <MDbgFrame> nativeFrames)
        {
            if (internalFrameCache == null)
            {
                yield break;
            }

            MDbgFrame mf = null;

            // iterate through the internal frames
            internalFrameCache.Reset();
            while (internalFrameCache.MoveNext())
            {
                mf = thread.LookupFrame(internalFrameCache.Current);
                yield return(mf);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// The function returns the index of the frame in the stack.
        /// </summary>
        /// <param name="frame">A frame returned with call to GetFrame.</param>
        /// <returns>an index of the frame</returns>
        /// <remarks>
        /// If the frame passed in was not created with this StackWalker object the function
        /// throws an exception.
        /// </remarks>
        public int GetFrameIndex(MDbgFrame frame)
        {
            lock (m_leafLock)
            {
                CheckUsability();

                // We do not need to grow frame cache. If it's not already in the cache, it can't be valid.
                if (m_frameCache != null)
                {
                    for (int i = 0; i < m_frameCache.Count; ++i)
                    {
                        if (m_frameCache[i] == frame)
                        {
                            return(i);
                        }
                    }
                }

                throw new ArgumentException("Invalid frame");
            }
        }
Esempio n. 8
0
        bool IEnumerator.MoveNext()
        {
            if (m_currentFrame == null)
            {
                if (m_bottomFrame == null)
                {
                    return(false);
                }

                m_currentFrame = m_bottomFrame;
            }
            else
            {
                MDbgFrame f = m_currentFrame.NextUp;
                if (f == null)
                {
                    return(false);
                }
                m_currentFrame = f;
            }
            return(true);
        }
Esempio n. 9
0
        /// <summary>
        /// Function returns mdbg frame for the thred it was created for.
        /// </summary>
        /// <param name="index">index of the frame. The leaf-most frame is indexed with 0.</param>
        /// <returns>the object representing frame</returns>
        /// <remarks>
        /// When the stack has 10 frames, it returns the frame for indexes 0-9. It returns null
        /// for index 10 and throws otherwise.
        /// </remarks>
        public MDbgFrame GetFrame(int index)
        {
            lock (m_cacheLock)
            {
                CheckUsability();

                // Need to check for out-of-range
                if (index < 0)
                {
                    throw new ArgumentOutOfRangeException("index");
                }

                // Grow the cache until it is large enough to contain the index.
                // This should be the only place that calls IterateNextFrame().
                while (index >= InternalFrameCache.Count)
                {
                    MDbgFrame frame = IterateNextFrame();

                    InternalFrameCache.Add(frame);

                    // Check if the index is asking for more frames than the callstack has.
                    if (frame == null)
                    {
                        if (index > InternalFrameCache.Count)
                        {
                            throw new ArgumentOutOfRangeException("index", index, "Callstack only has " + InternalFrameCache.Count + " frame(s).");
                        }
                    }
                    else
                    {
                        // Ensure that that the same frame is not added multiple times.
                        // This can cause infinite loops in the stackwalker because each frame
                        // must have a unique index.
                        Debug.Assert(GetFrameIndex(frame) == index, "FrameFactory " + m_frameEnum.ToString() + " added same frame (" + frame.ToString() + ") multiple times.");
                    }
                }
                return(InternalFrameCache[index]);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Gets the variables available for inspection in the supplied MDbgFrame.
        /// Currently does nothing with those variables. Left here for future use.
        /// </summary>
        /// <param name="frame">The frame to get the local variables from.</param>
        private IEnumerable<LocalVariableInformation> GetScopeVariables(MDbgFrame frame)
        {
            frame.Function.GetArguments(frame);

            LocalVariableProcessor processor = new LocalVariableProcessor();

            processor.AddLocalValues(frame.Function.GetActiveLocalVars(frame));
            processor.AddLocalValues(frame.Function.GetArguments(frame));

            return processor.LocalVariables;
        }
Esempio n. 11
0
 public FramePair(MDbgFrame f, String s)
 {
     m_frame = f;
     m_displayString = s;
 }
Esempio n. 12
0
 public CorValue ParseExpression2(string value, MDbgProcess process, MDbgFrame scope)
 {
     if (value.Length == 0)
     {
         return null;
     }
     CorGenericValue result;
     if (TryCreatePrimitiveValue(value, out result))
     {
         //value is a primitive type
         return result;
     }
     if (value[0] == '"' && value[value.Length - 1] == '"')
     {
         //value is a string
         return CreateString(value);
     }
     //value is some variable
     Debug.Assert(process != null);
     MDbgValue var = process.ResolveVariable(value, scope);
     return (var == null ? null : var.CorValue);
 }
Esempio n. 13
0
 public MDbgFrameEnumerable(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Esempio n. 14
0
 internal MDbgFrameEnumerator(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Esempio n. 15
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);
        }
Esempio n. 16
0
        public static StackSample GetThreadStacks(MDbgThread t, bool withArgs = false, bool originFirst = false)
        {
            //Console.WriteLine("Callstack for Thread {0}", t.Id.ToString());
            StackSample sample = new StackSample { ThreadId = t.Id, Time = DateTime.Now };
            MDbgFrame[] frames = new MDbgFrame[0];
            try
            {
                frames = t.Frames.ToArray();
            }
            catch (Exception ex)
            {
                DebuggerUtils.HandleExceptionSilently(ex);
            }

            foreach (MDbgFrame f in frames)
            {
                try
                {
                    string frame = GetFrameString(f, withArgs).Trim();
                    if (string.IsNullOrWhiteSpace(frame))
                        frame = "[Missing frame]";

                    if (originFirst)
                        sample.CallStack.Insert(0, frame);
                    else
                        sample.CallStack.Add(frame);
                }
                catch (Exception ex)
                {
                    DebuggerUtils.HandleExceptionSilently(ex);
                }
            }

            return sample;
        }
Esempio n. 17
0
 public MDbgFrameEnumerable(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Esempio n. 18
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  Support for printing local printing variables
        //
        //////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Gets an Array of MDbgValues for the Active Local Vars in the given frame.
        /// </summary>
        /// <param name="managedFrame">The Frame to look in.</param>
        /// <returns>The MDbgValue[] Active Local Valiables.</returns>
        public MDbgValue[] GetActiveLocalVars(MDbgFrame managedFrame)
        {
            Debug.Assert(managedFrame != null);
            if (managedFrame == null)
                throw new ArgumentException();

            CorFrame frame = managedFrame.CorFrame;

            // we only support this, when the frame is our function
            Debug.Assert(frame.FunctionToken == m_function.Token);
            if (!(frame.FunctionToken == m_function.Token))
                throw new ArgumentException();

            EnsureIsUpToDate();

            if (!m_haveSymbols)
            {
                // if we don't have symbols -- we'll print local variables as (loca1_0,local_1,local_2,...)
                // to give them names consistent with ILasm.
                int c = frame.GetLocalVariablesCount();
                if (c < 0)
                    c = 0;                                    // in case we cannot get locals,
                // we'll hide them.
                MDbgValue[] locals = new MDbgValue[c];
                for (int i = 0; i < c; ++i)
                {
                    CorValue arg = null;
                    try
                    {
                        arg = frame.GetLocalVariable(i);
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        if (e.ErrorCode != (int)Microsoft.Samples.Debugging.CorDebug.HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                            throw;
                    }
                    locals[i] = new MDbgValue(m_module.Process, "local_" + (i), arg);
                }
                return locals;
            }

            uint ip;
            CorDebugMappingResult mappingResult;
            frame.GetIP(out ip, out mappingResult);

            ArrayList al = new ArrayList();
            ISymbolScope scope = SymMethod.RootScope;
            AddLocalVariablesToList(frame, (int)ip, al, scope);

            return (MDbgValue[])al.ToArray(typeof(MDbgValue));
        }
Esempio n. 19
0
        // Helper to parse args to get a value for a GC handle.
        //
        // Syntax for gchandle. Ultimately need to compute an address.
        //  gchandle(var) where var is System.Runtime.InteropServices.GCHandle, address=var.m_handle
        //  gchandle(integer) where address =integer
        //  gchandle(var, offset) where var is a valuetype, then we do address= (IntPtr*) (&var + offset*sizeof(IntPtr))
        internal MDbgValue ParseGCHandleArgs(string stName, string[] args, MDbgFrame scope)
        {
            if (args.Length != 1 && args.Length != 2)
            {
                throw new MDbgException("Wrong number of args to gchandle function.");
            }

            string stVarBase = args[0];
            MDbgValue varBase = ResolveVariable(stVarBase, scope);
            //MDbgValue varBase = Shell.ExpressionParser.ParseExpression(stVarBase,this, scope);

            IntPtr add;

            if (args.Length == 2)
            {
                if (varBase == null)
                {
                    throw new MDbgException("Can't resolve var '" + stVarBase + "'");
                }

                // Form: gchandle(var, offset)
                CorGenericValue gv = varBase.CorValue.CastToGenericValue();
                IntPtr[] ar = null;
                if (gv != null)
                {
                    ar = gv.GetValueAsIntPtrArray();
                }
                if (ar == null)
                {
                    throw new MDbgException("Variable '" + stVarBase + "' is not a value type.");
                }

                int offset = Int32.Parse(args[1], CultureInfo.InvariantCulture);
                add = ar[offset];
            }
            else
            {
                if (varBase != null)
                {
                    add = IntPtr.Zero;
                    // Form: gchandle(var)
                    if (varBase.TypeName != "System.Runtime.InteropServices.GCHandle")
                    {
                        throw new MDbgException("Variable is not of type \"System.Runtime.InteropServices.GCHandle\".");
                    }

                    foreach (MDbgValue field in varBase.GetFields())
                    {
                        if (field.Name == "m_handle")
                        {
                            int handleAddress = Int32.Parse(field.GetStringValue(0));
                            add = new IntPtr(handleAddress);
                            break;
                        }
                    }
                }
                else
                {
                    // Trying to resolve as a raw address now
                    // form: gchandle(integer)
                    int handleAddress;
                    if (!Int32.TryParse(stVarBase, out handleAddress))
                    {
                        throw new MDbgException("Couldn't recognize the argument as a variable name or address");
                    }
                    add = new IntPtr(handleAddress);
                }
            }

            CorReferenceValue result;

            try
            {
                result = this.CorProcess.GetReferenceValueFromGCHandle(add);
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                if (e.ErrorCode == (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    throw new MDbgException("Invalid handle address.");
                }
                else
                {
                    throw;
                }
            }
            MDbgValue var = new MDbgValue(this, stName, result);
            return var;
        }
Esempio n. 20
0
 /// <summary>
 /// Return the chain the frame belongs to.
 /// </summary>
 /// <param name="frame">frame created by this stackwalker</param>
 /// <returns>The chain that owns the frame.</returns>
 protected virtual CorChain GetFrameChain(MDbgFrame frame)
 {
     Debug.Assert(frame != null);
     return(frame.CorFrame.Chain);
 }
Esempio n. 21
0
        public static string GetFrameString(MDbgFrame frame, bool withArgs = false)
        {
            try
            {
                if (withArgs)
                {
                    if (frame.IsManaged && !frame.Function.FullName.StartsWith("System."))
                        return string.Format("{0}({1})", frame.Function.FullName, string.Join(", ", frame.Function.GetArguments(frame).Select(arg => string.Format("{0} = {1}", arg.Name, arg.GetStringValue(false)))));
                }
                else
                {
                    if (frame.IsInfoOnly)
                        return null;

                    string retVal = frame.Function.FullName + " (";
                    foreach (MDbgValue value2 in frame.Function.GetArguments(frame))
                    {
                        retVal += value2.TypeName + ", ";
                    }
                    retVal = retVal.TrimEnd(", ".ToCharArray()) + ")";
                    return retVal;
                }
                //return frame.Function.FullName;
            }
            catch (Exception ex)
            {
                DebuggerUtils.HandleExceptionSilently(ex);
            }
            return null;
        }
Esempio n. 22
0
        /// <summary>
        /// The function returns the index of the frame in the stack.
        /// </summary>
        /// <param name="frame">A frame returned with call to GetFrame.</param>
        /// <returns>an index of the frame</returns>
        /// <remarks>
        /// If the frame passed in was not created with this StackWalker object the function
        /// throws an exception.
        /// </remarks>
        public int GetFrameIndex(MDbgFrame frame)
        {
            CheckUsability();

            if (m_frameCache != null)
            {
                for (int i = 0; i < m_frameCache.Count; ++i)
                {
                    if (m_frameCache[i] == frame)
                    {
                        return i;
                    }
                }
            }

            throw new ArgumentException("Invalid frame");
        }
Esempio n. 23
0
        // Helper to get all the fields, including static fields and base types.
        private MDbgValue[] InternalGetFields()
        {
            List <MDbgValue> al = new List <MDbgValue>();

            //dereference && (unbox);
            CorValue value = Dereference(CorValue, null);

            if (value == null)
            {
                throw new MDbgValueException("null value");
            }
            Unbox(ref value);
            CorObjectValue ov = value.CastToObjectValue();

            CorType cType = ov.ExactType;

            CorFrame cFrame = null;

            if (Process.Threads.HaveActive)
            {
                // we need a current frame to display thread local static values
                if (Process.Threads.Active.HaveCurrentFrame)
                {
                    MDbgFrame temp = Process.Threads.Active.CurrentFrame;
                    while (temp != null && !temp.IsManaged)
                    {
                        temp = temp.NextUp;
                    }
                    if (temp != null)
                    {
                        cFrame = temp.CorFrame;
                    }
                }
            }

            MDbgModule classModule;

            // initialization
            CorClass corClass = ov.Class;

            classModule = Process.Modules.Lookup(corClass.Module);

            // iteration through class hierarchy
            while (true)
            {
                Type classType = classModule.Importer.GetType(corClass.Token);
                foreach (MetadataFieldInfo fi in classType.GetFields())
                {
                    CorValue fieldValue = null;
                    try
                    {
                        if (fi.IsLiteral)
                        {
                            fieldValue = null;
                            // for now we just hide the constant fields.
                            continue;
                        }
                        else if (fi.IsStatic)
                        {
                            if (cFrame == null)
                            {
                                // Without a frame, we won't be able to find static values.  So
                                // just skip this guy
                                continue;
                            }

                            fieldValue = cType.GetStaticFieldValue(fi.MetadataToken, cFrame);
                        }
                        else
                        {
                            // we are asuming normal field value
                            fieldValue = ov.GetFieldValue(corClass, fi.MetadataToken);
                        }
                    }
                    catch (COMException)
                    {
                        // we won't report any problems.
                    }
                    al.Add(new MDbgValue(Process, fi.Name, fieldValue));
                }
                cType = cType.Base;
                if (cType == null)
                {
                    break;
                }
                corClass    = cType.Class;
                classModule = Process.Modules.Lookup(corClass.Module);
            }

            return(al.ToArray());
        }
Esempio n. 24
0
        /// <summary>
        /// Returns the caller of the frame.
        /// </summary>
        /// <param name="frame">frame to return the caller of</param>
        /// <returns>the caller of the frame or null if the frame is the last frame in the chain</returns>
        protected virtual MDbgFrame GetFrameCaller(MDbgFrame frame)
        {
            Debug.Assert(frame != null);

            CorFrame f = frame.CorFrame.Caller;
            if (f == null)
            {
                return null;
            }

            return new MDbgILFrame(Thread, f);
        }
Esempio n. 25
0
        public IEnumerable <MDbgFrame> EnumerateFrames(MDbgThread thread)
        {
            MDbgFrame               frameToReturn = null;
            long                    pEndVal = Int64.MinValue;
            CorStackWalk            m_v3StackWalk = thread.CorThread.CreateStackWalk(CorStackWalkType.ExtendedV3StackWalk);
            INativeContext          ctxUnmanagedChain = null, currentCtx = null;
            IEnumerable <MDbgFrame> nFrames;
            List <CorFrame>         iFrameCache = new List <CorFrame>(); //storage cache for internal frames

            // we need to call MoveNext() to make the enumerator valid
            while ((m_v3StackWalk != null) && (m_v3StackWalk.MoveNext()))
            {
                CorFrame frame = m_v3StackWalk.Current;

                if (frame != null)
                {
                    // If we get a RuntimeUnwindableFrame, then the stackwalker is also stopped at a native
                    // stack frame, but it's a native stack frame which requires special unwinding help from
                    // the runtime. When a debugger gets a RuntimeUnwindableFrame, it should use the runtime
                    // to unwind, but it has to do inspection on its own. It can call
                    // ICorDebugStackWalk::GetContext() to retrieve the context of the native stack frame.
                    if (frame.FrameType != CorFrameType.RuntimeUnwindableFrame)
                    {
                        // check for an internal frame...if the internal frame happens to come after the last
                        // managed frame, any call to GetContext() will assert
                        if (frame.FrameType != CorFrameType.InternalFrame)
                        {
                            // we need to store the CONTEXT when we're at a managed frame, if there's an internal frame
                            // after this, then we'll need this CONTEXT
                            currentCtx = m_v3StackWalk.GetContext();
                        }
                        else if ((frame.FrameType == CorFrameType.InternalFrame) && (ctxUnmanagedChain != null))
                        {
                            // we need to check to see if this internal frame could have been sandwiched between
                            // native frames, this will be the case if ctxUnmanagedChain is not null

                            // we need to store ALL internal frames until we hit the next managed frame
                            iFrameCache.Add(frame);
                            continue;
                        }
                        // else we'll use the 'stored' currentCtx if we're at an InternalFrame

                        pEndVal = Int64.MaxValue;
                        if (currentCtx != null)
                        {
                            pEndVal = currentCtx.StackPointer.ToInt64();
                        }

                        //check to see if we have native frames to unwind
                        nFrames = UnwindNativeFrames(thread, ctxUnmanagedChain, pEndVal);

                        foreach (MDbgFrame fr in StitchInternalFrames(thread, iFrameCache.GetEnumerator(), nFrames))
                        {
                            yield return(fr);
                        }

                        //clear out the CONTEXT and native frame cache
                        ctxUnmanagedChain = null;
                        nFrames           = null;
                        iFrameCache.Clear();

                        //return the managed frame
                        frameToReturn = thread.LookupFrame(frame);
                        yield return(frameToReturn);
                    }
                    else
                    {
                        continue;
                    }
                }
                // If we don't get a frame, then the stackwalker is stopped at a native stack frame.
                else
                {
                    // we've hit a native frame, we need to store the CONTEXT
                    ctxUnmanagedChain = m_v3StackWalk.GetContext();

                    //we need to invalidate the currentCtx since it won't be valid on the next loop iteration
                    currentCtx = null;
                }
            } //end while

            // we may have native frames at the end of the stack
            nFrames = UnwindNativeFrames(thread, ctxUnmanagedChain, Int64.MaxValue);


            foreach (MDbgFrame frame in StitchInternalFrames(thread, iFrameCache.GetEnumerator(), nFrames))
            {
                yield return(frame);
            }

            nFrames           = null;
            ctxUnmanagedChain = null;

            // End of stackwalk. Return null as sentinel.
            yield return(null);
        }
Esempio n. 26
0
 /// <summary>
 /// Return the chain the frame belongs to.
 /// </summary>
 /// <param name="frame">frame created by this stackwalker</param>
 /// <returns>The chain that owns the frame.</returns>
 protected virtual CorChain GetFrameChain(MDbgFrame frame)
 {
     Debug.Assert(frame != null);
     return frame.CorFrame.Chain;
 }
Esempio n. 27
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  Support for printing local printing variables
        //
        //////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Gets an Array of MDbgValues for the Active Local Vars in the given frame.
        /// </summary>
        /// <param name="managedFrame">The Frame to look in.</param>
        /// <returns>The MDbgValue[] Active Local Valiables.</returns>
        public MDbgValue[] GetActiveLocalVars(MDbgFrame managedFrame)
        {
            Debug.Assert(managedFrame != null);
            if (managedFrame == null)
            {
                throw new ArgumentException();
            }

            CorFrame frame = managedFrame.CorFrame;

            // we only support this, when the frame is our function
            Debug.Assert(frame.FunctionToken == m_function.Token);
            if (!(frame.FunctionToken == m_function.Token))
            {
                throw new ArgumentException();
            }

            EnsureIsUpToDate();

            if (!m_haveSymbols)
            {
                // if we don't have symbols -- we'll print local variables as (loca1_0,local_1,local_2,...)
                // to give them names consistent with ILasm.
                int c = frame.GetLocalVariablesCount();
                if (c < 0)
                {
                    c = 0;                                                        // in case we cannot get locals,
                }
                // we'll hide them.
                MDbgValue[] locals = new MDbgValue[c];
                for (int i = 0; i < c; ++i)
                {
                    CorValue arg = null;
                    try
                    {
                        arg = frame.GetLocalVariable(i);
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        if (e.ErrorCode != (int)Microsoft.Samples.Debugging.CorDebug.HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                        {
                            throw;
                        }
                    }
                    locals[i] = new MDbgValue(m_module.Process, "local_" + (i), arg);
                }
                return(locals);
            }

            uint ip;
            CorDebugMappingResult mappingResult;

            frame.GetIP(out ip, out mappingResult);

            ArrayList    al    = new ArrayList();
            ISymbolScope scope = SymMethod.RootScope;

            AddLocalVariablesToList(frame, (int)ip, al, scope);

            return((MDbgValue[])al.ToArray(typeof(MDbgValue)));
        }
Esempio n. 28
0
        /// <summary>
        /// Gets an array of MDbgValues that are the Arguments to the Function in the given Frame.
        /// </summary>
        /// <param name="managedFrame">The Frame to use.</param>
        /// <returns>The MDbgValue[] Arguments.</returns>
        public MDbgValue[] GetArguments(MDbgFrame managedFrame)
        {
            Debug.Assert(managedFrame != null);
            if (managedFrame == null)
            {
                throw new ArgumentException();
            }

            CorFrame f = managedFrame.CorFrame;

            // we only support this, when the frame is our function
            Debug.Assert(f.FunctionToken == m_function.Token);
            if (!(f.FunctionToken == m_function.Token))
            {
                throw new ArgumentException();
            }

            EnsureIsUpToDate();

            ArrayList al = new ArrayList();
            int       c  = f.GetArgumentCount();

            if (c == -1)
            {
                throw new MDbgException("Could not get metainformation. (Jit tracking information not turned on)");
            }

            int i;

            for (i = 0; i < c; i++)
            {
                CorValue arg = null;
                try
                {
                    arg = f.GetArgument(i);
                }
                catch (System.Runtime.InteropServices.COMException e)
                {
                    if (e.ErrorCode != (int)Microsoft.Samples.Debugging.CorDebug.HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                    {
                        throw;
                    }
                }
                al.Add(new MDbgValue(m_module.Process, arg));
            }
            MDbgValue[] argArray = (MDbgValue[])al.ToArray(typeof(MDbgValue));

            MethodInfo mi = managedFrame.Function.MethodInfo;

            foreach (ParameterInfo pi in mi.GetParameters())
            {
                int pos = pi.Position;
                // ParameterInfo at Position 0 refers to the return type (eg. when it has an attribute applied)
                if (pos == 0)
                {
                    continue;
                }
                if (mi.IsStatic)
                {
                    pos--;
                }
                Debug.Assert(pos < c);
                argArray[pos].InternalSetName(pi.Name);
            }

            i = 0;
            foreach (MDbgValue v in argArray)
            {
                if (v.Name == null)
                {
                    if (i == 0 && !mi.IsStatic)
                    {
                        v.InternalSetName("this");
                    }
                    else
                    {
                        v.InternalSetName("unnamed_param_" + i);
                    }
                    i++;
                }
            }
            return(argArray);
        }
Esempio n. 29
0
 public MDbgValue ParseExpression(string variableName, MDbgProcess process, MDbgFrame scope)
 {
     Debug.Assert(process != null);
     return process.ResolveVariable(variableName, scope);
 }
Esempio n. 30
0
        /// <summary>
        /// The function returns the index of the frame in the stack.
        /// </summary>
        /// <param name="frame">A frame returned with call to GetFrame.</param>
        /// <returns>an index of the frame</returns>
        /// <remarks>
        /// If the frame passed in was not created with this StackWalker object the function
        /// throws an exception.
        /// </remarks>
        public int GetFrameIndex(MDbgFrame frame)
        {
            lock (m_leafLock)
            {
                CheckUsability();

                // We do not need to grow frame cache. If it's not already in the cache, it can't be valid.
                if (m_frameCache != null)
                {
                    for (int i = 0; i < m_frameCache.Count; ++i)
                    {
                        if (m_frameCache[i] == frame)
                        {
                            return i;
                        }
                    }
                }

                throw new ArgumentException("Invalid frame");
            }
        }
Esempio n. 31
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.
                }
            }
        }
Esempio n. 32
0
 internal MDbgFrameEnumerator(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Esempio n. 33
0
        private MDbgThread GetMainThread(MDbgProcess proc)
        {
            MDbgThread mainthread = null;
            foreach (MDbgThread thread in proc.Threads)
            {
                if (DebuggerUtils.CheckValidState(thread))
                {
                    MDbgFrame[] frames = new MDbgFrame[0];

                    try
                    {
                        frames = thread.Frames.ToArray();
                    }
                    catch { }

                    foreach (MDbgFrame f in frames)
                    {
                        string line = DebuggerUtils.GetFrameString(f);

                        if (line.Contains("System.Windows.Application.Run") ||
                            line.Contains("Program.Main") ||
                            line.Contains("System.Windows.Forms.Application.Run"))
                        {
                            mainthread = thread;
                            //m_intMainThreadId = thread.Id;
                            break;
                        }
                    }
                }
            }
            return mainthread;
        }
Esempio n. 34
0
        bool IEnumerator.MoveNext()
        {
            if (m_currentFrame == null)
            {
                if (m_bottomFrame == null)
                    return false;

                m_currentFrame = m_bottomFrame;
            }
            else
            {
                MDbgFrame f = m_currentFrame.NextUp;
                if (f == null)
                    return false;
                m_currentFrame = f;
            }
            return true;
        }
Esempio n. 35
0
 // Add item to list
 // 'stText' is what we display in the list box.
 // 'frame' is the underlying frame associated with the text. Can be null if there's no frame.
 void AddItem(string stText, MDbgFrame frame)
 {
     ListBox.ObjectCollection list = this.listBoxCallstack.Items;
     list.Add(new FramePair(frame, stText));
 }
Esempio n. 36
0
 void IEnumerator.Reset()
 {
     m_currentFrame = null;
 }
Esempio n. 37
0
        /// <summary>
        /// Gets an array of MDbgValues that are the Arguments to the Function in the given Frame.
        /// </summary>
        /// <param name="managedFrame">The Frame to use.</param>
        /// <returns>The MDbgValue[] Arguments.</returns>
        public MDbgValue[] GetArguments(MDbgFrame managedFrame)
        {
            Debug.Assert(managedFrame != null);
            if (managedFrame == null)
                throw new ArgumentException();

            CorFrame f = managedFrame.CorFrame;

            // we only support this, when the frame is our function
            Debug.Assert(f.FunctionToken == m_function.Token);
            if (!(f.FunctionToken == m_function.Token))
                throw new ArgumentException();

            EnsureIsUpToDate();

            ArrayList al = new ArrayList();
            int c = f.GetArgumentCount();
            if (c == -1)
                throw new MDbgException("Could not get metainformation. (Jit tracking information not turned on)");

            int i;
            for (i = 0; i < c; i++)
            {
                CorValue arg = null;
                try
                {
                    arg = f.GetArgument(i);
                }
                catch (System.Runtime.InteropServices.COMException e)
                {
                    if (e.ErrorCode != (int)Microsoft.Samples.Debugging.CorDebug.HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                        throw;
                }
                al.Add(new MDbgValue(m_module.Process, arg));
            }
            MDbgValue[] argArray = (MDbgValue[])al.ToArray(typeof(MDbgValue));

            MethodInfo mi = managedFrame.Function.MethodInfo;
            foreach (ParameterInfo pi in mi.GetParameters())
            {
                int pos = pi.Position;
                // ParameterInfo at Position 0 refers to the return type (eg. when it has an attribute applied)
                if (pos == 0)
                    continue;
                if (mi.IsStatic)
                    pos--;
                Debug.Assert(pos < c);
                argArray[pos].InternalSetName(pi.Name);
            }

            i = 0;
            foreach (MDbgValue v in argArray)
                if (v.Name == null)
                {
                    if (i == 0 && !mi.IsStatic)
                        v.InternalSetName("this");
                    else
                        v.InternalSetName("unnamed_param_" + i);
                    i++;
                }
            return argArray;
        }
Esempio n. 38
0
        /// <summary>
        /// Resolves a Variable name in a given scope.
        /// </summary>
        /// <param name="variableName">The name of the variable to resolve.</param>
        /// <param name="scope">The MDbgFrame to look in for that variable.</param>
        /// <returns>The MDbgValue that the given variable has in the given scope.</returns>
        public MDbgValue ResolveVariable(string variableName, MDbgFrame scope)
        {
            Debug.Assert(variableName != null);
            Debug.Assert(scope != null);

            // variableName should have this form:
            // [[module][#<appdomain>]!][(([namespace.]+)<type.>)|.]variable([.field]*)

            // Syntax in BNF form:
            //
            // Expr --> module_scope '!' var_expr
            //         | var_expr
            // module_scope --> <module name>  // as determined by Modules.Lookup
            // var_expr --> var_root
            //            | var_expr '.' <id:field>
            //            | var_expr '[' <integer> ']'
            // var_root --> psuedo_var | local_var | parameter_var | global_var | static_class_var\
            //            | 'gchandle(' ... ')' // see ParseGCHandleArgs
            // psuedo_var --> '$' <id>   // as determined by DebuggerVars.HaveVariable
            // local_var --> <id> // as determined by f.GetActiveLocalVars
            // parameter_var --> <id> // as determined by f.GetArguments
            // global_var --> <id> // as determined by fields on global token in each module
            // static_class_var --> (<id:namespace> '.')* <id:class> '.' <id:static field>

            MDbgModule variableModule;          // name of the module we should look into for variable resolution
            // will contain null, if no module was specified
            { // limit scope of moduleVar
                string[] moduleVar = variableName.Split(new char[] { '!' }, 2);
                Debug.Assert(moduleVar != null);
                if (moduleVar.Length > 2)
                {
                    throw new MDbgException("Illegal variable syntax.");
                }
                else if (moduleVar.Length == 2)
                {
                    variableModule = Modules.Lookup(moduleVar[0]);
                    variableName = moduleVar[1];
                    if (variableModule == null)
                        throw new MDbgException("Module not found");
                }
                else
                    variableModule = null;
            }

            // lookup 1st part
            MDbgValue var = null;
            int nextPart = 0;

            // Check for predicates
            if (variableName.StartsWith("gchandle("))
            {
                string stName;
                string[] args;
                GetExpressionFunctionArgs(ref variableName, out stName, out args);
                nextPart = 1;

                var = this.ParseGCHandleArgs(stName, args, scope);
            } // end gchandle

            string[] nameParts = variableName.Split(new char[] { '.', '[' });

            Debug.Assert(nameParts.Length >= 1);  // there must be at least one part.

            if (var != null)
            {
                // already resolved, no extra work to do.
            }

            // Let's check if we are asking for debugger var. Those vars are prefixed with $.
            // if yes, return the var.
            else if (variableName.StartsWith("$")
               && variableModule == null          // debugger vars cannot have module specifier
               )
            {
                string varName = nameParts[nextPart];
                Debug.Assert(varName.StartsWith("$"));

                if (DebuggerVars.HaveVariable(nameParts[nextPart]))
                {
                    MDbgDebuggerVar dv = DebuggerVars[nameParts[0]];
                    var = new MDbgValue(this, dv.Name, dv.CorValue);
                }
                else
                    var = null;
                nextPart++;
            }
            else
            {
                ArrayList vars = new ArrayList();
                {  // fill up vars with locals+arguments
                    MDbgFunction f = scope.Function;
                    MDbgValue[] vals = f.GetActiveLocalVars(scope);
                    if (vals != null)
                        vars.AddRange(vals);

                    vals = f.GetArguments(scope);
                    if (vals != null)
                        vars.AddRange(vals);
                }

                // try to find a match in locals and arguments first
                foreach (MDbgValue v in vars)
                    if (v.Name == nameParts[nextPart])
                    {
                        var = v;
                        nextPart++;
                        break;
                    }

                // if no match for locals and arguments, look for globals and static class members
                if (var == null)
                {
                    // now let's try to resolve static var of form Namespace.namespace.typeName.var
                    bool bGlobal = (nameParts[nextPart].Length == 0);
                    if (bGlobal)
                        nextPart++;

                    foreach (MDbgModule m in this.Modules)
                    {
                        if (variableModule != null
                           && variableModule != m)
                            continue;                       // we're interested only in certain module

                        if (bGlobal)    // global variables
                        {
                            // nil type token is used to enum global static data members
                            MetadataType gType = (MetadataType)m.Importer.GetType(0);
                            FieldInfo[] gField = gType.GetFields(0);

                            for (int i = 0; i < gField.Length; i++)
                            {
                                if (nameParts[nextPart] == gField[i].Name)
                                {
                                    var = new MDbgValue(this, "." + gField[i].Name, scope.Function.Module.CorModule.GetGlobalVariableValue(gField[i].MetadataToken));
                                    nextPart++;
                                    break;
                                }
                            }

                            if (var != null)    // done if we find the first match in any module
                                break;
                        }
                        else    // static class members
                        {
                            System.Text.StringBuilder sb = new System.Text.StringBuilder();
                            sb.Append(nameParts[nextPart]);
                            for (int i = nextPart + 1; i < nameParts.Length; i++)
                            {
                                int typeToken = m.Importer.GetTypeTokenFromName(sb.ToString());
                                if (typeToken != CorMetadataImport.TokenNotFound)
                                {
                                    // we resolved type, let's try to get statics
                                    CorClass cl = m.CorModule.GetClassFromToken(typeToken);

                                    Type classType = m.Importer.GetType(cl.Token);
                                    foreach (MetadataFieldInfo fi in classType.GetFields())
                                    {
                                        if (fi.Name != nameParts[i])
                                            continue;

                                        if (fi.IsStatic)
                                        {
                                            sb.Append(".").Append(nameParts[i]);
                                            CorValue fieldValue = cl.GetStaticFieldValue(fi.MetadataToken, scope.CorFrame);
                                            var = new MDbgValue(this, sb.ToString(), fieldValue);
                                            nextPart = i + 1;
                                            goto FieldValueFound;   // done if we find the first match in any module
                                        }
                                    }
                                }
                                sb.Append(".").Append(nameParts[i]);
                            }
                        }
                    }
                FieldValueFound:
                    ;
                }
            };

            if (var != null)
            {
                // now try to resolve remaining parts.
                for (int i = nextPart; i < nameParts.Length; i++)
                {
                    string part = nameParts[i];
                    if (part.EndsWith("]"))
                    {
                        // it is probably array index
                        string[] indexStrings = part.Substring(0, part.Length - 1).Split(',');
                        Debug.Assert(indexStrings != null && indexStrings.Length > 0);
                        int[] indexes = new int[indexStrings.Length];
                        for (int j = 0; j < indexStrings.Length; ++j)
                            indexes[j] = Int32.Parse(indexStrings[j], CultureInfo.InvariantCulture);
                        var = var.GetArrayItem(indexes);
                    }
                    else
                    {
                        // we'll treat it as field name
                        var = var.GetField(part);
                    }
                }
            }
            return var;
        }