Exemplo n.º 1
0
 public O2MDbgVariable(MDbgValue mdbgValue, string _parentType, string _assemblyName)
 {
     IsProperty = false;
     parentType = _parentType;
     assemblyName = _assemblyName;
     name = mdbgValue.Name;
     try
     {
         value = mdbgValue.GetStringValue(false);
     }
     catch (Exception ex)
     {
         DI.log.ex(ex, "in O2MDbgVariable(MDbgValue mdbgValue), while trying to get value for: " + mdbgValue.Name);
     }
     type = mdbgValue.TypeName;
     complexType = mdbgValue.IsComplexType;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the specified Field.
        /// </summary>
        /// <param name="name">The Name of the Field to get.</param>
        /// <returns>The Value of the specified Field.</returns>
        public MDbgValue GetField(string name)
        {
            MDbgValue ret = null;

            foreach (MDbgValue v in GetFields())
            {
                if (v.Name.Equals(name))
                {
                    ret = v;
                    break;
                }
            }
            if (ret == null)
            {
                DI.log.error("from MDbgEngine: Field '" + name + "' not found.");
            }
            return(ret);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets Array Items.  This function can be called only on one dimensional arrays.
        /// </summary>
        /// <returns>An array of the values for the Array Items.</returns>
        public MDbgValue[] GetArrayItems()
        {
            if (!IsArrayType)
            {
                throw new MDbgValueException("Type is not array type");
            }

            CorDebug.CorValue value = Dereference(CorValue);

            CorDebug.CorArrayValue av = value.CastToArrayValue();
            int[] dims = av.GetDimensions();
            Debug.Assert(dims != null);

            var al = new ArrayList();

            Debug.Assert(av.Rank == 1);
            for (int i = 0; i < dims[0]; i++)
            {
                var v = new MDbgValue(Process, "[" + i + "]", av.GetElementAtPosition(i));
                al.Add(v);
            }
            return((MDbgValue[])al.ToArray(typeof(MDbgValue)));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the Array Item for the specified indexes
        /// </summary>
        /// <param name="indexes">Which indexes to get the Array Item for.</param>
        /// <returns>The Value for the given indexes.</returns>
        public MDbgValue GetArrayItem(params int[] indexes)
        {
            if (!IsArrayType)
                throw new MDbgValueException("Type is not array type");

            CorDebug.CorValue value = Dereference(CorValue);
            CorDebug.CorArrayValue av = value.CastToArrayValue();
            Debug.Assert(av != null);
            if (av.Rank != indexes.Length)
                throw new MDbgValueException("Invalid number of dimensions.");

            var sb = new StringBuilder("[");
            for (int i = 0; i < indexes.Length; ++i)
            {
                if (i != 0)
                    sb.Append(",");
                sb.Append(indexes[i]);
            }
            sb.Append("]");

            var v = new MDbgValue(Process, sb.ToString(), av.GetElement(indexes));
            return v;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets Array Items.  This function can be called only on one dimensional arrays.
        /// </summary>
        /// <returns>An array of the values for the Array Items.</returns>
        public MDbgValue[] GetArrayItems()
        {
            if (!IsArrayType)
                throw new MDbgValueException("Type is not array type");

            CorDebug.CorValue value = Dereference(CorValue);

            CorDebug.CorArrayValue av = value.CastToArrayValue();
            int[] dims = av.GetDimensions();
            Debug.Assert(dims != null);

            var al = new ArrayList();
            Debug.Assert(av.Rank == 1);
            for (int i = 0; i < dims[0]; i++)
            {
                var v = new MDbgValue(Process, "[" + i + "]", av.GetElementAtPosition(i));
                al.Add(v);
            }
            return (MDbgValue[]) al.ToArray(typeof (MDbgValue));
        }
Exemplo n.º 6
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));
        }
Exemplo n.º 7
0
        private string PrintObject(int indentLevel, CorDebug.CorObjectValue ov, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            // Print generics-aware type.
            string name = InternalUtil.PrintCorType(m_process, ov.ExactType);

            var txt = new StringBuilder();

            txt.Append(name);

            if (expandDepth > 0)
            {
                // we gather the field info of the class before we do
                // funceval since funceval requires running the debugger process
                // and this in turn can cause GC and invalidate our references.
                var expandedDescription = new StringBuilder();
                if (IsComplexType)
                {
                    foreach (MDbgValue v in GetFields())
                    {
                        expandedDescription.Append("\n").Append(IndentedString(indentLevel + 1, v.Name)).
                        Append("=").Append(IndentedBlock(indentLevel + 2,
                                                         v.GetStringValue(expandDepth - 1, false)));
                    }
                }

                if (ov.IsValueClass && canDoFunceval)
                // we could display even values for real Objects, but we will just show
                // "description" for valueclasses.
                {
                    CorDebug.CorClass cls      = ov.ExactType.Class;
                    CorMetadataImport importer = m_process.Modules.Lookup(cls.Module).Importer;
                    var mdType = importer.GetType(cls.Token) as MetadataType;

                    if (mdType.ReallyIsEnum)
                    {
                        txt.AppendFormat(" <{0}>", InternalGetEnumString(ov, mdType));
                    }
                    else if (m_process.IsRunning)
                    {
                        txt.Append(" <N/A during run>");
                    }
                    else
                    {
                        MDbgThread activeThread = m_process.Threads.Active;

                        CorDebug.CorValue     thisValue;
                        CorDebug.CorHeapValue hv = ov.CastToHeapValue();
                        if (hv != null)
                        {
                            // we need to pass reference value.
                            CorDebug.CorHandleValue handle = hv.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION);
                            thisValue = handle;
                        }
                        else
                        {
                            thisValue = ov;
                        }

                        try
                        {
                            CorDebug.CorEval eval = m_process.Threads.Active.CorThread.CreateEval();
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND,
                                                                         activeThread.CorThread);

                            MDbgFunction toStringFunc =
                                m_process.ResolveFunctionName(null, "System.Object", "ToString"
                                                              , thisValue.ExactType.Class.Module.Assembly.AppDomain);
                            Debug.Assert(toStringFunc != null);
                            // we should be always able to resolve ToString function.

                            eval.CallFunction(toStringFunc.CorFunction, new[] { thisValue });
                            m_process.Go();
                            do
                            {
                                m_process.StopEvent.WaitOne();
                                if (m_process.StopReason is EvalCompleteStopReason)
                                {
                                    CorDebug.CorValue cv = eval.Result;
                                    Debug.Assert(cv != null);
                                    var    mv      = new MDbgValue(m_process, cv);
                                    string valName = mv.GetStringValue(0);

                                    // just purely for esthetical reasons we 'discard' "
                                    if (valName.StartsWith("\"") && valName.EndsWith("\""))
                                    {
                                        valName = valName.Substring(1, valName.Length - 2);
                                    }

                                    txt.Append(" <").Append(valName).Append(">");
                                    break;
                                }
                                if ((m_process.StopReason is ProcessExitedStopReason) ||
                                    (m_process.StopReason is EvalExceptionStopReason))
                                {
                                    txt.Append(" <N/A cannot evaluate>");
                                    break;
                                }
                                // hitting bp or whatever should not matter -- we need to ignore it
                                m_process.Go();
                            } while (true);
                        }
                        catch (COMException e)
                        {
                            // Ignore canot copy a VC class error - Can't copy a VC with object refs in it.
                            if (e.ErrorCode != (int)CorDebug.HResult.CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS)
                            {
                                throw;
                            }
                        }
                        finally
                        {
                            // we need to resume all the threads that we have suspended no matter what.
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_RUN,
                                                                         activeThread.CorThread);
                        }
                    }
                }
                txt.Append(expandedDescription.ToString());
            }
            return(txt.ToString());
        }
