public static NamedValue GetNullBasedArray(Value val) { IList<FieldInfo> flds = val.Type.GetFields(); if (flds.Count != 3) return null; foreach (FieldInfo fi in flds) if (fi.Name == "NullBasedArray") return fi.GetValue(val); return null; }
// Object graph visualizer: collection support temp disabled (porting to new NRefactory). /* /// <summary> /// Creates an expression which, when evaluated, creates a List<T> in the debugee /// filled with contents of IEnumerable<T> from the debugee. /// </summary> /// <param name="iEnumerableVariable">Expression for IEnumerable variable in the debugee.</param> /// <param name="itemType"> /// The generic argument of IEnumerable<T> that <paramref name="iEnumerableVariable"/> implements.</param> public static Expression CreateDebugListExpression(Expression iEnumerableVariable, DebugType itemType, out DebugType listType) { // is using itemType.AppDomain ok? listType = DebugType.CreateFromType(itemType.AppDomain, typeof(System.Collections.Generic.List<>), itemType); var iEnumerableType = DebugType.CreateFromType(itemType.AppDomain, typeof(IEnumerable<>), itemType); // explicitely cast the variable to IEnumerable<T>, where T is itemType Expression iEnumerableVariableExplicitCast = new CastExpression(iEnumerableType.GetTypeReference() , iEnumerableVariable, CastType.Cast); return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.SingleItemList()); }*/ /// <summary> /// Evaluates 'new List<T>(iEnumerableValue)' in the debuggee. /// </summary> public static Value CreateListFromIEnumerable(Value iEnumerableValue) { ParameterizedType iEnumerableType; IType itemType; if (!iEnumerableValue.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) throw new GetValueException("Value is not IEnumerable"); return ValueNode.CreateListFromIEnumerable(iEnumerableType, iEnumerableValue).GetPermanentReferenceOfHeapValue(); }
/// <summary> Get the value of given member. </summary> /// <param name="objectInstance">null if member is static</param> public static Value GetMemberValue(Value objectInstance, MemberInfo memberInfo, Value[] arguments) { arguments = arguments ?? new Value[0]; if (memberInfo is FieldInfo) { if (arguments.Length > 0) throw new GetValueException("Arguments can not be used for a field"); return GetFieldValue(objectInstance, (FieldInfo)memberInfo); } else if (memberInfo is PropertyInfo) { return GetPropertyValue(objectInstance, (PropertyInfo)memberInfo, arguments); } else if (memberInfo is MethodInfo) { return InvokeMethod(objectInstance, (MethodInfo)memberInfo, arguments); } throw new DebuggerException("Unknown member type: " + memberInfo.GetType()); }
static void CheckObject(Value objectInstance, MemberInfo memberInfo) { if (!memberInfo.IsStatic) { if (objectInstance == null) { throw new DebuggerException("No target object specified"); } if (objectInstance.IsNull) { throw new GetValueException("Null reference"); } //if (!objectInstance.IsObject) // eg Array.Length can be called if (!memberInfo.DeclaringType.IsInstanceOfType(objectInstance)) { throw new GetValueException("Object is not of type " + memberInfo.DeclaringType.FullName); } } }
/// <summary> /// Given an object of correct type, get the value of this field /// </summary> public MemberValue GetValue(Value objectInstance) { if (objectInstance != null) return new MemberValue( this, this.Process, new IExpirable[] {objectInstance}, new IMutable[] {objectInstance}, delegate { return GetCorValue(objectInstance); } ); else return new MemberValue( this, this.Process, new IExpirable[0], new IMutable[0] , delegate { return GetCorValue(objectInstance); } ); }
public static int GetImageListIndex(Value val) { try { if (val.IsObject) { return 0; // Class } else { return 1; // Field } } catch (System.Exception e) { return 1; } }
internal Exception(Thread thread) { creationTime = DateTime.Now; this.process = thread.Process; this.thread = thread; corValue = thread.CorThread.CurrentException; exceptionType = thread.CurrentExceptionType; Value runtimeValue = new Value(process, new IExpirable[] {process.PauseSession}, new IMutable[] {}, delegate { return corValue; } ); NamedValue nv = runtimeValue.GetMember("_message"); if (!nv.IsNull) message = nv.AsString; else message = runtimeValue.Type.FullName; if (thread.LastFunctionWithLoadedSymbols != null) { location = thread.LastFunctionWithLoadedSymbols.NextStatement; } callstack = ""; int callstackItems = 0; if (!nv.IsNull) foreach(Function function in thread.Callstack) { if (callstackItems >= 100) { callstack += "...\n"; break; } SourcecodeSegment loc = function.NextStatement; callstack += function.Name + "()"; if (loc != null) { callstack += " - " + loc.SourceFullFilename + ":" + loc.StartLine + "," + loc.StartColumn; } callstack += "\n"; callstackItems++; } type = runtimeValue.Type.FullName; }
bool InjectInterpreter() { if (!DebuggerService.IsDebuggerLoaded) { PrintLine(ResourceService.GetString("ICSharpCode.BooInterpreter.Debuggee.ErrorDebuggerNotLoaded")); return false; } WindowsDebugger winDebugger = DebuggerService.CurrentDebugger as WindowsDebugger; if (winDebugger == null) { PrintLine(ResourceService.GetString("ICSharpCode.BooInterpreter.Debuggee.ErrorIncompatibleDebugger")); return false; } if (winDebugger.DebuggedProcess == null) { PrintLine(ResourceService.GetString("ICSharpCode.BooInterpreter.Debuggee.ErrorNoProgramDebugged")); return false; } process = winDebugger.DebuggedProcess; process.Expired += delegate { interpreter = null; }; process.LogMessage -= OnDebuggerLogMessage; process.LogMessage += OnDebuggerLogMessage; Value assembly; // Boo.Lang.Interpreter.dll string path = Path.Combine(Path.GetDirectoryName(typeof(InterpreterContext).Assembly.Location), "Boo.Lang.Interpreter.dll"); assembly = LoadAssembly(path); // Debugger.BooInterpreter.dll assembly = LoadAssembly(typeof(DebugeeInteractiveInterpreter).Assembly.Location); Value interpreterType = Eval.NewString(process, typeof(DebugeeInteractiveInterpreter).FullName); interpreter = Eval.InvokeMethod(process, typeof(Assembly), "CreateInstance", assembly, new Value[] {interpreterType}); interpreter_localVariable = interpreter.GetMember("localVariable"); RunCommand( "import System\n" + "import System.IO\n" + "import System.Text\n" + "interpreter.RememberLastValue = true\n" + "interpreter.Print = def(msg): System.Diagnostics.Debugger.Log(0xB00, \"DebugeeInterpreterContext.PrintLine\", msg)"); return true; }
static ICorDebugValue[] ValuesAsCorDebug(Value[] values) { ICorDebugValue[] valuesAsCorDebug = new ICorDebugValue[values.Length]; for(int i = 0; i < values.Length; i++) { valuesAsCorDebug[i] = values[i].CorValue; } return valuesAsCorDebug; }
public static Value NewObject(Thread evalThread, IMethod constructor, Value[] constructorArguments) { return AsyncNewObject(evalThread, constructor, constructorArguments).WaitForResult(); }
public static Eval AsyncInvokeMethod(Thread evalThread, IMethod method, Value thisValue, Value[] args) { return new Eval( evalThread, "Function call: " + method.FullName, delegate(Eval eval) { MethodInvokeStarter(eval, method, thisValue, args); } ); }
internal void NotifyEvaluationComplete(bool successful) { // Eval result should be ICorDebugHandleValue so it should survive Continue() if (state == EvalState.EvaluatedTimeOut) { return; } if (corEval.GetResult() == null) { state = EvalState.EvaluatedNoResult; } else { if (successful) { state = EvalState.EvaluatedSuccessfully; } else { state = EvalState.EvaluatedException; } result = new Value(AppDomain, corEval.GetResult()); } }
/// <summary> /// Formats current Value according to the given format, specified by <see cref="System.Diagnostics.DebuggerDisplayAttribute"/>. /// </summary> /// <param name="debugFormat">Format to use</param> /// <returns>Formatted string.</returns> /// <remarks> /// Not all possible expressions are supported, but only a simple set. /// Otherwise we would have to support any C# expression. /// </remarks> static string FormatDebugValue(Thread evalThread, Value value, string debugFormat) { StringBuilder formattedOutput = new StringBuilder(); StringBuilder currentFieldName = new StringBuilder(); bool insideFieldName = false; bool ignoringRestOfExpression = false; bool insideMethodBrackets = false; bool isMethodName = false; bool escapeNextChar = false; for (int i = 0; i < debugFormat.Length; i++) { char thisChar = debugFormat[i]; if (!escapeNextChar && (thisChar == '{')) { insideFieldName = true; } else if (!escapeNextChar && (thisChar == '}')) { // Insert contents of specified member, if we can find it, otherwise we display "?" string memberValueStr = "?"; // Decide if we want a method or field/property Predicate<IUnresolvedMember> isNeededMember; if (isMethodName) { // We only support methods without parameters here! isNeededMember = m => (m.Name == currentFieldName.ToString()) && (m.SymbolKind == SymbolKind.Method) && (((IUnresolvedMethod) m).Parameters.Count == 0); } else { isNeededMember = m => (m.Name == currentFieldName.ToString()) && ((m.SymbolKind == SymbolKind.Field) || (m.SymbolKind == SymbolKind.Property)); } IMember member = value.type.GetMembers(isNeededMember).FirstOrDefault(); if (member != null) { Value memberValue = value.GetMemberValue(evalThread, member); memberValueStr = memberValue.InvokeToString(evalThread); } formattedOutput.Append(memberValueStr); insideFieldName = false; ignoringRestOfExpression = false; insideMethodBrackets = false; isMethodName = false; currentFieldName.Clear(); } else if (!escapeNextChar && (thisChar == '\\')) { // Next character will be escaped escapeNextChar = true; } else if (insideFieldName && (thisChar == '(')) { insideMethodBrackets = true; } else if ((thisChar == ')') && insideMethodBrackets) { insideMethodBrackets = false; isMethodName = true; // Everything following the brackets will be ignored ignoringRestOfExpression = true; } else if (insideFieldName && !Char.IsDigit(thisChar) && !Char.IsLetter(thisChar)) { // Char seems not to belong to a field name, ignore everything from now on ignoringRestOfExpression = true; } else { if (insideFieldName) { if (!ignoringRestOfExpression) currentFieldName.Append(thisChar); } else { formattedOutput.Append(thisChar); } escapeNextChar = false; } } return formattedOutput.ToString(); }
/// <summary> Set the value of the property using the set accessor </summary> public Value SetPropertyValue(Thread evalThread, IProperty propertyInfo, Value[] arguments, Value newValue) { return SetPropertyValue(evalThread, this, propertyInfo, arguments, newValue); }
/// <summary> Determines whether the given object is instance of the /// current type or can be implicitly cast to it </summary> public bool IsInstanceOfType(Value objectInstance) { return objectInstance.Type.Equals(this) || objectInstance.Type.IsSubclassOf(this); }
static ICorDebugValue GetFieldCorValue(Thread contextThread, Value objectInstance, IField fieldInfo) { // Current frame is used to resolve context specific static values (eg. ThreadStatic) ICorDebugFrame curFrame = null; if (contextThread != null && contextThread.MostRecentStackFrame != null && contextThread.MostRecentStackFrame.CorILFrame != null) { curFrame = contextThread.MostRecentStackFrame.CorILFrame; } try { if (fieldInfo.IsStatic) { return (fieldInfo.DeclaringType).ToCorDebug().GetStaticFieldValue(fieldInfo.GetMetadataToken(), curFrame); } else { return objectInstance.CorObjectValue.GetFieldValue((fieldInfo.DeclaringType).ToCorDebug().GetClass(), fieldInfo.GetMetadataToken()); } } catch (COMException e) { // System.Runtime.InteropServices.COMException (0x80131303): A class is not loaded. (Exception from HRESULT: 0x80131303) if ((uint)e.ErrorCode == 0x80131303) throw new GetValueException("Class " + fieldInfo.DeclaringType.FullName + " is not loaded"); throw new GetValueException("Can not get value of field", e); } }
/// <summary> Get the value of the property using the get accessor </summary> public static Value GetPropertyValue(Thread evalThread, Value objectInstance, IProperty propertyInfo, params Value[] arguments) { CheckObject(objectInstance, propertyInfo); if (!propertyInfo.CanGet) throw new GetValueException("Property does not have a get method"); return Value.InvokeMethod(evalThread, objectInstance, propertyInfo.Getter, arguments); }
// Box value type public Value Box(Thread evalThread) { byte[] rawValue = this.CorGenericValue.GetRawValue(); // The type must not be a primive type (always true in current design) ICorDebugReferenceValue corRefValue = Eval.NewObjectNoConstructor(evalThread, this.Type).CorReferenceValue; // Make the reference to box permanent corRefValue = ((ICorDebugHeapValue2)corRefValue.Dereference()).CreateHandle(CorDebugHandleType.HANDLE_STRONG); // Create new value Value newValue = new Value(appDomain, corRefValue); // Copy the data inside the box newValue.CorGenericValue.SetRawValue(rawValue); return newValue; }
/// <summary> Set the value of the property using the set accessor </summary> public static Value SetPropertyValue(Thread evalThread, Value objectInstance, IProperty propertyInfo, Value[] arguments, Value newValue) { CheckObject(objectInstance, propertyInfo); if (!propertyInfo.CanSet) throw new GetValueException("Property does not have a set method"); arguments = arguments ?? new Value[0]; Value[] allParams = new Value[1 + arguments.Length]; allParams[0] = newValue; arguments.CopyTo(allParams, 1); return Value.InvokeMethod(evalThread, objectInstance, propertyInfo.Setter, allParams); }
/// <summary> Copy the acutal value from some other Value object </summary> public void SetValue(Thread evalThread, Value newValue) { ICorDebugValue newCorValue = newValue.CorValue; if (this.CorValue is ICorDebugReferenceValue) { if (!(newCorValue is ICorDebugReferenceValue)) newCorValue = newValue.Box(evalThread).CorValue; ((ICorDebugReferenceValue)this.CorValue).SetValue(((ICorDebugReferenceValue)newCorValue).GetValue()); } else { this.CorGenericValue.SetRawValue(newValue.CorGenericValue.GetRawValue()); } }
/// <summary> Asynchronously invoke the method </summary> public static Eval AsyncInvokeMethod(Thread evalThread, Value objectInstance, IMethod methodInfo, params Value[] arguments) { CheckObject(objectInstance, methodInfo); return Eval.AsyncInvokeMethod( evalThread, (IMethod)methodInfo, methodInfo.IsStatic ? null : objectInstance, arguments ?? new Value[0] ); }
public void SetArrayElement(Thread evalThread, uint[] elementIndices, Value newVal) { Value elem = GetArrayElement(elementIndices); elem.SetValue(evalThread, newVal); }
/// <summary> Synchronously calls a function and returns its return value </summary> public static Value InvokeMethod(Thread evalThread, IMethod method, Value thisValue, Value[] args) { uint fieldToken = method.GetBackingFieldToken(); if (fieldToken != 0) { var field = method.DeclaringType.ImportField(fieldToken); if (field != null) { evalThread.Process.TraceMessage("Using backing field for " + method.FullName); return Value.GetMemberValue(evalThread, thisValue, field, args); } } return AsyncInvokeMethod(evalThread, method, thisValue, args).WaitForResult(); }
static void CheckObject(Value objectInstance, IMember memberInfo) { if (memberInfo == null) throw new DebuggerException("memberInfo is null"); if (!memberInfo.IsStatic) { if (objectInstance == null) throw new DebuggerException("No target object specified"); if (objectInstance.IsNull) throw new GetValueException("Null reference"); // Array.Length can be called if (objectInstance.Type.Kind == TypeKind.Array) return; if (objectInstance.Type.GetDefinition() == null || !objectInstance.Type.GetDefinition().IsDerivedFrom(memberInfo.DeclaringType.GetDefinition())) throw new GetValueException("Object is not of type " + memberInfo.DeclaringType.FullName); } }
/// <exception cref="GetValueException"><c>GetValueException</c>.</exception> static void MethodInvokeStarter(Eval eval, IMethod method, Value thisValue, Value[] args) { List<ICorDebugValue> corArgs = new List<ICorDebugValue>(); args = args ?? new Value[0]; if (args.Length != method.Parameters.Count) { 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"); corArgs.Add(thisValue.CorValue); } for(int i = 0; i < args.Length; i++) { Value arg = args[i]; IType paramType = method.Parameters[i].Type; if (!arg.IsNull && arg.Type.GetDefinition() != null && paramType.GetDefinition() != null && !arg.Type.GetDefinition().IsDerivedFrom(paramType.GetDefinition())) { throw new GetValueException("Inncorrect parameter type. Expected " + paramType.ToString()); } // It is importatnt to pass the parameter in the correct form (boxed/unboxed) if (paramType.IsReferenceType == true) { if (!arg.IsReference) throw new DebuggerException("Reference expected as method argument"); corArgs.Add(arg.CorValue); } else { corArgs.Add(arg.CorGenericValue); // Unbox } } ICorDebugType[] genericArgs = method.GetTypeArguments(); eval.CorEval2.CallParameterizedFunction( method.ToCorFunction(), (uint)genericArgs.Length, genericArgs, (uint)corArgs.Count, corArgs.ToArray() ); }
/// <summary> Get the value of given member. </summary> /// <param name="objectInstance">null if member is static</param> public static Value GetMemberValue(Thread evalThread, Value objectInstance, IMember memberInfo, params Value[] arguments) { if (memberInfo is IField) { if (arguments.Length > 0) throw new GetValueException("Arguments can not be used for a field"); return GetFieldValue(evalThread, objectInstance, (IField)memberInfo); } else if (memberInfo is IProperty) { return GetPropertyValue(evalThread, objectInstance, (IProperty)memberInfo, arguments); } else if (memberInfo is IMethod) { return InvokeMethod(evalThread, objectInstance, (IMethod)memberInfo, arguments); } else if (memberInfo is IEvent) { string name = memberInfo.Name; IField f = memberInfo.DeclaringType.GetFields(m => m.Name == name, GetMemberOptions.None).FirstOrDefault(); if (f == null) { name += "Event"; f = memberInfo.DeclaringType.GetFields(m => m.Name == name, GetMemberOptions.None).FirstOrDefault(); } if (f == null) throw new GetValueException("Cannot retrieve event value"); return GetFieldValue(evalThread, objectInstance, f); } throw new DebuggerException("Unknown member type: " + memberInfo.GetType()); }
public static Eval AsyncNewObject(Thread evalThread, IMethod constructor, Value[] constructorArguments) { ICorDebugType[] typeArgs = constructor.GetTypeArguments(); ICorDebugValue[] ctorArgs = ValuesAsCorDebug(constructorArguments); return new Eval( evalThread, "New object: " + constructor.FullName, delegate(Eval eval) { eval.CorEval2.NewParameterizedObject( constructor.ToCorFunction(), (uint)typeArgs.Length, typeArgs, (uint)ctorArgs.Length, ctorArgs); } ); }
public static void SetFieldValue(Thread evalThread, Value objectInstance, IField fieldInfo, Value newValue) { Value val = GetFieldValue(evalThread, objectInstance, fieldInfo); if (!newValue.Type.GetDefinition().IsDerivedFrom(fieldInfo.Type.GetDefinition())) throw new GetValueException("Cannot assign {0} to {1}", newValue.Type.FullName, fieldInfo.Type.FullName); val.SetValue(evalThread, newValue); }
/// <summary> /// Asynchronously invoke the method of an a given object /// </summary> public Eval AsyncInvoke(Value objectInstance, Value[] arguments) { return Eval.AsyncInvokeMethod( this, this.IsStatic ? null : objectInstance, arguments ?? new Value[0] ); }
/// <summary> Get the value of given field. </summary> /// <param name="thread"> Thread to use for thread-local storage </param> /// <param name="objectInstance">null if field is static</param> public static Value GetFieldValue(Thread evalThread, Value objectInstance, IField fieldInfo) { CheckObject(objectInstance, fieldInfo); if (fieldInfo.IsStatic && fieldInfo.IsConst) { return GetLiteralValue(evalThread, (IField)fieldInfo); } else { return new Value(evalThread.AppDomain, GetFieldCorValue(evalThread, objectInstance, fieldInfo)); } }