示例#1
0
        /// <summary>
        /// Recursively dereference the input value until we finally find a non-dereferenceable
        /// value.  Along the way, optionally build up a "ptr string" that shows the addresses
        /// we dereference, separated by "->".
        /// </summary>
        /// <param name="value">Value to dereference</param>
        /// <param name="ptrStringBuilder">StringBuilder if caller wants us to generate
        /// a "ptr string" (in which case we'll stick it there).  If caller doesn't want
        /// a ptr string, this can be null</param>
        /// <returns>CorValue we arrive at after dereferencing as many times as we can</returns>
        private CorValue Dereference(CorValue value, StringBuilder ptrStringBuilder)
        {
            while (true)
            {
                CorReferenceValue rv = value.CastToReferenceValue();
                if (rv == null)
                {
                    break; // not a reference
                }
                if (ptrStringBuilder != null)
                {
                    if (ptrStringBuilder.Length > 0)
                    {
                        ptrStringBuilder.Append("->");
                    }
                    ptrStringBuilder.Append("0x" + rv.Value.ToString("X", System.Globalization.CultureInfo.CurrentUICulture));
                }

                // Bail as soon as we hit a reference to NULL
                if (rv.IsNull)
                {
                    return(null);    // reference to null
                }
                CorValue newValue = null;
                try
                {
                    newValue = rv.Dereference();
                }
                catch (COMException ce)
                {
                    // Check for any errors that are expected
                    if (ce.ErrorCode != (int)HResult.CORDBG_E_VALUE_POINTS_TO_FUNCTION)
                    {
                        throw;  // some other error
                    }
                }

                if (newValue == null)
                {
                    break;  // couldn't dereference the reference (eg. void*)
                }
                value = newValue;
            }
            return(value);
        }
示例#2
0
        internal CorHandleValue GetHandle(CorValue val)
        {
            CorHandleValue handleVal = null;

            if (!handles.TryGetValue(val.Address, out handleVal))
            {
                handleVal = val.CastToHandleValue();
                if (handleVal == null)
                {
                    // Create a handle
                    CorReferenceValue refVal  = val.CastToReferenceValue();
                    CorHeapValue      heapVal = refVal.Dereference().CastToHeapValue();
                    handleVal = heapVal.CreateHandle(CorDebugHandleType.HANDLE_STRONG);
                }
                handles.Add(val.Address, handleVal);
            }
            return(handleVal);
        }
示例#3
0
 private CorValue Dereference(CorValue value)
 {
     while (true)
     {
         CorReferenceValue rv = value.CastToReferenceValue();
         if (rv == null)
         {
             break;                     // not a reference
         }
         if (rv.IsNull)
         {
             return(null);                       // reference to null
         }
         CorValue newValue = rv.Dereference();
         if (newValue == null)
         {
             break;                      // couldn't dereference the reference (eg. void*)
         }
         value = newValue;
     }
     return(value);
 }