Exemplo n.º 8
0
        public static void UnwrapGCHandleCmd(string arguments)
        {
            var ap = new ArgParser(arguments);
            if (ap.Count != 1)
            {
                WriteError(
                    "Wrong arguments, should be name or address of a \"System.Runtime.InteropServices.GCHandle\" object.");
                return;
            }

            long handleAdd = 0;

            // First try to resolve the argument as a variable in the current frame
            MDbgValue var = Debugger.Processes.Active.ResolveVariable(
                ap.AsString(0),
                Debugger.Processes.Active.Threads.Active.CurrentFrame);
            if (var != null)
            {
                if (var.TypeName != "System.Runtime.InteropServices.GCHandle")
                {
                    WriteError("Variable is not of type \"System.Runtime.InteropServices.GCHandle\".");
                    return;
                }

                foreach (MDbgValue field in var.GetFields())
                {
                    if (field.Name == "m_handle")
                    {
                        handleAdd = Int64.Parse(field.GetStringValue(0));
                        break;
                    }
                }
            }
            else
            {
                // Trying to resolve as a raw address now
                try
                {
                    handleAdd = ap.GetArgument(0).AsAddress;
                }
                catch (FormatException)
                {
                    WriteError("Couldn't recognize the argument as a variable name or address");
                    return;
                }
            }

            var add = new IntPtr(handleAdd);
            CorReferenceValue result;

            try
            {
                result = Debugger.Processes.Active.CorProcess.GetReferenceValueFromGCHandle(add);
            }
            catch (COMException e)
            {
                if (e.ErrorCode == (int) HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    WriteError("Invalid handle address.");
                    return;
                }
                else
                {
                    throw;
                }
            }

            CorValue v = result.Dereference();
            var mv = new MDbgValue(Debugger.Processes.Active, v);
            if (mv.IsComplexType)
            {
                WriteOutput(string.Format("GCHandle to <{0}>",
                                          InternalUtil.PrintCorType(Debugger.Processes.Active, v.ExactType)));

                // now print fields as well
                foreach (MDbgValue f in mv.GetFields())
                    WriteOutput(" " + f.Name + "=" + f.GetStringValue(0));
            }
            else
            {
                WriteOutput(string.Format("GCHandle to {0}", mv.GetStringValue(0)));
            }
        }
