// The following function create values only for the purpuse of evalutaion // They actually do not allocate memory on the managed heap // The advantage is that it does not continue the process /// <exception cref="DebuggerException">Can not create string this way</exception> public static Value CreateValue(Process process, object value) { if (value is string) { throw new DebuggerException("Can not create string this way"); } CorElementType corElemType; ICorDebugClass corClass = null; if (value != null) { corElemType = DebugType.TypeNameToCorElementType(value.GetType().FullName); } else { corElemType = CorElementType.CLASS; corClass = DebugType.Create(process, null, typeof(object).FullName).CorType.Class; } ICorDebugEval corEval = CreateCorEval(process); ICorDebugValue corValue = corEval.CreateValue((uint)corElemType, corClass); Value v = new Value(process, new Expressions.PrimitiveExpression(value), corValue); if (value != null) { v.PrimitiveValue = value; } return(v); }
DebugType(Process process, ICorDebugType corType) { if (corType == null) { throw new ArgumentNullException("corType"); } this.process = process; this.corType = corType; this.corElementType = (CorElementType)corType.Type; if (this.IsClass || this.IsValueType) { this.corClass = corType.Class; this.module = process.GetModule(corClass.Module); this.classProps = module.MetaData.GetTypeDefProps(corClass.Token); } if (this.IsClass || this.IsValueType || this.IsArray || this.IsPointer) { foreach (ICorDebugType t in corType.EnumerateTypeParameters().Enumerator) { typeArguments.Add(DebugType.Create(process, t)); } } this.fullName = GetFullName(); }
internal Value(Process process, Expression expression, ICorDebugValue corValue) { if (corValue == null) { throw new ArgumentNullException("corValue"); } this.process = process; this.expression = expression; this.corValue = corValue; this.corValue_pauseSession = process.PauseSession; if (corValue.Is <ICorDebugReferenceValue>() && corValue.CastTo <ICorDebugReferenceValue>().Value == 0 && corValue.CastTo <ICorDebugValue2>().ExactType == null) { // We were passed null reference and no metadata description // (happens during CreateThread callback for the thread object) this.type = DebugType.Create(this.Process, null, "System.Object"); } else { ICorDebugType exactType = this.CorValue.CastTo <ICorDebugValue2>().ExactType; this.type = DebugType.Create(this.Process, exactType); } }
internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, uint chainIndex, uint frameIndex) { this.process = thread.Process; this.thread = thread; this.corILFrame = corILFrame; this.corILFramePauseSession = process.PauseSession; this.corFunction = corILFrame.Function; this.chainIndex = chainIndex; this.frameIndex = frameIndex; DebugType debugType = DebugType.Create( this.Process, corFunction.Class, corILFrame.CastTo <ICorDebugILFrame2>().EnumerateTypeParameters().ToList().ToArray() ); this.methodInfo = debugType.GetMethod(corFunction.Token); }
public Value GetPermanentReference() { ICorDebugValue corValue = this.CorValue; if (this.Type.IsClass) { corValue = this.CorObjectValue.CastTo <ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo <ICorDebugValue>(); } if (this.Type.IsValueType || this.Type.IsPrimitive) { if (!corValue.Is <ICorDebugReferenceValue>()) { // Box the value type if (this.Type.IsPrimitive) { // Get value type for the primive type object o = this.PrimitiveValue; corValue = Eval.NewObjectNoConstructor(DebugType.Create(process, null, this.Type.FullName)).RawCorValue; this.SetPrimitiveValue(o); } else { corValue = Eval.NewObjectNoConstructor(this.Type).RawCorValue; } // Make the reference to box permanent corValue = corValue.CastTo <ICorDebugReferenceValue>().Dereference().CastTo <ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo <ICorDebugValue>(); // Create new value Value newValue = new Value(process, new IExpirable[] {}, new IMutable[] {}, delegate { return(corValue); }); // Copy the data inside the box newValue.CorGenericValue.RawValue = this.CorGenericValue.RawValue; return(newValue); } else { // Make the reference to box permanent corValue = corValue.CastTo <ICorDebugReferenceValue>().Dereference().CastTo <ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo <ICorDebugValue>(); } } return(new Value(process, new IExpirable[] {}, new IMutable[] {}, delegate { return corValue; })); }
/// <summary> /// Get a method from a managed type, method name and argument count /// </summary> public static MethodInfo GetFromName(Process process, System.Type type, string name, int paramCount) { if (type.IsNested) { throw new DebuggerException("Not implemented for nested types"); } if (type.IsGenericType) { throw new DebuggerException("Not implemented for generic types"); } if (type.IsGenericParameter) { throw new DebuggerException("Type can not be generic parameter"); } foreach (Module module in process.Modules) { TypeDefProps typeDefProps; try { typeDefProps = module.MetaData.FindTypeDefByName(type.FullName, 0 /* enclosing class for nested */); } catch { continue; } foreach (MethodProps methodProps in module.MetaData.EnumMethodsWithName(typeDefProps.Token, name)) { if (module.MetaData.GetParamCount(methodProps.Token) == paramCount) { ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(methodProps.Token); ICorDebugClass2 corClass = corFunction.Class.As <ICorDebugClass2>(); ICorDebugType corType = corClass.GetParameterizedType(type.IsValueType ? (uint)CorElementType.VALUETYPE : (uint)CorElementType.CLASS, 0, new ICorDebugType[] {}); return(new MethodInfo(DebugType.Create(process, corType), methodProps)); } } } throw new DebuggerException("Not found"); }
Value Box() { byte[] rawValue = this.CorGenericValue.RawValue; // Box the value type ICorDebugValue corValue; if (this.Type.IsPrimitive) { // Get value type for the primive type corValue = Eval.NewObjectNoConstructor(DebugType.Create(process, null, this.Type.FullName)).CorValue; } else { corValue = Eval.NewObjectNoConstructor(this.Type).CorValue; } // Make the reference to box permanent corValue = corValue.CastTo <ICorDebugReferenceValue>().Dereference().CastTo <ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo <ICorDebugValue>(); // Create new value Value newValue = new Value(process, expression, corValue); // Copy the data inside the box newValue.CorGenericValue.RawValue = rawValue; return(newValue); }
void LoadMemberInfo() { foreach (InterfaceImplProps implProps in module.MetaData.EnumInterfaceImplProps(this.Token)) { if ((implProps.Interface & 0xFF000000) == (uint)CorTokenType.mdtTypeDef || (implProps.Interface & 0xFF000000) == (uint)CorTokenType.mdtTypeRef) { this.interfaces.Add(DebugType.Create(module, implProps.Interface)); } } // Load fields foreach (FieldProps field in module.MetaData.EnumFields(this.MetadataToken)) { if (field.IsStatic && field.IsLiteral) { continue; // Skip static literals TODO: Why? } fields.Add(new FieldInfo(this, field)); } ; // Load methods foreach (MethodProps m in module.MetaData.EnumMethods(this.MetadataToken)) { methods.Add(new MethodInfo(this, m)); } foreach (PropertyProps p in module.MetaData.EnumProperties(this.MetadataToken)) { properties.Add(new PropertyInfo(this, p.Name, GetGetMethod(p), GetSetMethod(p))); } // Load properties // TODO: Handle indexers ("get_Item") in other code // Collect data Dictionary <string, MethodInfo> accessors = new Dictionary <string, MethodInfo>(); Dictionary <string, object> propertyNames = new Dictionary <string, object>(); /*foreach(MethodInfo method in methods) { * if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) { * // There can be many get_Items * // TODO: This returns only last, return all * accessors[method.Name] = method; * propertyNames[method.Name.Remove(0,4)] = null; * } * }*/ // Pair up getters and setters /* * foreach(KeyValuePair<string, object> kvp in propertyNames) { * MethodInfo getter = null; * MethodInfo setter = null; * accessors.TryGetValue("get_" + kvp.Key, out getter); * accessors.TryGetValue("set_" + kvp.Key, out setter); * properties.Add(new PropertyInfo(this, getter, setter)); * }*/ // Make a combined collection foreach (FieldInfo field in fields) { members.Add(field); } foreach (MemberInfo method in methods) { members.Add(method); } foreach (PropertyInfo property in properties) { members.Add(property); } }