public CorValue Invoke(string methodName, CorValue instance, params CorValue[] args) { var allArgs = new List <CorValue>(); if (instance != null) { allArgs.Add(instance); } allArgs.AddRange(args); MDbgFunction func = process.ResolveFunctionNameFromScope(methodName); if (null == func) { throw new Exception(String.Format(CultureInfo.InvariantCulture, "Could not resolve {0}", new Object[] { methodName })); } CorEval eval = process.Threads.Active.CorThread.CreateEval(); // Get Variables ArrayList vars = new ArrayList(); String arg; foreach (var v in allArgs) { 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); } } } eval.CallFunction(func.CorFunction, (CorValue[])vars.ToArray(typeof(CorValue))); return(GetResult()); }
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); }
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); } }