Exemplo n.º 9
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.º 10
0
 public O2MDbgVariable(MDbgValue mdbgValue, O2MDbgVariable _parentVariable)
     : this(mdbgValue, _parentVariable.parentType, _parentVariable.assemblyName)
 {
     parentVariable = _parentVariable;
 }
Exemplo n.º 11
0
        public static void PrintCmd(string arguments, O2Thread.FuncVoidT1<string> o2Callback)
        {
            const string debuggerVarsOpt = "d";
            const string noFuncevalOpt = "nf";
            const string expandDepthOpt = "r";

            var ap = new ArgParser(arguments, debuggerVarsOpt + ";" + noFuncevalOpt + ";" + expandDepthOpt + ":1");
            bool canDoFunceval = ! ap.OptionPassed(noFuncevalOpt);

            int? expandDepth = null; // we use optional here because
            // different codes bellow has different
            // default values.
            if (ap.OptionPassed(expandDepthOpt))
            {
                expandDepth = ap.GetOption(expandDepthOpt).AsInt;
                if (expandDepth < 0)
                    throw new MDbgShellException("Depth cannot be negative.");
            }

            MDbgFrame frame = CommandBase.Debugger.Processes.Active.Threads.Active.CurrentFrame;
            if (ap.OptionPassed(debuggerVarsOpt))
            {
                // let's print all debugger variables
                MDbgProcess p = CommandBase.Debugger.Processes.Active;
                foreach (MDbgDebuggerVar dv in p.DebuggerVars)
                {
                    var v = new MDbgValue(p, dv.CorValue);
                    CommandBase.WriteOutput(dv.Name + "=" + v.GetStringValue(expandDepth == null ? 0 : (int) expandDepth,
                                                                 canDoFunceval));
                }
            }
            else
            {
                if (ap.Count == 0)
                {
                    // get all active variables
                    MDbgFunction f = frame.Function;

                    var vars = new ArrayList();
                    MDbgValue[] vals = f.GetActiveLocalVars(frame);
                    if (vals != null)
                    {
                        vars.AddRange(vals);
                    }

                    vals = f.GetArguments(frame);
                    if (vals != null)
                    {
                        vars.AddRange(vals);
                    }
                    foreach (MDbgValue v in vars)
                    {
                        CommandBase.WriteOutput(v.Name + "=" + v.GetStringValue(expandDepth == null ? 0 : (int) expandDepth,
                                                                    canDoFunceval));
                    }
                }
                else
                {
                    // user requested printing of specific variables
                    for (int j = 0; j < ap.Count; ++j)
                    {
                        MDbgValue var = CommandBase.Debugger.Processes.Active.ResolveVariable(ap.AsString(j), frame);
                        if (var != null)
                        {
                            CommandBase.WriteOutput(ap.AsString(j) + "=" + var.GetStringValue(expandDepth == null
                                                                                      ? 1
                                                                                      : (int) expandDepth, canDoFunceval));
                        }
                        else
                        {
                            throw new MDbgShellException("Variable not found");
                        }
                    }
                }
            }
        }
