Beispiel #1
0
        public ExpressionParsingResult ParseExpression(string expression)
        {
            //the expression is either setter of method invoke
            var result = new ExpressionParsingResult();

            result.IsSetter   = expression.IsSetExpression();
            result.Expression = expression;

            int    bracketIndex = expression.IndexOfAny(new[] { '(', '=' });
            string methodName   = expression.Substring(0, bracketIndex).Trim();
            string args         = expression.Substring(bracketIndex).Replace("(", "").Replace(")", "").Replace("=", "").Trim();

            string[] methodParts = methodName.Split('.');

            if (methodParts.Length == 1 && result.IsSetter) //myVar=3
            {
                result.IsLocalVariable = true;
            }

            result.ExpressionValue = args;


            string reference;

            if (methodParts.Length == 1)
            {
                //varName
                reference = methodParts[0];
            }
            else
            {
                //<<TypeName>|<CodeReference>>.<MethodName>
                reference = string.Join(".", methodParts.Take(methodParts.Length - 1).ToArray());
            }

            try
            {
                if ((expression.IsInvokeExpression() || expression.IsSetExpression()) && methodParts.Length == 1)
                {
                    MDbgValue callingObject = process.ResolveVariable("this", process.Threads.Active.CurrentFrame);

                    var mName = methodParts[0];  //either instance or static (e.g. "do()")

                    MDbgFunction func = process.ResolveFunctionNameFromScope(mName);
                    if (func != null) //method call
                    {
                        result.IsLocalVariable = false;

                        if (func.MethodInfo.IsStatic) //static method call
                        {
                            result.Instance = null;
                            result.Member   = process.Threads.Active.CurrentFrame.Function.MethodInfo.DeclaringType.FullName + "." + mName;
                        }
                        else
                        {
                            result.Instance = callingObject.CorValue;
                            result.Member   = mName;
                        }
                    }
                    else //variable assignment
                    {
                        var variable = process.ResolveVariable(reference, process.Threads.Active.CurrentFrame);
                        if (variable != null)//local variable assignment
                        {
                            result.IsLocalVariable = true;
                            result.Instance        = variable.CorValue;
                            result.Member          = reference;
                        }
                        else
                        {
                            if (callingObject == null) //static member assignment
                            {
                                result.IsLocalVariable = false;
                                result.Instance        = null;
                                result.Member          = process.Threads.Active.CurrentFrame.Function.MethodInfo.DeclaringType.FullName + "." + mName;
                            }
                            else //instance member assignment
                            {
                                result.IsLocalVariable = false;
                                result.Instance        = callingObject.CorValue;
                                result.Member          = methodParts.Last();
                            }
                        }
                    }
                }
                else
                {
                    var instance = process.ResolveVariable(reference, process.Threads.Active.CurrentFrame);
                    if (instance != null)
                    {
                        result.Instance = instance.CorValue;
                        result.Member   = methodParts.Last();
                    }
                }
            }
            catch { }

            if (result.Instance == null && result.Member == null)
            {
                result.Member = methodName;
            }

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

            // Get Variables
            ArrayList vars = new ArrayList();
            String    arg;

            if (args.Length != 0)
            {
                foreach (var item in args.Split(','))
                {
                    arg = item.Trim();

                    CorValue v = process.m_engine.ParseExpression(arg, process, process.Threads.Active.CurrentFrame);

                    if (v == null)
                    {
                        throw new Exception("Cannot resolve expression or variable " + arg);
                    }

                    if (v is CorGenericValue)
                    {
                        vars.Add(v as CorValue);
                    }
                    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);
                        }
                    }
                }
            }

            result.Arguments = (CorValue[])vars.ToArray(typeof(CorValue));
            return(result);
        }
Beispiel #2
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);
        }
Beispiel #3
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);
            }
        }