internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, uint chainIndex, uint frameIndex) { this.process = thread.Process; this.thread = thread; this.appDomain = process.AppDomains[corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain()]; this.corILFrame = corILFrame; this.corILFramePauseSession = process.PauseSession; this.corFunction = corILFrame.GetFunction(); this.chainIndex = chainIndex; this.frameIndex = frameIndex; MetaDataImport metaData = thread.Process.Modules[corFunction.GetClass().GetModule()].MetaData; int methodGenArgs = metaData.EnumGenericParams(corFunction.GetToken()).Length; // Class parameters are first, then the method ones List<ICorDebugType> corGenArgs = ((ICorDebugILFrame2)corILFrame).EnumerateTypeParameters().ToList(); // Remove method parametrs at the end corGenArgs.RemoveRange(corGenArgs.Count - methodGenArgs, methodGenArgs); List<DebugType> genArgs = new List<DebugType>(corGenArgs.Count); foreach(ICorDebugType corGenArg in corGenArgs) { genArgs.Add(DebugType.CreateFromCorType(this.AppDomain, corGenArg)); } DebugType debugType = DebugType.CreateFromCorClass( this.AppDomain, null, corFunction.GetClass(), genArgs.ToArray() ); this.methodInfo = (DebugMethodInfo)debugType.GetMember(corFunction.GetToken()); }
/// <summary> /// Invokes RuntimeHelpers.GetHashCode on given value, that is a default hashCode ignoring user overrides. /// </summary> /// <param name="value">Valid value.</param> /// <returns>Hash code of the object in the debugee.</returns> public static int InvokeDefaultGetHashCode(this Value value) { if (hashCodeMethod == null || hashCodeMethod.Process.HasExited) { DebugType typeRuntimeHelpers = DebugType.CreateFromType(value.AppDomain, typeof(System.Runtime.CompilerServices.RuntimeHelpers)); hashCodeMethod = (DebugMethodInfo)typeRuntimeHelpers.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Static); if (hashCodeMethod == null) { throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode"); } } Value defaultHashCode = Eval.InvokeMethod(DebuggerHelpers.hashCodeMethod, null, new Value[]{value}); //MethodInfo method = value.Type.GetMember("GetHashCode", BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo; //string hashCode = value.InvokeMethod(method, null).AsString; return (int)defaultHashCode.PrimitiveValue; }
/// <summary> /// Invokes RuntimeHelpers.GetHashCode on given value, that is a default hashCode ignoring user overrides. /// </summary> /// <param name="value">Valid value.</param> /// <returns>Hash code of the object in the debugee.</returns> public static int InvokeDefaultGetHashCode(this Value value) { if (hashCodeMethod == null || hashCodeMethod.Process.HasExited) { DebugType typeRuntimeHelpers = DebugType.CreateFromType(value.AppDomain, typeof(System.Runtime.CompilerServices.RuntimeHelpers)); hashCodeMethod = (DebugMethodInfo)typeRuntimeHelpers.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Static); if (hashCodeMethod == null) { throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode"); } } // David: I had hard time finding out how to invoke static method. // value.InvokeMethod is nice for instance methods. // what about MethodInfo.Invoke() ? // also, there could be an overload that takes 1 parameter instead of array string defaultHashCode = Eval.InvokeMethod(DebuggerHelpers.hashCodeMethod, null, new Value[]{value}).AsString; //MethodInfo method = value.Type.GetMember("GetHashCode", BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo; //string hashCode = value.InvokeMethod(method, null).AsString; return int.Parse(defaultHashCode); }
internal DebugConstructorInfo(DebugMethodInfo methodInfo) { this.methodInfo = methodInfo; }
public static Eval AsyncNewObject(DebugMethodInfo constructor, Value[] constructorArguments) { ICorDebugValue[] constructorArgsCorDebug = ValuesAsCorDebug(constructorArguments); return new Eval( constructor.AppDomain, "New object: " + constructor.FullName, delegate(Eval eval) { eval.CorEval2.NewParameterizedObject( constructor.CorFunction, (uint)constructor.DeclaringType.GetGenericArguments().Length, ((DebugType)constructor.DeclaringType).GenericArgumentsAsCorDebugType, (uint)constructorArgsCorDebug.Length, constructorArgsCorDebug); } ); }
public static Value NewObject(DebugMethodInfo constructor, Value[] constructorArguments) { return AsyncNewObject(constructor, constructorArguments).WaitForResult(); }
/// <exception cref="GetValueException"><c>GetValueException</c>.</exception> static void MethodInvokeStarter(Eval eval, DebugMethodInfo method, Value thisValue, Value[] args) { List<ICorDebugValue> corArgs = new List<ICorDebugValue>(); args = args ?? new Value[0]; if (args.Length != method.ParameterCount) { throw new GetValueException("Invalid parameter count"); } if (!method.IsStatic) { if (thisValue == null) throw new GetValueException("'this' is null"); if (thisValue.IsNull) throw new GetValueException("Null reference"); // if (!(thisValue.IsObject)) // eg Can evaluate on array if (!method.DeclaringType.IsInstanceOfType(thisValue)) { throw new GetValueException( "Can not evaluate because the object is not of proper type. " + "Expected: " + method.DeclaringType.FullName + " Seen: " + thisValue.Type.FullName ); } corArgs.Add(thisValue.CorValue); } for(int i = 0; i < args.Length; i++) { Value arg = args[i]; DebugType paramType = (DebugType)method.GetParameters()[i].ParameterType; if (!arg.Type.CanImplicitelyConvertTo(paramType)) throw new GetValueException("Inncorrect parameter type"); // Implicitely convert to correct primitve type if (paramType.IsPrimitive && args[i].Type != paramType) { object oldPrimVal = arg.PrimitiveValue; object newPrimVal = Convert.ChangeType(oldPrimVal, paramType.PrimitiveType); arg = CreateValue(method.AppDomain, newPrimVal); } // It is importatnt to pass the parameted in the correct form (boxed/unboxed) if (paramType.IsValueType) { corArgs.Add(arg.CorGenericValue); } else { if (args[i].Type.IsValueType) { corArgs.Add(arg.Box().CorValue); } else { corArgs.Add(arg.CorValue); } } } ICorDebugType[] genericArgs = ((DebugType)method.DeclaringType).GenericArgumentsAsCorDebugType; eval.CorEval2.CallParameterizedFunction( method.CorFunction, (uint)genericArgs.Length, genericArgs, (uint)corArgs.Count, corArgs.ToArray() ); }
public static Eval AsyncInvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args) { return new Eval( method.AppDomain, "Function call: " + method.FullName, delegate(Eval eval) { MethodInvokeStarter(eval, method, thisValue, args); } ); }
/// <summary> Synchronously calls a function and returns its return value </summary> public static Value InvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args) { if (method.BackingField != null) { method.Process.TraceMessage("Using backing field for " + method.FullName); return Value.GetMemberValue(thisValue, method.BackingField, args); } return AsyncInvokeMethod(method, thisValue, args).WaitForResult(); }