Exemplo n.º 12
0
        public static void FuncEvalCmd(string arguments, IMDbgShell Shell, O2Thread.FuncVoidT1<string> execOnEval)
        {
            try
            {

                var activeProcess = DI.o2MDbg.ActiveProcess; //Debugger.Processes.Active
                const string appDomainOption = "ad";
                var ap = new ArgParser(arguments, appDomainOption + ":1");
                if (!(ap.Count >= 1))
                {
                    throw new MDbgShellException("Not Enough arguments");
                }


                // Currently debugger picks first function -- we have not implementing resolving overloaded functions.
                // Good example is Console.WriteLine -- there is 18 different types:
                // 1) [06000575] Void WriteLine()
                // 2) [06000576] Void WriteLine(Boolean)
                // 3) [06000577] Void WriteLine(Char)
                // 4) [06000578] Void WriteLine(Char[])
                // 5) [06000579] Void WriteLine(Char[], Int32, Int32)
                // 6) [0600057a] Void WriteLine(Decimal)
                // 7) [0600057b] Void WriteLine(Double)
                // 8) [0600057c] Void WriteLine(Single)
                // 9) [0600057d] Void WriteLine(Int32)
                // 10) [0600057e] Void WriteLine(UInt32)
                // 11) [0600057f] Void WriteLine(Int64)
                // 12) [06000580] Void WriteLine(UInt64)
                // 13) [06000581] Void WriteLine(Object)
                // 14) [06000582] Void WriteLine(String)
                // 15) [06000583] Void WriteLine(String, Object)
                // 16) [06000584] Void WriteLine(String, Object, Object)
                // 17) [06000585] Void WriteLine(String, Object, Object, Object)
                // 18) [06000586] Void WriteLine(String, Object, Object, Object, Object, ...)
                // 19) [06000587] Void WriteLine(String, Object[])
                //
                CorAppDomain appDomain;
                if (ap.OptionPassed(appDomainOption))
                {
                    MDbgAppDomain ad = activeProcess.AppDomains[ap.GetOption(appDomainOption).AsInt];
                    if (ad == null)
                    {
                        throw new ArgumentException("Invalid Appdomain Number");
                    }
                    appDomain = ad.CorAppDomain;
                }
                else
                {
                    appDomain = activeProcess.Threads.Active.CorThread.AppDomain;
                }

                MDbgFunction func = activeProcess.ResolveFunctionNameFromScope(ap.AsString(0), appDomain);
                if (null == func)
                {
                    throw new MDbgShellException(String.Format(CultureInfo.InvariantCulture, "Could not resolve {0}",
                                                               new Object[] {ap.AsString(0)}));
                }

                CorEval eval = activeProcess.Threads.Active.CorThread.CreateEval();

                // Get Variables
                var vars = new ArrayList();
                String arg;
                for (int i = 1; i < ap.Count; i++)
                {
                    arg = ap.AsString(i);

                    CorValue v = Shell.ExpressionParser.ParseExpression2(arg, activeProcess,
                                                                         activeProcess.Threads.Active.
                                                                             CurrentFrame);

                    if (v == null)
                    {
                        throw new MDbgShellException("Cannot resolve expression or variable " + ap.AsString(i));
                    }

                    if (v is CorGenericValue)
                    {
                        vars.Add(v);
                    }

                    else
                    {
                        CorHeapValue hv = v.CastToHeapValue();
                        if (hv != null)
                        {
                            // we cannot pass directly heap values, we need to pass reference to heap valus
                            CorReferenceValue myref =
                                eval.CreateValue(CorElementType.ELEMENT_TYPE_CLASS, null).CastToReferenceValue();
                            myref.Value = hv.Address;
                            vars.Add(myref);
                        }
                        else
                        {
                            vars.Add(v);
                        }
                    }
                }

                eval.CallFunction(func.CorFunction, (CorValue[]) vars.ToArray(typeof (CorValue)));
                activeProcess.Go().WaitOne();

                // now display result of the funceval
                if (!(activeProcess.StopReason is EvalCompleteStopReason))
                {
                    // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason
                    Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput,
                                         "Func-eval not fully completed and debuggee has stopped");
                    Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput,
                                         "Result of funceval won't be printed when finished.");
                }
                else
                {
                    eval = (activeProcess.StopReason as EvalCompleteStopReason).Eval;
                    Debug.Assert(eval != null);

                    CorValue cv = eval.Result;
                    if (cv != null)
                    {
                        var mv = new MDbgValue(activeProcess, cv);
                        if (execOnEval != null) // if this callback is set then execute 
                        {
                            execOnEval(mv.GetStringValue(1));                         
                            return;
                        }
                        Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "result = " + mv.GetStringValue(1));
                        if (cv.CastToReferenceValue() != null)
                            if (activeProcess.DebuggerVars.SetEvalResult(cv))
                                Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "results saved to $result");

                    }
                }               
            }
            catch (Exception ex)
            {
                DI.log.ex(ex, "in FuncEvalCmd");
            }
            if (execOnEval != null)                         // need to call this here so that the sync AutoResetEvent is set
                execOnEval(null);
        }
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  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.º 14
0
        private string PrintObject(int indentLevel, CorDebug.CorObjectValue ov, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            // Print generics-aware type.
            string name = InternalUtil.PrintCorType(m_process, ov.ExactType);

            var txt = new StringBuilder();
            txt.Append(name);

            if (expandDepth > 0)
            {
                // we gather the field info of the class before we do
                // funceval since funceval requires running the debugger process
                // and this in turn can cause GC and invalidate our references.
                var expandedDescription = new StringBuilder();
                if (IsComplexType)
                {
                    foreach (MDbgValue v in GetFields())
                    {
                        expandedDescription.Append("\n").Append(IndentedString(indentLevel + 1, v.Name)).
                            Append("=").Append(IndentedBlock(indentLevel + 2,
                                                             v.GetStringValue(expandDepth - 1, false)));
                    }
                }

                if (ov.IsValueClass && canDoFunceval)
                    // we could display even values for real Objects, but we will just show 
                    // "description" for valueclasses.
                {
                    CorDebug.CorClass cls = ov.ExactType.Class;
                    CorMetadataImport importer = m_process.Modules.Lookup(cls.Module).Importer;
                    var mdType = importer.GetType(cls.Token) as MetadataType;

                    if (mdType.ReallyIsEnum)
                    {
                        txt.AppendFormat(" <{0}>", InternalGetEnumString(ov, mdType));
                    }
                    else if (m_process.IsRunning)
                        txt.Append(" <N/A during run>");
                    else
                    {
                        MDbgThread activeThread = m_process.Threads.Active;

                        CorDebug.CorValue thisValue;
                        CorDebug.CorHeapValue hv = ov.CastToHeapValue();
                        if (hv != null)
                        {
                            // we need to pass reference value.
                            CorDebug.CorHandleValue handle = hv.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION);
                            thisValue = handle;
                        }
                        else
                            thisValue = ov;

                        try
                        {
                            CorDebug.CorEval eval = m_process.Threads.Active.CorThread.CreateEval();
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND,
                                                                         activeThread.CorThread);

                            MDbgFunction toStringFunc =
                                m_process.ResolveFunctionName(null, "System.Object", "ToString"
                                                              , thisValue.ExactType.Class.Module.Assembly.AppDomain);
                            Debug.Assert(toStringFunc != null);
                            // we should be always able to resolve ToString function.

                            eval.CallFunction(toStringFunc.CorFunction, new[] {thisValue});
                            m_process.Go();
                            do
                            {
                                m_process.StopEvent.WaitOne();
                                if (m_process.StopReason is EvalCompleteStopReason)
                                {
                                    CorDebug.CorValue cv = eval.Result;
                                    Debug.Assert(cv != null);
                                    var mv = new MDbgValue(m_process, cv);
                                    string valName = mv.GetStringValue(0);

                                    // just purely for esthetical reasons we 'discard' "
                                    if (valName.StartsWith("\"") && valName.EndsWith("\""))
                                        valName = valName.Substring(1, valName.Length - 2);

                                    txt.Append(" <").Append(valName).Append(">");
                                    break;
                                }
                                if ((m_process.StopReason is ProcessExitedStopReason) ||
                                    (m_process.StopReason is EvalExceptionStopReason))
                                {
                                    txt.Append(" <N/A cannot evaluate>");
                                    break;
                                }
                                // hitting bp or whatever should not matter -- we need to ignore it
                                m_process.Go();
                            } while (true);
                        }
                        catch (COMException e)
                        {
                            // Ignore canot copy a VC class error - Can't copy a VC with object refs in it.
                            if (e.ErrorCode != (int) CorDebug.HResult.CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS)
                                throw;
                        }
                        finally
                        {
                            // we need to resume all the threads that we have suspended no matter what.
                            m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_RUN,
                                                                         activeThread.CorThread);
                        }
                    }
                }
                txt.Append(expandedDescription.ToString());
            }
            return txt.ToString();
        }
