// 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;
                }
            }
        }
        /// <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)
        {
            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;
        }
        /// <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 (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);
                DI.log.error("intenal MDbg error: Debug.Assert(ce.ErrorCode == (int) HResult.CORDBG_E_BAD_THREAD_STATE || ce.ErrorCode == (int) HResult.CORDBG_E_THREAD_NOT_SCHEDULED);");
                DI.log.ex(ce);
            }

            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);
        }
        /// <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));
        }
        /// <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");
        }
        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);
        }
Exemplo n.º 7
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 = CorProcess.GetReferenceValueFromGCHandle(add);
            }
            catch (COMException e)
            {
                if (e.ErrorCode == (int) HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    throw new MDbgException("Invalid handle address.");
                }
                else
                {
                    throw;
                }
            }
            var var = new MDbgValue(this, stName, result);
            return var;
        }
Exemplo 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;
        }
Exemplo n.º 9
0
 void IEnumerator.Reset()
 {
     m_currentFrame = null;
 }
Exemplo n.º 10
0
 internal MDbgFrameEnumerator(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Exemplo n.º 11
0
 public MDbgFrameEnumerable(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Exemplo n.º 12
0
 public MDbgFrameEnumerable(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
Exemplo n.º 13
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();

            var 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 (COMException e)
                {
                    if (e.ErrorCode != (int) HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                        throw;
                }
                al.Add(new MDbgValue(m_module.Process, arg));
            }
            var 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;
        }
 // 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.
 private void AddItem(string stText, MDbgFrame frame)
 {
     ListBox.ObjectCollection list = listBoxCallstack.Items;
     list.Add(new FramePair(frame, stText));
 }
Exemplo n.º 15
0
 internal MDbgFrameEnumerator(MDbgFrame bottomFrame)
 {
     m_bottomFrame = bottomFrame;
 }
        /// <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);
        }
Exemplo n.º 17
0
 public CorValue ParseExpression2(string value, MDbgProcess process, MDbgFrame scope)
 {
     if (value.Length == 0)
     {
         return null;
     }
     if (RepresentsPrimitiveValue(value))
     {
         //value is a primitive type
         return CreatePrimitiveValue(value);
     }
     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);
 }
Exemplo n.º 18
0
 public MDbgValue ParseExpression(string variableName, MDbgProcess process, MDbgFrame scope)
 {
     Debug.Assert(process != null);
     return process.ResolveVariable(variableName, scope);
 }
Exemplo n.º 19
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[] {'!'}, 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 = ParseGCHandleArgs(stName, args, scope);
            } // end gchandle

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

            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
            {
                var 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 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 
                            var 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
                        {
                            var sb = new 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);
                        var 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;
        }
Exemplo n.º 20
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);
        }
 public FramePair(MDbgFrame f, String s)
 {
     m_frame = f;
     m_displayString = s;
 }
Exemplo n.º 22
0
 void IEnumerator.Reset()
 {
     m_currentFrame = null;
 }
Exemplo n.º 23
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.
                var locals = new MDbgValue[c];
                for (int i = 0; i < c; ++i)
                {
                    CorValue arg = null;
                    try
                    {
                        arg = frame.GetLocalVariable(i);
                    }
                    catch (COMException e)
                    {
                        if (e.ErrorCode != (int) 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);

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

            return (MDbgValue[]) al.ToArray(typeof (MDbgValue));
        }
 /// <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);
 }
Exemplo n.º 25
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");
        }
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  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.
                var locals = new MDbgValue[c];
                for (int i = 0; i < c; ++i)
                {
                    CorValue arg = null;
                    try
                    {
                        arg = frame.GetLocalVariable(i);
                    }
                    catch (COMException e)
                    {
                        if (e.ErrorCode != (int)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);

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

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

            return((MDbgValue[])al.ToArray(typeof(MDbgValue)));
        }
Exemplo n.º 27
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;
 }
        /// <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();

            var 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 (COMException e)
                {
                    if (e.ErrorCode != (int)HResult.CORDBG_E_IL_VAR_NOT_AVAILABLE)
                    {
                        throw;
                    }
                }
                al.Add(new MDbgValue(m_module.Process, arg));
            }
            var 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);
        }