/// <summary> /// Constructor /// </summary> /// <param name="value">Value (will be owned by this <see cref="CorValueHolder"/> instance) or null</param> /// <param name="getCorValue">Delegate to fetch a new value once it's been neutered. The /// returned value will be owned by this <see cref="CorValueHolder"/> instance</param> public CorValueHolder(CorValue value, Func<CorValue> getCorValue) { if (getCorValue == null) throw new ArgumentNullException(); this.value = value; this.getCorValue = getCorValue; }
string StoreValue_CorDebug(DnEval dnEval, List <CorValue> createdValues, CorAppDomain appDomain, DnThread dnThread, CorValue targetValue, DmdType targetType, CorValue sourceValue, DmdType sourceType) { if (targetType.IsByRef) { return(CordbgErrorHelper.InternalError); } int hr; if (!targetType.IsValueType) { if (!targetValue.IsReference) { return(CordbgErrorHelper.InternalError); } if (!sourceValue.IsReference) { var boxedSourceValue = BoxIfNeeded(dnEval, appDomain, createdValues, sourceValue, targetType, sourceType); if (!boxedSourceValue.IsReference) { return(CordbgErrorHelper.InternalError); } sourceValue = boxedSourceValue; } if (!sourceValue.IsNull && sourceType.IsValueType) { var sourceDerefVal = sourceValue.GetDereferencedValue(out hr); if (sourceDerefVal == null) { return(CordbgErrorHelper.GetErrorMessage(hr)); } if (!sourceDerefVal.IsBox) { return(CordbgErrorHelper.InternalError); } } hr = targetValue.SetReferenceAddress(sourceValue.ReferenceAddress); if (hr != 0) { return(CordbgErrorHelper.GetErrorMessage(hr)); } return(null); } else { if (!sourceType.IsValueType) { return(CordbgErrorHelper.InternalError); } if (targetValue.IsReference) { targetValue = targetValue.GetDereferencedValue(out hr); if (targetValue == null) { return(CordbgErrorHelper.GetErrorMessage(hr)); } } if (targetValue.IsBox) { return(CordbgErrorHelper.InternalError); } if (sourceValue.IsReference) { sourceValue = sourceValue.GetDereferencedValue(out hr); if (sourceValue == null) { return(CordbgErrorHelper.GetErrorMessage(hr)); } } if (sourceValue.IsBox) { sourceValue = sourceValue.GetBoxedValue(out hr); if (sourceValue == null) { return(CordbgErrorHelper.GetErrorMessage(hr)); } } if (!targetValue.IsGeneric || !sourceValue.IsGeneric) { return(CordbgErrorHelper.InternalError); } if (targetValue.Size != sourceValue.Size) { return(CordbgErrorHelper.InternalError); } hr = targetValue.WriteGenericValue(sourceValue.ReadGenericValue(), dnThread.Process.CorProcess); if (hr < 0) { return(CordbgErrorHelper.GetErrorMessage(hr)); } return(null); } }
CorValue BoxIfNeeded(DnEval dnEval, CorAppDomain appDomain, List <CorValue> createdValues, CorValue corValue, DmdType targetType, DmdType valueType) { if (!targetType.IsValueType && valueType.IsValueType && corValue.IsGeneric && !corValue.IsHeap) { var etype = corValue.ElementType; var corValueType = corValue.ExactType; if (!corValueType.HasClass) { corValueType = GetType(appDomain, valueType); } var boxedValue = dnEval.Box(corValue, corValueType) ?? throw new InvalidOperationException(); if (boxedValue != corValue) { createdValues.Add(boxedValue); } corValue = boxedValue; } return(corValue); }
public bool GetNullableValue(out IDebuggerValue value) { IDebuggerValue valueTmp = null; bool res = debugger.Dispatcher.UI(() => { CorValue corValue; bool res2 = this.value.GetNullableValue(out corValue); valueTmp = corValue == null ? null : new DebuggerValue(debugger, corValue); return res2; }); value = valueTmp; return res; }
public void InvalidateCorValue() { if (value != null) value.DisposeHandle(); value = null; }
public CorValueResult CallResult(CorFunction func, CorType[] typeArgs, CorValue[] args, out int hr) { var res = Call(func, typeArgs, args, out hr); if (res == null || res.Value.WasException || res.Value.ResultOrException == null) return new CorValueResult(); return res.Value.ResultOrException.Value; }
public EvalResult Call(CorFunction func, CorValue[] args) { return Call(func, null, args); }
public CorValRef(CorValue val) { this.val = val; this.version = CorDebuggerSession.EvaluationTimestamp; }
/// <summary> /// Creates a new instance of the MDbgValue Object. /// This constructor is public so that applications can use this class to print values (CorValue). /// CorValue's can be returned for example by funceval(CorEval.Result). /// </summary> /// <param name="process">The Process that will own the Value.</param> /// <param name="name">The name of the variable.</param> /// <param name="value">The CorValue that this MDbgValue will start with.</param> public MDbgValue(MDbgProcess process, string name, CorValue value) { Debug.Assert(process != null && name != null); // corValue can be null for native variables in MC++ Initialize(process, name, value); }
private string InternalGetValue(int indentLevel, int expandDepth, bool canDoFunceval) { Debug.Assert(expandDepth >= 0); CorValue value = this.CorValue; if (value == null) { return("<N/A>"); } // Record the memory addresses if displaying them is enabled string prefix = String.Empty; StringBuilder ptrStrBuilder = null; if (m_process.m_engine.Options.ShowAddresses) { ptrStrBuilder = new StringBuilder(); } try { value = Dereference(value, ptrStrBuilder); } catch (COMException ce) { if (ce.ErrorCode == (int)HResult.CORDBG_E_BAD_REFERENCE_VALUE) { return(MakePrefixFromPtrStringBuilder(ptrStrBuilder) + "<invalid reference value>"); } throw; } prefix = MakePrefixFromPtrStringBuilder(ptrStrBuilder); if (value == null) { return(prefix + "<null>"); } Unbox(ref value); switch (value.Type) { case CorElementType.ELEMENT_TYPE_BOOLEAN: case CorElementType.ELEMENT_TYPE_I1: case CorElementType.ELEMENT_TYPE_U1: case CorElementType.ELEMENT_TYPE_I2: case CorElementType.ELEMENT_TYPE_U2: case CorElementType.ELEMENT_TYPE_I4: case CorElementType.ELEMENT_TYPE_U4: case CorElementType.ELEMENT_TYPE_I: case CorElementType.ELEMENT_TYPE_U: case CorElementType.ELEMENT_TYPE_I8: case CorElementType.ELEMENT_TYPE_U8: case CorElementType.ELEMENT_TYPE_R4: case CorElementType.ELEMENT_TYPE_R8: case CorElementType.ELEMENT_TYPE_CHAR: { object v = value.CastToGenericValue().GetValue(); string result; IFormattable vFormattable = v as IFormattable; if (vFormattable != null) { result = vFormattable.ToString(null, System.Globalization.CultureInfo.CurrentUICulture); } else { result = v.ToString(); } // let's put quotes around char values if (value.Type == CorElementType.ELEMENT_TYPE_CHAR) { result = "'" + result + "'"; } return(prefix + result); } case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_VALUETYPE: CorObjectValue ov = value.CastToObjectValue(); return(prefix + PrintObject(indentLevel, ov, expandDepth, canDoFunceval)); case CorElementType.ELEMENT_TYPE_STRING: CorStringValue sv = value.CastToStringValue(); return(prefix + '"' + sv.String + '"'); case CorElementType.ELEMENT_TYPE_SZARRAY: case CorElementType.ELEMENT_TYPE_ARRAY: CorArrayValue av = value.CastToArrayValue(); return(prefix + PrintArray(indentLevel, av, expandDepth, canDoFunceval)); case CorElementType.ELEMENT_TYPE_PTR: return(prefix + "<non-null pointer>"); case CorElementType.ELEMENT_TYPE_FNPTR: return(prefix + "0x" + value.CastToReferenceValue().Value.ToString("X")); case CorElementType.ELEMENT_TYPE_BYREF: case CorElementType.ELEMENT_TYPE_TYPEDBYREF: case CorElementType.ELEMENT_TYPE_OBJECT: default: return(prefix + "<printing value of type: " + value.Type + " not implemented>"); } }
static void AddExceptionInfo(StringBuilder sb, CorValue exValue, string msg) { var exType = exValue?.ExactType; int? hr = EvalUtils.ReflectionReadExceptionHResult(exValue); string exMsg; EvalUtils.ReflectionReadExceptionMessage(exValue, out exMsg); string exTypeString = exType?.ToString() ?? dnSpy_Debugger_Resources.UnknownExceptionType; var s = string.Format(dnSpy_Debugger_Resources.ExceptionInfoFormat, msg, exTypeString, exMsg ?? dnSpy_Debugger_Resources.ExceptionMessageIsNull, hr ?? -1); sb.Append(s); }
public CorValue VariableExpressionInvoke(ExpressionParsingResult info) { //based on MdbgCommands.SetCmd(string arguments) if (info.Instance == null) { throw new Exception("Cannot resolve variable "); } if (info.Arguments == null || !info.Arguments.Any()) { throw new Exception("Cannot resolve arguments "); } // Arguments has to be in the form of variable=varName, variable=value or variable=(<type>)value, // where we use the ldasm naming convention (e.g. "int", "sbyte", "ushort", etc...) for <type>. // Example inputs: var=myInt, var=45, var=(long)45 MDbgValue lsMVar = new MDbgValue(process, info.Instance); CorValue val = info.Arguments.First(); CorGenericValue valGeneric = val as CorGenericValue; bool bIsReferenceValue = val is CorReferenceValue; if (lsMVar != null) { if (valGeneric != null) { CorValue lsVar = lsMVar.CorValue; if (lsVar == null) { throw new Exception("cannot set constant values to unavailable variables"); } // val is a primitive value CorGenericValue lsGenVal = lsVar.CastToGenericValue(); if (lsGenVal == null) { throw new Exception("cannot set constant values to non-primitive values"); } try { // We want to allow some type coercion. Eg, casting between integer precisions. lsMVar.Value = val; // This may do type coercion } catch (MDbgValueWrongTypeException) { throw new Exception(String.Format("Type mismatch. Can't convert from {0} to {1}", val.Type, lsGenVal.Type)); } } else if (bIsReferenceValue) { //reget variable lsMVar = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame); lsMVar.Value = val; } else { if (val.CastToHeapValue() != null) { throw new Exception("Heap values should be assigned only to debugger variables"); } if (val.CastToGenericValue() != null) { lsMVar.Value = val.CastToGenericValue(); } else { lsMVar.Value = val.CastToReferenceValue(); } } } // as a last thing we do is to return new value of the variable lsMVar = process.ResolveVariable(info.Member, process.Threads.Active.CurrentFrame); return(lsMVar.CorValue); }
void Push(CorValue arg) { if (arg == null) { eval.Invoke("DbgAgent.ObjectInspector.StackAddNull", obj); } else { string methodName = "DbgAgent.ObjectInspector.StackAdd_"; switch (arg.Type) { case CorElementType.ELEMENT_TYPE_R8: methodName += "R8"; break; case CorElementType.ELEMENT_TYPE_R4: methodName += "R4"; break; case CorElementType.ELEMENT_TYPE_U8: methodName += "U8"; break; case CorElementType.ELEMENT_TYPE_I8: methodName += "I8"; break; case CorElementType.ELEMENT_TYPE_U4: methodName += "U4"; break; case CorElementType.ELEMENT_TYPE_I4: methodName += "I4"; break; case CorElementType.ELEMENT_TYPE_U2: methodName += "U2"; break; case CorElementType.ELEMENT_TYPE_I2: methodName += "I2"; break; case CorElementType.ELEMENT_TYPE_U1: methodName += "U1"; break; case CorElementType.ELEMENT_TYPE_I1: methodName += "I1"; break; case CorElementType.ELEMENT_TYPE_CHAR: methodName += "I8"; break; case CorElementType.ELEMENT_TYPE_BOOLEAN: methodName += "BOOLEAN"; break; default: methodName += "OBJECT"; break; } eval.Invoke(methodName, obj, arg); } }
public RemoteInspector AddArg(CorValue arg) { args.Add(arg); return(this); }
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); }
EvalArgumentResult ConvertSZArray(string[] array, out DmdType type) { var elementType = reflectionAppDomain.System_String; type = elementType.MakeArrayType(); var corElementType = engine.GetType(appDomain, elementType); var res = dnEval.CreateSZArray(corElementType, array.Length, out int hr); if (res == null || !res.Value.NormalResult) { return(EvalArgumentResult.Create(res, hr)); } if (!IsInitialized(array)) { return(EvalArgumentResult.Create(res, hr)); } Debug.Assert(array.Length > 0); CorValue elem = null; bool error = true; try { var arrayValue = res.Value.ResultOrException; for (int i = 0; i < array.Length; i++) { var s = array[i]; if (s == null) { continue; } var stringValueRes = Convert(s, elementType, out var type2); if (stringValueRes.ErrorMessage != null) { return(stringValueRes); } if (!stringValueRes.CorValue.IsReference) { return(new EvalArgumentResult(PredefinedEvaluationErrorMessages.InternalDebuggerError)); } var av = arrayValue; if (av.IsReference) { av = av.DereferencedValue; } if (av?.IsArray != true) { return(new EvalArgumentResult(PredefinedEvaluationErrorMessages.InternalDebuggerError)); } Debug.Assert(elem == null); elem = av.GetElementAtPosition(i, out hr); if (elem == null) { return(new EvalArgumentResult(CordbgErrorHelper.GetErrorMessage(hr))); } elem.ReferenceAddress = stringValueRes.CorValue.ReferenceAddress; engine.DisposeHandle_CorDebug(elem); elem = null; } var eaRes = new EvalArgumentResult(AddValue(type, res.Value.ResultOrException)); error = false; return(eaRes); } finally { if (error) { engine.DisposeHandle_CorDebug(res.Value.ResultOrException); } engine.DisposeHandle_CorDebug(elem); } }
public EvalArgumentResult(CorValue corValue) { ErrorMessage = null; CorValue = corValue ?? throw new ArgumentNullException(nameof(corValue)); }
private void Initialize(MDbgProcess process, string name, CorValue value) { m_process = process; m_name = name; m_corValue = value; }
public CorValue RuntimeInvoke(CorEvaluationContext ctx, CorFunction function, CorType[] typeArgs, CorValue thisObj, CorValue[] arguments) { if (!ctx.Thread.ActiveChain.IsManaged) { throw new EvaluatorException("Cannot evaluate expression because the thread is stopped in native code."); } CorValue[] args; if (thisObj == null) { args = arguments; } else { args = new CorValue[arguments.Length + 1]; args[0] = thisObj; arguments.CopyTo(args, 1); } CorMethodCall mc = new CorMethodCall(); CorValue exception = null; CorEval eval = ctx.Eval; EvalEventHandler completeHandler = delegate(object o, CorEvalEventArgs eargs) { OnEndEvaluating(); mc.DoneEvent.Set(); eargs.Continue = false; }; EvalEventHandler exceptionHandler = delegate(object o, CorEvalEventArgs eargs) { OnEndEvaluating(); exception = eargs.Eval.Result; mc.DoneEvent.Set(); eargs.Continue = false; }; process.OnEvalComplete += completeHandler; process.OnEvalException += exceptionHandler; mc.OnInvoke = delegate { if (function.GetMethodInfo(this).Name == ".ctor") { eval.NewParameterizedObject(function, typeArgs, args); } else { eval.CallParameterizedFunction(function, typeArgs, args); } process.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, ctx.Thread); ClearEvalStatus(); OnStartEvaluating(); process.Continue(false); }; mc.OnAbort = delegate { eval.Abort(); }; mc.OnGetDescription = delegate { System.Reflection.MethodInfo met = function.GetMethodInfo(ctx.Session); if (met != null) { return(met.Name); } else { return("<Unknown>"); } }; try { ObjectAdapter.AsyncExecute(mc, ctx.Options.EvaluationTimeout); } finally { process.OnEvalComplete -= completeHandler; process.OnEvalException -= exceptionHandler; } if (exception != null) { /* ValueReference<CorValue, CorType> msg = ctx.Adapter.GetMember (ctx, val, "Message"); * if (msg != null) { * string s = msg.ObjectValue as string; * mc.ExceptionMessage = s; * } * else * mc.ExceptionMessage = "Evaluation failed.";*/ CorValRef vref = new CorValRef(exception); throw new EvaluatorException("Evaluation failed: " + ObjectAdapter.GetValueTypeName(ctx, vref)); } return(eval.Result); }
private string PrintObject(int indentLevel, CorObjectValue ov, int expandDepth, bool canDoFunceval) { Debug.Assert(expandDepth >= 0); bool fNeedToResumeThreads = true; // Print generics-aware type. string name = InternalUtil.PrintCorType(this.m_process, ov.ExactType); StringBuilder txt = new StringBuilder(); txt.Append(name); if (expandDepth > 0) { // we gather the field info of the class before we do // funceval since funceval requires running the debugger process // and this in turn can cause GC and invalidate our references. StringBuilder expandedDescription = new StringBuilder(); if (IsComplexType) { foreach (MDbgValue v in GetFields()) { expandedDescription.Append("\n").Append(IndentedString(indentLevel + 1, v.Name)). Append("=").Append(IndentedBlock(indentLevel + 2, v.GetStringValue(expandDepth - 1, false))); } } // if the value we're printing is a nullable type that has no value (is null), we can't do a func eval // to get its value, since it will be boxed as a null pointer. We already have the information we need, so // we'll just take care of it now. Note that ToString() for null-valued nullable types just prints the // empty string. // bool hasValue = (bool)(GetField("hasValue").CorValue.CastToGenericValue().GetValue()); if (IsNullableType(ov.ExactType) && !(bool)(GetField("hasValue").CorValue.CastToGenericValue().GetValue())) { txt.Append(" < >"); } else if (ov.IsValueClass && canDoFunceval) // we could display even values for real Objects, but we will just show // "description" for valueclasses. { CorClass cls = ov.ExactType.Class; CorMetadataImport importer = m_process.Modules.Lookup(cls.Module).Importer; MetadataType mdType = importer.GetType(cls.Token) as MetadataType; if (mdType.ReallyIsEnum) { txt.AppendFormat(" <{0}>", InternalGetEnumString(ov, mdType)); } else if (m_process.IsRunning) { txt.Append(" <N/A during run>"); } else { MDbgThread activeThread = m_process.Threads.Active; CorValue thisValue; CorHeapValue hv = ov.CastToHeapValue(); if (hv != null) { // we need to pass reference value. CorHandleValue handle = hv.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION); thisValue = handle; } else { thisValue = ov; } try { CorEval eval = m_process.Threads.Active.CorThread.CreateEval(); m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, activeThread.CorThread); MDbgFunction toStringFunc = m_process.ResolveFunctionName(null, "System.Object", "ToString", thisValue.ExactType.Class.Module.Assembly.AppDomain)[0]; Debug.Assert(toStringFunc != null); // we should be always able to resolve ToString function. eval.CallFunction(toStringFunc.CorFunction, new CorValue[] { thisValue }); m_process.Go(); do { m_process.StopEvent.WaitOne(); if (m_process.StopReason is EvalCompleteStopReason) { CorValue cv = eval.Result; Debug.Assert(cv != null); MDbgValue mv = new MDbgValue(m_process, cv); string valName = mv.GetStringValue(0); // just purely for esthetical reasons we 'discard' " if (valName.StartsWith("\"") && valName.EndsWith("\"")) { valName = valName.Substring(1, valName.Length - 2); } txt.Append(" <").Append(valName).Append(">"); break; } if ((m_process.StopReason is ProcessExitedStopReason) || (m_process.StopReason is EvalExceptionStopReason)) { txt.Append(" <N/A cannot evaluate>"); break; } // hitting bp or whatever should not matter -- we need to ignore it m_process.Go(); }while (true); } catch (COMException e) { // Ignore cannot copy a VC class error - Can't copy a VC with object refs in it. if (e.ErrorCode != (int)HResult.CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS) { throw; } } catch (System.NotImplementedException) { fNeedToResumeThreads = false; } finally { if (fNeedToResumeThreads) { // we need to resume all the threads that we have suspended no matter what. m_process.CorProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_RUN, activeThread.CorThread); } } } } txt.Append(expandedDescription.ToString()); } return(txt.ToString()); }
public EvalResult? Call(CorFunction func, CorType[] typeArgs, CorValue[] args, out int hr) { return WaitForResult(hr = eval.CallParameterizedFunction(func, typeArgs, args)); }
// Helper to get all the fields, including static fields and base types. private MDbgValue[] InternalGetFields() { List <MDbgValue> al = new List <MDbgValue>(); //dereference && (unbox); CorValue value = Dereference(CorValue, null); if (value == null) { throw new MDbgValueException("null value"); } Unbox(ref value); CorObjectValue ov = value.CastToObjectValue(); CorType cType = ov.ExactType; CorFrame cFrame = null; if (Process.Threads.HaveActive) { // we need a current frame to display thread local static values if (Process.Threads.Active.HaveCurrentFrame) { MDbgFrame temp = Process.Threads.Active.CurrentFrame; while (temp != null && !temp.IsManaged) { temp = temp.NextUp; } if (temp != null) { cFrame = temp.CorFrame; } } } MDbgModule classModule; // initialization CorClass corClass = ov.Class; classModule = Process.Modules.Lookup(corClass.Module); // iteration through class hierarchy while (true) { Type classType = classModule.Importer.GetType(corClass.Token); foreach (MetadataFieldInfo fi in classType.GetFields()) { CorValue fieldValue = null; try { if (fi.IsLiteral) { fieldValue = null; // for now we just hide the constant fields. continue; } else if (fi.IsStatic) { if (cFrame == null) { // Without a frame, we won't be able to find static values. So // just skip this guy continue; } fieldValue = cType.GetStaticFieldValue(fi.MetadataToken, cFrame); } else { // we are asuming normal field value fieldValue = ov.GetFieldValue(corClass, fi.MetadataToken); } } catch (COMException) { // we won't report any problems. } al.Add(new MDbgValue(Process, fi.Name, fieldValue)); } cType = cType.Base; if (cType == null) { break; } corClass = cType.Class; classModule = Process.Modules.Lookup(corClass.Module); } return(al.ToArray()); }
public void DisposeHandle(CorValue value) { var dbg = Debugger; if (dbg != null) dbg.DisposeHandle(value); }
public static T EvaluateCallMethod <T>(DnThread thread, CorValue thisObj, string methodName) { try { if (!DebuggerSettings.Instance.PropertyEvalAndFunctionCalls) { return(default(T)); } if (DebugManager.Instance.EvalDisabled) { return(default(T)); } if (!DebugManager.Instance.CanEvaluate) { return(default(T)); } if (thisObj == null || thisObj.IsNull) { return(default(T)); } var derefThisObj = thisObj.NeuterCheckDereferencedValue; if (derefThisObj == null) { return(default(T)); } var cls = derefThisObj.Class; if (cls == null) { return(default(T)); } var mod = cls.Module; if (mod == null) { return(default(T)); } var mdi = mod.GetMetaDataInterface <IMetaDataImport>(); if (mdi == null) { return(default(T)); } uint mdToken; int hr = mdi.FindMethod(cls.Token, methodName, IntPtr.Zero, 0, out mdToken); if (hr < 0) { return(default(T)); } var func = mod.GetFunctionFromToken(mdToken); if (func == null) { return(default(T)); } CorValueResult res; using (var eval = DebugManager.Instance.CreateEval(thread.CorThread)) res = eval.CallResult(func, null, new CorValue[] { thisObj }, out hr); if (hr < 0) { return(default(T)); } return((T)res.Value); } catch { } return(default(T)); }
void InitializeLocals(LocalInitType initType) { if (!IsEnabled || theDebugger.ProcessState != DebuggerProcessState.Paused) { ClearAllLocals(); return; } if (initType == LocalInitType.Simple) { // Property eval has completed, don't do a thing return; } var thread = stackFrameManager.SelectedThread; var frame = stackFrameManager.SelectedFrame; int frameNo = stackFrameManager.SelectedFrameNumber; DnProcess process; if (thread == null) { process = theDebugger.Debugger.Processes.FirstOrDefault(); thread = process == null ? null : process.Threads.FirstOrDefault(); } else { process = thread.Process; } var newFrameInfo = new FrameInfo(this, thread, process, frame, frameNo); if (frameInfo == null || !frameInfo.Equals(newFrameInfo)) { ClearAndDisposeChildren(); } frameInfo = newFrameInfo; CorValue[] corArgs, corLocals; if (frame != null) { corArgs = frame.ILArguments.ToArray(); corLocals = frame.ILLocals.ToArray(); } else { corArgs = corLocals = new CorValue[0]; } var args = new List <ICorValueHolder>(corArgs.Length); var locals = new List <ICorValueHolder>(corLocals.Length); for (int i = 0; i < corArgs.Length; i++) { args.Add(new LocArgCorValueHolder(theDebugger, true, this, corArgs[i], i)); } for (int i = 0; i < corLocals.Length; i++) { locals.Add(new LocArgCorValueHolder(theDebugger, false, this, corLocals[i], i)); } var exValue = thread == null ? null : thread.CorThread.CurrentException; var exValueHolder = exValue == null ? null : new DummyCorValueHolder(exValue); int numGenArgs = frameInfo.ValueContext.GenericTypeArguments.Count + frameInfo.ValueContext.GenericMethodArguments.Count; if (!CanReuseChildren(exValueHolder, args.Count, locals.Count, numGenArgs)) { ClearAndDisposeChildren(); } if (rootNode.Children.Count == 0) { hasInitializedArgNames = false; hasInitializedLocalNames = false; hasInitializedArgNamesFromMetadata = false; hasInitializedLocalNamesFromPdbFile = false; } List <TypeSig> argTypes; List <TypeSig> localTypes; if (frame != null) { frame.GetArgAndLocalTypes(out argTypes, out localTypes); } else { argTypes = localTypes = new List <TypeSig>(); } if (rootNode.Children.Count == 0) { if (exValueHolder != null) { rootNode.Children.Add(new CorValueVM(frameInfo.ValueContext, exValueHolder, null, new ExceptionValueType())); } for (int i = 0; i < args.Count; i++) { rootNode.Children.Add(new CorValueVM(frameInfo.ValueContext, args[i], Read(argTypes, i), new ArgumentValueType(i))); } for (int i = 0; i < locals.Count; i++) { rootNode.Children.Add(new CorValueVM(frameInfo.ValueContext, locals[i], Read(localTypes, i), new LocalValueType(i))); } if (numGenArgs != 0) { rootNode.Children.Add(new TypeVariablesValueVM(frameInfo.ValueContext)); } } else { int index = 0; if (exValueHolder != null) { if (index < rootNode.Children.Count && NormalValueVM.IsType <ExceptionValueType>(rootNode.Children[index])) { ((CorValueVM)rootNode.Children[index++]).Reinitialize(frameInfo.ValueContext, exValueHolder, null); } else { rootNode.Children.Insert(index++, new CorValueVM(frameInfo.ValueContext, exValueHolder, null, new ExceptionValueType())); } } else { if (index < rootNode.Children.Count && NormalValueVM.IsType <ExceptionValueType>(rootNode.Children[index])) { ValueVM.DisposeAndRemoveAt(rootNode, index); } } for (int i = 0; i < args.Count; i++, index++) { ((CorValueVM)rootNode.Children[index]).Reinitialize(frameInfo.ValueContext, args[i], Read(argTypes, i)); } for (int i = 0; i < locals.Count; i++, index++) { ((CorValueVM)rootNode.Children[index]).Reinitialize(frameInfo.ValueContext, locals[i], Read(localTypes, i)); } if (numGenArgs != 0) { ((TypeVariablesValueVM)rootNode.Children[index++]).Reinitialize(frameInfo.ValueContext); } } InitializeLocalAndArgNames(); if (!hasInitializedArgNames && !hasInitializedArgNamesFromMetadata) { InitializeArgNamesFromMetadata(); } if (!hasInitializedLocalNames && !hasInitializedLocalNamesFromPdbFile) { InitializeLocalNamesFromPdbFile(); } }
public void InvalidateCorValue() { value?.DisposeHandle(); value = null; }
internal void DisposeHandle_CorDebug(CorValue value) { Debug.Assert(debuggerThread.CheckAccess()); dnDebugger.DisposeHandle(value); }
public override string CallToString(EvaluationContext ctx, object objr) { CorValue obj = GetRealObject(ctx, objr); if ((obj is CorReferenceValue) && ((CorReferenceValue)obj).IsNull) { return(string.Empty); } CorStringValue stringVal = obj as CorStringValue; if (stringVal != null) { return(stringVal.String); } CorArrayValue arr = obj as CorArrayValue; if (arr != null) { StringBuilder tn = new StringBuilder(GetDisplayTypeName(ctx, arr.ExactType.FirstTypeParameter)); tn.Append("["); int[] dims = arr.GetDimensions(); for (int n = 0; n < dims.Length; n++) { if (n > 0) { tn.Append(','); } tn.Append(dims[n]); } tn.Append("]"); return(tn.ToString()); } CorEvaluationContext cctx = (CorEvaluationContext)ctx; CorObjectValue co = obj as CorObjectValue; if (co != null) { if (IsEnum(ctx, co.ExactType)) { MetadataType rt = co.ExactType.GetTypeInfo(cctx.Session) as MetadataType; bool isFlags = rt != null && rt.ReallyIsFlagsEnum; string enumName = GetTypeName(ctx, co.ExactType); ValueReference val = GetMember(ctx, null, objr, "value__"); ulong nval = (ulong)System.Convert.ChangeType(val.ObjectValue, typeof(ulong)); ulong remainingFlags = nval; string flags = null; foreach (ValueReference evals in GetMembers(ctx, co.ExactType, null, BindingFlags.Public | BindingFlags.Static)) { ulong nev = (ulong)System.Convert.ChangeType(evals.ObjectValue, typeof(ulong)); if (nval == nev) { return(evals.Name); } if (isFlags && nev != 0 && (nval & nev) == nev) { if (flags == null) { flags = enumName + "." + evals.Name; } else { flags += " | " + enumName + "." + evals.Name; } remainingFlags &= ~nev; } } if (isFlags) { if (remainingFlags == nval) { return(nval.ToString()); } if (remainingFlags != 0) { flags += " | " + remainingFlags; } return(flags); } else { return(nval.ToString()); } } CorType targetType = (CorType)GetValueType(ctx, objr); MethodInfo met = OverloadResolve(cctx, "ToString", targetType, new CorType[0], BindingFlags.Public | BindingFlags.Instance, false); if (met != null && met.DeclaringType.FullName != "System.Object") { object[] args = new object[0]; object ores = RuntimeInvoke(ctx, targetType, objr, "ToString", args, args); CorStringValue res = GetRealObject(ctx, ores) as CorStringValue; if (res != null) { return(res.String); } } return(GetDisplayTypeName(ctx, targetType)); } CorGenericValue genVal = obj as CorGenericValue; if (genVal != null) { return(genVal.GetValue().ToString()); } return(base.CallToString(ctx, obj)); }
internal DbgDotNetValueResult Box_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, CorValue value, DmdType type) { debuggerThread.VerifyAccess(); evalInfo.CancellationToken.ThrowIfCancellationRequested(); var tmp = CheckFuncEval(evalInfo); if (tmp != null) { return(tmp.Value); } var dnThread = GetThread(evalInfo.Frame.Thread); var createdValues = new List <CorValue>(); CorValue boxedValue = null; try { using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) { dnEval.SetThread(dnThread); dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout); dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo); boxedValue = BoxIfNeeded(dnEval, appDomain, createdValues, value, type.AppDomain.System_Object, type); if (boxedValue == null) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(-1))); } return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(boxedValue, type.AppDomain, tryCreateStrongHandle: true))); } } catch (TimeoutException) { return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError)); } finally { foreach (var v in createdValues) { if (boxedValue != v) { dnDebugger.DisposeHandle(v); } } } }
public override object TryCast(EvaluationContext ctx, object val, object type) { CorType ctype = (CorType)GetValueType(ctx, val); CorValue obj = GetRealObject(ctx, val); string tname = GetTypeName(ctx, type); string ctypeName = GetValueTypeName(ctx, val); if (tname == "System.Object") { return(val); } if (tname == ctypeName) { return(val); } if (obj is CorStringValue) { return(ctypeName == tname ? val : null); } if (obj is CorArrayValue) { return((ctypeName == tname || ctypeName == "System.Array") ? val : null); } if (obj is CorObjectValue) { CorObjectValue co = (CorObjectValue)obj; if (IsEnum(ctx, co.ExactType)) { ValueReference rval = GetMember(ctx, null, val, "value__"); return(TryCast(ctx, rval.Value, type)); } while (ctype != null) { if (GetTypeName(ctx, ctype) == tname) { return(val); } ctype = ctype.Base; } return(null); } CorGenericValue genVal = obj as CorGenericValue; if (genVal != null) { Type t = Type.GetType(tname); if (t != null && t.IsPrimitive && t != typeof(string)) { object pval = genVal.GetValue(); try { pval = System.Convert.ChangeType(pval, t); } catch { return(null); } return(CreateValue(ctx, pval)); } else if (IsEnum(ctx, (CorType)type)) { return(CreateEnum(ctx, (CorType)type, val)); } } return(null); }
string StoreSimpleValue_CorDebug(DnThread dnThread, CorValue targetValue, DmdType targetType, object sourceValue) { if (targetType.IsByRef) { return(CordbgErrorHelper.InternalError); } int hr; if (targetType.IsPointer || targetType.IsFunctionPointer) { var sourceValueBytes = TryGetValueBytes(sourceValue); Debug.Assert(sourceValueBytes != null); if (sourceValueBytes == null || targetValue.Size != (uint)sourceValueBytes.Length) { return(CordbgErrorHelper.InternalError); } ulong address = targetValue.Address; if (address == 0) { return(CordbgErrorHelper.InternalError); } hr = dnThread.Process.CorProcess.WriteMemory(address, sourceValueBytes, 0, sourceValueBytes.Length, out var sizeWritten); if (hr < 0) { return(CordbgErrorHelper.GetErrorMessage(hr)); } return(null); } else if (!targetType.IsValueType) { if (sourceValue != null) { return(CordbgErrorHelper.InternalError); } hr = targetValue.SetReferenceAddress(0); if (hr != 0) { return(CordbgErrorHelper.GetErrorMessage(hr)); } return(null); } else { if (targetValue.IsReference) { targetValue = targetValue.GetDereferencedValue(out hr); if (targetValue == null) { return(CordbgErrorHelper.GetErrorMessage(hr)); } } if (targetValue.IsBox) { return(CordbgErrorHelper.InternalError); } if (!targetValue.IsGeneric || sourceValue == null) { return(CordbgErrorHelper.InternalError); } var sourceValueBytes = TryGetValueBytes(sourceValue); Debug.Assert(sourceValueBytes != null); if (sourceValueBytes == null || targetValue.Size != (uint)sourceValueBytes.Length) { return(CordbgErrorHelper.InternalError); } hr = targetValue.WriteGenericValue(sourceValueBytes, dnThread.Process.CorProcess); if (hr < 0) { return(CordbgErrorHelper.GetErrorMessage(hr)); } return(null); } }
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 EvalArgumentResult(string errorMessage) { ErrorMessage = errorMessage ?? throw new ArgumentNullException(nameof(errorMessage)); CorValue = null; }
public static CachedOutput CreateType(CorValue value, TypePrinterFlags flags) => CreateType(new TypeOutput(), value, flags).cachedOutput;
public DebuggerValue(Debugger debugger, CorValue value) { debugger.Dispatcher.VerifyAccess(); this.debugger = debugger; CorValue = value; hashCode = value.GetHashCode(); address = value.Address; size = value.Size; elementType = (CorElementType)value.ElementType; vflags = 0; if (value.IsGeneric) vflags |= VFlags.Generic; if (value.IsReference) { vflags |= VFlags.Reference; if (value.IsNull) vflags |= VFlags.Null; } if (value.IsHandle) vflags |= VFlags.Handle; if (value.IsArray) vflags |= VFlags.Array; if (value.IsBox) vflags |= VFlags.Box; if (value.IsString) vflags |= VFlags.String; if (value.IsObject) { vflags |= VFlags.Object; if (value.IsValueClass) vflags |= VFlags.ValueClass; } if (value.IsContext) vflags |= VFlags.Context; if (value.IsComObject) vflags |= VFlags.ComObject; if (value.IsExceptionObject) vflags |= VFlags.ExObject; if (value.IsHeap) vflags |= VFlags.Heap; }
public CreateCorValueResult(CorValue value, int hr, bool canDispose = true) { Value = value; HResult = hr; CanDispose = canDispose; }
public CorValRef(ValueLoader loader) { this.val = loader(); this.loader = loader; this.version = CorDebuggerSession.EvaluationTimestamp; }
public DebuggerValue(Debugger debugger, CorValue value) { debugger.Dispatcher.VerifyAccess(); this.debugger = debugger; this.value = value; this.hashCode = value.GetHashCode(); this.address = value.Address; this.size = value.Size; this.elementType = (CorElementType)value.Type; this.vflags = 0; if (value.IsGeneric) { this.vflags |= VFlags.Generic; } if (value.IsReference) { this.vflags |= VFlags.Reference; if (value.IsNull) { this.vflags |= VFlags.Null; } } if (value.IsHandle) { this.vflags |= VFlags.Handle; } if (value.IsArray) { this.vflags |= VFlags.Array; } if (value.IsBox) { this.vflags |= VFlags.Box; } if (value.IsString) { this.vflags |= VFlags.String; } if (value.IsObject) { this.vflags |= VFlags.Object; if (value.IsValueClass) { this.vflags |= VFlags.ValueClass; } } if (value.IsContext) { this.vflags |= VFlags.Context; } if (value.IsComObject) { this.vflags |= VFlags.ComObject; } if (value.IsExceptionObject) { this.vflags |= VFlags.ExObject; } if (value.IsHeap) { this.vflags |= VFlags.Heap; } }
public CorValue Box(CorValue value) { Debug.Assert(value != null && value.IsGeneric && !value.IsBox && !value.IsHeap && value.ExactType.IsValueType); if (value == null || !value.IsGeneric || value.IsBox || value.IsHeap || !value.ExactType.IsValueType) return value; var res = WaitForResult(eval.NewParameterizedObjectNoConstructor(value.ExactType.Class, value.ExactType.TypeParameters.ToArray())); if (res == null || res.Value.WasException) return null; var newObj = res.Value.ResultOrException; var r = newObj.NeuterCheckDereferencedValue; var vb = r == null ? null : r.BoxedValue; if (vb == null) return null; int hr = vb.WriteGenericValue(value.ReadGenericValue()); if (hr < 0) return null; return newObj; }
public LocArgCorValueHolder(ITheDebugger theDebugger, bool isArg, LocalsVM locals, CorValue value, int index) { this.theDebugger = theDebugger; this.isArg = isArg; this.locals = locals; this.value = value; this.index = index; }
public EvalResult Call(CorFunction func, CorType[] typeArgs, CorValue[] args) { int hr; var res = Call(func, typeArgs, args, out hr); if (res != null) return res.Value; throw new EvalException(hr, string.Format("Could not call method {0:X8}, HR=0x{1:X8}", func.Token, hr)); }
public void InvalidateCorValue() { theDebugger.DisposeHandle(value); value = null; }
public CorValueResult CallResult(CorFunction func, CorValue[] args) { return CallResult(func, null, args); }
public EvalResult CallConstructor(CorFunction ctor, CorValue[] args) => CallConstructor(ctor, null, args);
public EvalResult(bool wasException, CorValue resultOrException) { this.WasException = wasException; this.ResultOrException = resultOrException; }
public EvalResult CallConstructor(CorFunction ctor, CorType[] typeArgs, CorValue[] args) { int hr; var res = CallConstructor(ctor, typeArgs, args, out hr); if (res != null) return res.Value; throw new EvalException(hr, string.Format("Could not call .ctor {0:X8}, HR=0x{1:X8}", ctor.Token, hr)); }
static void AddExceptionInfo(StringBuilder sb, CorValue exValue, string msg) { var exType = exValue == null ? null : exValue.ExactType; int? hr = EvalUtils.ReflectionReadExceptionHResult(exValue); string exMsg = EvalUtils.ReflectionReadExceptionMessage(exValue); string exTypeString = exType == null ? "<Unknown Exception Type>" : exType.ToString(); var s = string.Format("{0}: {1}\n\nMessage: {2}\n\nHResult: 0x{3:X8}", msg, exTypeString, exMsg, hr ?? -1); sb.Append(s); }
public EvalResult? CallConstructor(CorFunction func, CorType[] typeArgs, CorValue[] args, out int hr) => WaitForResult(hr = eval.NewParameterizedObject(func, typeArgs, args));
public DummyCorValueHolder(CorValue value) { this.value = value; }
public EvalResult(bool wasException, CorValue resultOrException) { WasException = wasException; ResultOrException = resultOrException; }
public void DisposeHandle(CorValue value) { if (value == null || !value.IsHandle) return; if (ProcessState != DebuggerProcessState.Running) value.DisposeHandle(); else disposeValues.Add(value); }
string GetExceptionMessage(CorValue exValue) { string exMsg; if (EvalUtils.ReflectionReadExceptionMessage(exValue, out exMsg)) return exMsg ?? dnSpy_Debugger_Resources.ExceptionMessageIsNull; return "???"; }