Exemplo n.º 15
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.º 16
0
        private string PrintArray(int indentLevel, CorDebug.CorArrayValue av, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            var txt = new StringBuilder();
            txt.Append("array [");
            int[] dims = av.GetDimensions();
            Debug.Assert(dims != null);

            for (int i = 0; i < dims.Length; ++i)
            {
                if (i != 0)
                    txt.Append(",");
                txt.Append(dims[i]);
            }
            txt.Append("]");

            if (expandDepth > 0 && av.Rank == 1 && av.ElementType != CorElementType.ELEMENT_TYPE_VOID)
            {
                for (int i = 0; i < dims[0]; i++)
                {
                    // Arrays not starting with 0 are not implemented
                    var v = new MDbgValue(Process, av.GetElementAtPosition(i));
                    txt.Append("\n").Append(IndentedString(indentLevel + 1, "[" + i + "] = ")).
                        Append(IndentedBlock(indentLevel + 2,
                                             v.GetStringValue(expandDepth - 1, canDoFunceval)));
                }
            }
            return txt.ToString();
        }
Exemplo n.º 17
0
        public static void NewObjCmd(string arguments)
        {
            var ap = new ArgParser(arguments);

            string className = ap.AsString(0);
            MDbgFunction func = Debugger.Processes.Active.ResolveFunctionName(null, className, ".ctor",
                                                                              Debugger.Processes.Active.Threads.Active.
                                                                                  CorThread.AppDomain);
            if (null == func)
                throw new MDbgShellException(String.Format(CultureInfo.InvariantCulture, "Could not resolve {0}",
                                                           ap.AsString(0)));

            CorEval eval = Debugger.Processes.Active.Threads.Active.CorThread.CreateEval();

            var callArguments = new ArrayList();
            // parse the arguments to newobj
            int i = 1;
            while (ap.Exists(i))
            {
                string arg = ap.AsString(i);
                // this is a normal argument
                MDbgValue rsMVar = Debugger.Processes.Active.ResolveVariable(arg,
                                                                             Debugger.Processes.Active.Threads.Active.
                                                                                 CurrentFrame);
                if (rsMVar == null)
                {
                    // cordbg supports also limited literals -- currently only NULL & I4.
                    if (string.Compare(arg, "null", true) == 0)
                    {
                        callArguments.Add(eval.CreateValue(CorElementType.ELEMENT_TYPE_CLASS, null));
                    }
                    else
                    {
                        int v;
                        if (!Int32.TryParse(arg, out v))
                            throw new MDbgShellException(string.Format(CultureInfo.InvariantCulture,
                                                                       "Argument '{0}' could not be resolved to variable or number",
                                                                       arg));

                        CorGenericValue gv = eval.CreateValue(CorElementType.ELEMENT_TYPE_I4, null).CastToGenericValue();
                        Debug.Assert(gv != null);
                        gv.SetValue(v);
                        callArguments.Add(gv);
                    }
                }
                else
                {
                    callArguments.Add(rsMVar.CorValue);
                }
                ++i;
            }

            eval.NewParameterizedObject(func.CorFunction, null, (CorValue[]) callArguments.ToArray(typeof (CorValue)));
            Debugger.Processes.Active.Go().WaitOne();

            // now display result of the funceval
            if (! (Debugger.Processes.Active.StopReason is EvalCompleteStopReason))
            {
                // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason
                WriteOutput(MDbgOutputConstants.StdOutput,"Newobj command not fully completed and debuggee has stopped");
                WriteOutput(MDbgOutputConstants.StdOutput,"Result of Newobj won't be printed when finished.");
            }
            else
            {
                eval = (Debugger.Processes.Active.StopReason as EvalCompleteStopReason).Eval;
                Debug.Assert(eval != null);

                CorValue cv = eval.Result;
                if (cv != null)
                {
                    var mv = new MDbgValue(Debugger.Processes.Active, cv);
                    WriteOutput("result = " + mv.GetStringValue(1));
                    if (Debugger.Processes.Active.DebuggerVars.SetEvalResult(cv))
                        WriteOutput(MDbgOutputConstants.StdOutput,"results saved to $result");
                }
            }
            Shell.DisplayCurrentLocation();
        }