public static void SetValue(this CorValRef thisVal, EvaluationContext ctx, CorValRef val) { CorEvaluationContext cctx = (CorEvaluationContext)ctx; CorObjectAdaptor actx = (CorObjectAdaptor)ctx.Adapter; if (actx.IsEnum(ctx, thisVal.Val.ExactType) && !actx.IsEnum(ctx, val.Val.ExactType)) { ValueReference vr = actx.GetMember(ctx, null, thisVal, "value__"); vr.Value = val; // Required to make sure that var returns an up-to-date value object thisVal.IsValid = false; return; } CorReferenceValue s = thisVal.Val.CastToReferenceValue(); if (s != null) { CorReferenceValue v = val.Val.CastToReferenceValue(); if (v != null) { s.Value = v.Value; return; } } CorGenericValue gv = CorObjectAdaptor.GetRealObject(cctx, thisVal.Val) as CorGenericValue; if (gv != null) { gv.SetValue(ctx.Adapter.TargetObjectToObject(ctx, val)); } }
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()); }
/// <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); }
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); }
string GetThreadName(CorThread thread) { // From http://social.msdn.microsoft.com/Forums/en/netfxtoolsdev/thread/461326fe-88bd-4a6b-82a9-1a66b8e65116 try { CorReferenceValue refVal = thread.ThreadVariable.CastToReferenceValue(); if (refVal.IsNull) { return(string.Empty); } CorObjectValue val = refVal.Dereference().CastToObjectValue(); if (val != null) { Type classType = val.ExactType.GetTypeInfo(this); // Loop through all private instance fields in the thread class foreach (MetadataFieldInfo fi in classType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) { if (fi.Name == "m_Name") { CorReferenceValue fieldValue = val.GetFieldValue(val.Class, fi.MetadataToken).CastToReferenceValue(); if (fieldValue.IsNull) { return(string.Empty); } else { return(fieldValue.Dereference().CastToStringValue().String); } } } } } catch (Exception) { // Ignore } return(string.Empty); }
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); }
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()); }
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); }
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); } }