示例#4
0
        private string MakePtrString(CorValue value)
        {
            StringBuilder sb = new StringBuilder();

            while (true)
            {
                CorReferenceValue rv = value.CastToReferenceValue();
                if (rv == null)
                {
                    break;                     // not a reference
                }
                if (sb.Length > 0)
                {
                    sb.Append("->");
                }
                sb.Append("0x" + rv.Value.ToString("X", System.Globalization.CultureInfo.CurrentUICulture));

                CorValue newValue = null;
                try
                {
                    newValue = rv.Dereference();
                }
                catch (COMException ce)
                {
                    if (ce.ErrorCode != (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                    {
                        throw;                          // some other error
                    }
                }

                if (newValue == null)
                {
                    break;                      // couldn't dereference the reference (eg. void* or invalid ref)
                }
                value = newValue;
            }

            return(sb.ToString());
        }
示例#5
0
        public static CorValue GetRealObject(EvaluationContext ctx, CorValue obj)
        {
            CorEvaluationContext cctx = (CorEvaluationContext)ctx;

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

            try {
                if (obj is CorStringValue)
                {
                    return(obj);
                }

                if (obj is CorGenericValue)
                {
                    return(obj);
                }

                if (obj is CorGenericValue)
                {
                    return(obj);
                }

                if (obj is CorArrayValue)
                {
                    return(obj);
                }

                CorArrayValue arrayVal = obj.CastToArrayValue();
                if (arrayVal != null)
                {
                    return(arrayVal);
                }

                CorReferenceValue refVal = obj.CastToReferenceValue();
                if (refVal != null)
                {
                    if (refVal.IsNull)
                    {
                        return(refVal);
                    }
                    else
                    {
                        cctx.Session.WaitUntilStopped();
                        return(GetRealObject(cctx, refVal.Dereference()));
                    }
                }

                cctx.Session.WaitUntilStopped();
                CorBoxValue boxVal = obj.CastToBoxValue();
                if (boxVal != null)
                {
                    return(Unbox(ctx, boxVal));
                }

                if (obj.ExactType.Type == CorElementType.ELEMENT_TYPE_STRING)
                {
                    return(obj.CastToStringValue());
                }

                if (CorMetadataImport.CoreTypes.ContainsKey(obj.Type))
                {
                    CorGenericValue genVal = obj.CastToGenericValue();
                    if (genVal != null)
                    {
                        return(genVal);
                    }
                }

                if (!(obj is CorObjectValue))
                {
                    return(obj.CastToObjectValue());
                }
            }
            catch {
                // Ignore
                throw;
            }
            return(obj);
        }
示例#6
0
        private string InternalGetValue(int indentLevel, int expandDepth, bool canDoFunceval)
        {
            Debug.Assert(expandDepth >= 0);

            CorValue value = this.CorValue;

            if (value == null)
            {
                return("<N/A>");
            }

            // Record the memory addresses if displaying them is enabled
            string        prefix        = String.Empty;
            StringBuilder ptrStrBuilder = null;

            if (m_process.m_engine.Options.ShowAddresses)
            {
                ptrStrBuilder = new StringBuilder();
            }

            try
            {
                value = Dereference(value, ptrStrBuilder);
            }
            catch (COMException ce)
            {
                if (ce.ErrorCode == (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    return(MakePrefixFromPtrStringBuilder(ptrStrBuilder) + "<invalid reference value>");
                }
                throw;
            }

            prefix = MakePrefixFromPtrStringBuilder(ptrStrBuilder);

            if (value == null)
            {
                return(prefix + "<null>");
            }

            Unbox(ref value);

            switch (value.Type)
            {
            case CorElementType.ELEMENT_TYPE_BOOLEAN:
            case CorElementType.ELEMENT_TYPE_I1:
            case CorElementType.ELEMENT_TYPE_U1:
            case CorElementType.ELEMENT_TYPE_I2:
            case CorElementType.ELEMENT_TYPE_U2:
            case CorElementType.ELEMENT_TYPE_I4:
            case CorElementType.ELEMENT_TYPE_U4:
            case CorElementType.ELEMENT_TYPE_I:
            case CorElementType.ELEMENT_TYPE_U:
            case CorElementType.ELEMENT_TYPE_I8:
            case CorElementType.ELEMENT_TYPE_U8:
            case CorElementType.ELEMENT_TYPE_R4:
            case CorElementType.ELEMENT_TYPE_R8:
            case CorElementType.ELEMENT_TYPE_CHAR:
            {
                object v = value.CastToGenericValue().GetValue();
                string result;

                IFormattable vFormattable = v as IFormattable;
                if (vFormattable != null)
                {
                    result = vFormattable.ToString(null, System.Globalization.CultureInfo.CurrentUICulture);
                }
                else
                {
                    result = v.ToString();
                }

                // let's put quotes around char values
                if (value.Type == CorElementType.ELEMENT_TYPE_CHAR)
                {
                    result = "'" + result + "'";
                }

                return(prefix + result);
            }

            case CorElementType.ELEMENT_TYPE_CLASS:
            case CorElementType.ELEMENT_TYPE_VALUETYPE:
                CorObjectValue ov = value.CastToObjectValue();
                return(prefix + PrintObject(indentLevel, ov, expandDepth, canDoFunceval));

            case CorElementType.ELEMENT_TYPE_STRING:
                CorStringValue sv = value.CastToStringValue();
                return(prefix + '"' + sv.String + '"');

            case CorElementType.ELEMENT_TYPE_SZARRAY:
            case CorElementType.ELEMENT_TYPE_ARRAY:
                CorArrayValue av = value.CastToArrayValue();
                return(prefix + PrintArray(indentLevel, av, expandDepth, canDoFunceval));

            case CorElementType.ELEMENT_TYPE_PTR:
                return(prefix + "<non-null pointer>");

            case CorElementType.ELEMENT_TYPE_FNPTR:
                return(prefix + "0x" + value.CastToReferenceValue().Value.ToString("X"));

            case CorElementType.ELEMENT_TYPE_BYREF:
            case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
            case CorElementType.ELEMENT_TYPE_OBJECT:
            default:
                return(prefix + "<printing value of type: " + value.Type + " not implemented>");
            }
        }
示例#7
0
        public CorValue VariableExpressionInvoke(ExpressionParsingResult info)
        {
            //based on MdbgCommands.SetCmd(string arguments)
            if (info.Instance == null)
            {
                throw new Exception("Cannot resolve variable ");
            }

            if (info.Arguments == null || !info.Arguments.Any())
            {
                throw new Exception("Cannot resolve arguments ");
            }

            // Arguments has to be in the form of variable=varName, variable=value or variable=(<type>)value,
            // where we use the ldasm naming convention (e.g. "int", "sbyte", "ushort", etc...) for <type>.
            // Example inputs: var=myInt, var=45, var=(long)45

            MDbgValue lsMVar = new MDbgValue(process, info.Instance);
            CorValue  val    = info.Arguments.First();

            CorGenericValue valGeneric        = val as CorGenericValue;
            bool            bIsReferenceValue = val is CorReferenceValue;

            if (lsMVar != null)
            {
                if (valGeneric != null)
                {
                    CorValue lsVar = lsMVar.CorValue;
                    if (lsVar == null)
                    {
                        throw new Exception("cannot set constant values to unavailable variables");
                    }

                    // val is a primitive value
                    CorGenericValue lsGenVal = lsVar.CastToGenericValue();
                    if (lsGenVal == null)
                    {
                        throw new Exception("cannot set constant values to non-primitive values");
                    }

                    try
                    {
                        // We want to allow some type coercion. Eg, casting between integer precisions.
                        lsMVar.Value = val; // This may do type coercion
                    }
                    catch (MDbgValueWrongTypeException)
                    {
                        throw new Exception(String.Format("Type mismatch. Can't convert from {0} to {1}", val.Type, lsGenVal.Type));
                    }
                }
                else if (bIsReferenceValue)
                {
                    //reget variable
                    lsMVar       = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame);
                    lsMVar.Value = val;
                }
                else
                {
                    if (val.CastToHeapValue() != null)
                    {
                        throw new Exception("Heap values should be assigned only to debugger variables");
                    }
                    if (val.CastToGenericValue() != null)
                    {
                        lsMVar.Value = val.CastToGenericValue();
                    }
                    else
                    {
                        lsMVar.Value = val.CastToReferenceValue();
                    }
                }
            }

            // as a last thing we do is to return new value of the variable
            lsMVar = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame);
            return(lsMVar.CorValue);
        }
示例#8
0
        private string InternalGetValue(int indentLevel, int expandDepth, bool canDoFunceval, string variableName, Dictionary <string, int> variablesToLog)
        {
            Debug.Assert(expandDepth >= 0);

            CorValue value = this.CorValue;

            if (value == null)
            {
                return("<N/A>");
            }

            // Record the memory addresses if displaying them is enabled
            string        prefix        = String.Empty;
            StringBuilder ptrStrBuilder = null;

            if (m_process.m_engine.Options.ShowAddresses)
            {
                ptrStrBuilder = new StringBuilder();
            }

            try
            {
                value = Dereference(value, ptrStrBuilder);
            }
            catch (COMException ce)
            {
                if (ce.ErrorCode == (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE)
                {
                    return(MakePrefixFromPtrStringBuilder(ptrStrBuilder) + "<invalid reference value>");
                }
                throw;
            }

            prefix = MakePrefixFromPtrStringBuilder(ptrStrBuilder);

            if (value == null)
            {
                return(prefix + "<null>");
            }

            Unbox(ref value);

            switch (value.Type)
            {
            case CorElementType.ELEMENT_TYPE_BOOLEAN:
            case CorElementType.ELEMENT_TYPE_I1:
            case CorElementType.ELEMENT_TYPE_U1:
            case CorElementType.ELEMENT_TYPE_I2:
            case CorElementType.ELEMENT_TYPE_U2:
            case CorElementType.ELEMENT_TYPE_I4:
            case CorElementType.ELEMENT_TYPE_U4:
            case CorElementType.ELEMENT_TYPE_I:
            case CorElementType.ELEMENT_TYPE_U:
            case CorElementType.ELEMENT_TYPE_I8:
            case CorElementType.ELEMENT_TYPE_U8:
            case CorElementType.ELEMENT_TYPE_R4:
            case CorElementType.ELEMENT_TYPE_R8:
            case CorElementType.ELEMENT_TYPE_CHAR:
            {
                if (variablesToLog == null)
                {
                }
                else if (!variablesToLog.Any(variable => variable.Key == variableName))
                {
                    return("[SKIP]");
                }

                object v = value.CastToGenericValue().GetValue();
                string result;

                IFormattable vFormattable = v as IFormattable;
                if (vFormattable != null)
                {
                    result = vFormattable.ToString(null, System.Globalization.CultureInfo.CurrentUICulture);
                }
                else
                {
                    result = v.ToString();
                }

                // let's put quotes around char values
                if (value.Type == CorElementType.ELEMENT_TYPE_CHAR)
                {
                    result = "'" + result + "'";
                }

                return(Loger.WriteThisToLog(variableName, prefix + result));
            }

            case CorElementType.ELEMENT_TYPE_CLASS:
            case CorElementType.ELEMENT_TYPE_VALUETYPE:
                CorObjectValue ov           = value.CastToObjectValue();
                var            objectString = PrintObject(indentLevel, ov, expandDepth, canDoFunceval, variableName, variablesToLog);
                string         objectPrint;

                if (objectString == "[SKIP]")
                {
                    objectPrint = "[SKIP]";
                }
                else
                {
                    objectPrint = prefix + objectString;
                    Loger.WriteThisToLog(variableName, objectPrint.Substring(0, objectPrint.IndexOf('\n') > -1 ? objectPrint.IndexOf('\n') : objectPrint.Length));
                }

                return(objectPrint);

            case CorElementType.ELEMENT_TYPE_STRING:
                if (variablesToLog == null)
                {
                }
                else if (!variablesToLog.Any(variable => variable.Key == variableName))
                {
                    return("[SKIP]");
                }
                CorStringValue sv = value.CastToStringValue();
                return(Loger.WriteThisToLog(variableName, $"{prefix}\"{sv.String}\""));

            case CorElementType.ELEMENT_TYPE_SZARRAY:
            case CorElementType.ELEMENT_TYPE_ARRAY:
                CorArrayValue av          = value.CastToArrayValue();
                var           arrayString = PrintArray(indentLevel, av, expandDepth, canDoFunceval, variableName, variablesToLog);
                string        arrayPrint;
                if (arrayString == "[SKIP]")
                {
                    arrayPrint = "[SKIP]";
                }
                else
                {
                    arrayPrint = prefix + arrayString;
                    Loger.WriteThisToLog(variableName, arrayPrint.Substring(0, arrayPrint.IndexOf('\n') > -1 ? arrayPrint.IndexOf('\n') : arrayPrint.Length));
                }
                return(arrayPrint);

            case CorElementType.ELEMENT_TYPE_PTR:
                return(Loger.WriteThisToLog(variableName, prefix + "<non-null pointer>"));;

            case CorElementType.ELEMENT_TYPE_FNPTR:
                return(Loger.WriteThisToLog(variableName, prefix + "0x" + value.CastToReferenceValue().Value.ToString("X")));

            case CorElementType.ELEMENT_TYPE_BYREF:
            case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
            case CorElementType.ELEMENT_TYPE_OBJECT:
            default:
                return(Loger.WriteThisToLog(variableName, prefix + "<printing value of type: " + value.Type + " not implemented>"));
            }
        }
示例#9
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);
            }
        }