/// <summary> /// Get a CorType that function for this frame is declared in. /// </summary> /// <returns>The cortype of the function</returns> private CorType GetClassType() { CorClass c = thisFrame.Function.Class; if (TokenUtils.RidFromToken(c.Token) != 1 && TokenUtils.RidFromToken(c.Token) != 0) { // ICorDebug API lets us always pass ET_Class CorElementType et = CorElementType.ELEMENT_TYPE_CLASS; // Get type parameters. IEnumerable typars = thisFrame.TypeParameters; //IEnumerator tyenum = typars.GetEnumerator(); int cNumTyParamsOnClass = metaImporter.CountGenericParams(c.Token); CorType[] types = new CorType[cNumTyParamsOnClass]; int it = 0; foreach (CorType arg in typars) { if (it == cNumTyParamsOnClass) { break; } types[it] = arg; it++; } return(c.GetParameterizedType(et, types)); } else { return(null); } }
public IDebuggerMethod[] GetConstructors() => debugger.Dispatcher.UI(() => { var ctors = CorClass.FindConstructors(); var res = new IDebuggerMethod[ctors.Length]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerMethod(debugger, ctors[i]); } return(res); });
public IDebuggerField[] GetFields(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var fields = CorClass.FindFields(name, checkBaseClasses).ToList(); var res = new IDebuggerField[fields.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerField(debugger, fields[i]); } return(res); });
public IDebuggerProperty[] GetProperties(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var props = CorClass.FindProperties(name, checkBaseClasses).ToList(); var res = new IDebuggerProperty[props.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerProperty(debugger, props[i]); } return(res); });
public IDebuggerEvent[] GetEvents(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var events = CorClass.FindEvents(name, checkBaseClasses).ToList(); var res = new IDebuggerEvent[events.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerEvent(debugger, events[i]); } return(res); });
public IDebuggerMethod[] GetMethods(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var funcs = CorClass.FindFunctions(name, checkBaseClasses).ToList(); var res = new IDebuggerMethod[funcs.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerMethod(debugger, funcs[i]); } return(res); });
public DebuggerClass(Debugger debugger, CorClass cls) { debugger.Dispatcher.VerifyAccess(); this.debugger = debugger; CorClass = cls; hashCode = cls.GetHashCode(); Token = cls.Token; Attributes = cls.GetTypeAttributes(); }
void InitializeNamespaceName() { debugger.Dispatcher.VerifyAccess(); Debug.Assert(name == null); string tmpNs, tmpName; CorClass.GetName(out tmpNs, out tmpName); @namespace = tmpNs; name = tmpName ?? string.Empty; }
public static CachedOutput CreateType(CorValue value, CorClass cls, TypePrinterFlags flags) { var valueOutput = CreateType(new TypeOutput(), value, flags); if (cls == null || value == null) { return(valueOutput.cachedOutput); } var typeOutput = value.WriteType(new TypeOutput(), cls, flags); return(CreateTypeInternal(valueOutput, typeOutput)); }
public IDebuggerEvent[] GetEvents(bool checkBaseClasses) { if (!checkBaseClasses) { return(Events); } return(debugger.Dispatcher.UI(() => { var events = CorClass.FindEvents(checkBaseClasses).ToList(); var res = new IDebuggerEvent[events.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerEvent(debugger, events[i]); } return res; })); }
public IDebuggerField[] GetFields(bool checkBaseClasses) { if (!checkBaseClasses) { return(Fields); } return(debugger.Dispatcher.UI(() => { var fields = CorClass.FindFields(checkBaseClasses).ToList(); var res = new IDebuggerField[fields.Count]; for (int i = 0; i < res.Length; i++) { res[i] = new DebuggerField(debugger, fields[i]); } return res; })); }
public override object GetEnclosingType(EvaluationContext gctx) { CorEvaluationContext ctx = (CorEvaluationContext)gctx; if (ctx.Frame.FrameType != CorFrameType.ILFrame || ctx.Frame.Function == null) { return(null); } CorClass cls = ctx.Frame.Function.Class; List <CorType> tpars = new List <CorType> (); foreach (CorType t in ctx.Frame.TypeParameters) { tpars.Add(t); } return(cls.GetParameterizedType(CorElementType.ELEMENT_TYPE_CLASS, tpars.ToArray())); }
void OnUnloadClass(DnModule dnModule, CorClass cls) { if (dnModule == null || !dnModule.IsDynamic || cls == null) { return; } var cmd = dnModule.CorModuleDef; if (cmd == null) { return; } Debug.Assert(classLoader != null); if (classLoader == null) { return; } classLoader.UnloadClass(dnModule, cls.Token); }
public override object GetType(EvaluationContext gctx, string name, object[] gtypeArgs) { CorType[] typeArgs = CastArray <CorType> (gtypeArgs); CorEvaluationContext ctx = (CorEvaluationContext)gctx; foreach (CorModule mod in ctx.Session.GetModules()) { CorMetadataImport mi = ctx.Session.GetMetadataForModule(mod.Name); if (mi != null) { foreach (Type t in mi.DefinedTypes) { if (t.FullName == name) { CorClass cls = mod.GetClassFromToken(t.MetadataToken); return(cls.GetParameterizedType(CorElementType.ELEMENT_TYPE_CLASS, typeArgs)); } } } } return(null); }
/// <summary> /// Gets the full class path of the function /// </summary> /// <param name="sb">string builder to be used to create full class path</param> /// <param name="ct">The cortype of the function</param> // Ignore the complexity warning - don't want to rewrite it now. private void GetFunctionClassPath(StringBuilder sb, CorType ct) { //StringBuilder sb, CorType ct, CorMetadataImport importer switch (ct.Type) { case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_VALUETYPE: // We need to get the name from the metadata. We can get a cached metadata importer // from a MDbgModule, or we could get a new one from the CorModule directly. // Is this hash lookup to get a MDbgModule cheaper than just re-querying for the importer? CorClass cc = ct.Class; Type tn = metaImporter.GetType(cc.Token); sb.Append(tn.FullName); //AddGenericArgs(sb, proc, ct.TypeParameters); return; // Primitives case CorElementType.ELEMENT_TYPE_BOOLEAN: sb.Append("System.Boolean"); return; case CorElementType.ELEMENT_TYPE_CHAR: sb.Append("System.Char"); return; case CorElementType.ELEMENT_TYPE_I1: sb.Append("System.SByte"); return; case CorElementType.ELEMENT_TYPE_U1: sb.Append("System.Byte"); return; case CorElementType.ELEMENT_TYPE_I2: sb.Append("System.Int16"); return; case CorElementType.ELEMENT_TYPE_U2: sb.Append("System.UInt16"); return; case CorElementType.ELEMENT_TYPE_I4: sb.Append("System.Int32"); return; case CorElementType.ELEMENT_TYPE_U4: sb.Append("System.Uint32"); return; case CorElementType.ELEMENT_TYPE_I8: sb.Append("System.Int64"); return; case CorElementType.ELEMENT_TYPE_U8: sb.Append("System.UInt64"); return; case CorElementType.ELEMENT_TYPE_I: sb.Append("System.IntPtr"); return; case CorElementType.ELEMENT_TYPE_U: sb.Append("System.UIntPtr"); return; case CorElementType.ELEMENT_TYPE_R4: sb.Append("System.Single"); return; case CorElementType.ELEMENT_TYPE_R8: sb.Append("System.Double"); return; // Well known class-types. case CorElementType.ELEMENT_TYPE_OBJECT: sb.Append("System.Object"); return; case CorElementType.ELEMENT_TYPE_STRING: sb.Append("System.String"); return; // Special compound types. Based off first type-param case CorElementType.ELEMENT_TYPE_SZARRAY: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_BYREF: case CorElementType.ELEMENT_TYPE_PTR: CorType t = ct.FirstTypeParameter; GetFunctionClassPath(sb, t); switch (ct.Type) { case CorElementType.ELEMENT_TYPE_SZARRAY: sb.Append("[]"); return; case CorElementType.ELEMENT_TYPE_ARRAY: int rank = ct.Rank; sb.Append('['); for (int i = 0; i < rank - 1; i++) { // <strip>@todo- could we print out exact boundaries? // Probably would have to do some sort of func-eval on the array object.</strip> sb.Append(','); } sb.Append(']'); return; case CorElementType.ELEMENT_TYPE_BYREF: sb.Append("&"); return; case CorElementType.ELEMENT_TYPE_PTR: sb.Append("*"); return; } Debug.Assert(false); // shouldn't have gotten here. return; // <strip>Other wacky stuff. // @todo - can we do a better job of printing these?</strip> case CorElementType.ELEMENT_TYPE_FNPTR: sb.Append("*(...)"); return; case CorElementType.ELEMENT_TYPE_TYPEDBYREF: sb.Append("typedbyref"); return; default: sb.Append("<unknown>"); return; } }
public IDebuggerEvent GetEvent(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var evt = CorClass.FindEvent(name, checkBaseClasses); return(evt == null ? null : new DebuggerEvent(debugger, evt)); });
public IDebuggerProperty GetProperty(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var prop = CorClass.FindProperty(name, checkBaseClasses); return(prop == null ? null : new DebuggerProperty(debugger, prop)); });
void OnUnloadClass(DnModule dnModule, CorClass cls) { if (dnModule == null || !dnModule.IsDynamic || cls == null) return; var cmd = dnModule.CorModuleDef; if (cmd == null) return; Debug.Assert(classLoader != null); if (classLoader == null) return; classLoader.UnloadClass(dnModule, cls.Token); }
// Print CorType to the given string builder. // Will print generic info. internal static void PrintCorType(StringBuilder sb, MDbgProcess proc, CorType ct) { switch (ct.Type) { case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_VALUETYPE: // We need to get the name from the metadata. We can get a cached metadata importer // from a MDbgModule, or we could get a new one from the CorModule directly. // Is this hash lookup to get a MDbgModule cheaper than just re-querying for the importer? CorClass cc = ct.Class; MDbgModule m = proc.Modules.Lookup(cc.Module); Type tn = m.Importer.GetType(cc.Token); sb.Append(tn.FullName); AddGenericArgs(sb, proc, ct.TypeParameters); return; // Primitives case CorElementType.ELEMENT_TYPE_BOOLEAN: sb.Append("System.Boolean"); return; case CorElementType.ELEMENT_TYPE_CHAR: sb.Append("System.Char"); return; case CorElementType.ELEMENT_TYPE_I1: sb.Append("System.SByte"); return; case CorElementType.ELEMENT_TYPE_U1: sb.Append("System.Byte"); return; case CorElementType.ELEMENT_TYPE_I2: sb.Append("System.Int16"); return; case CorElementType.ELEMENT_TYPE_U2: sb.Append("System.UInt16"); return; case CorElementType.ELEMENT_TYPE_I4: sb.Append("System.Int32"); return; case CorElementType.ELEMENT_TYPE_U4: sb.Append("System.Uint32"); return; case CorElementType.ELEMENT_TYPE_I8: sb.Append("System.Int64"); return; case CorElementType.ELEMENT_TYPE_U8: sb.Append("System.UInt64"); return; case CorElementType.ELEMENT_TYPE_I: sb.Append("System.IntPtr"); return; case CorElementType.ELEMENT_TYPE_U: sb.Append("System.UIntPtr"); return; case CorElementType.ELEMENT_TYPE_R4: sb.Append("System.Single"); return; case CorElementType.ELEMENT_TYPE_R8: sb.Append("System.Double"); return; // Well known class-types. case CorElementType.ELEMENT_TYPE_OBJECT: sb.Append("System.Object"); return; case CorElementType.ELEMENT_TYPE_STRING: sb.Append("System.String"); return; // Special compound types. Based off first type-param case CorElementType.ELEMENT_TYPE_SZARRAY: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_BYREF: case CorElementType.ELEMENT_TYPE_PTR: CorType t = ct.FirstTypeParameter; PrintCorType(sb, proc, t); switch (ct.Type) { case CorElementType.ELEMENT_TYPE_SZARRAY: sb.Append("[]"); return; case CorElementType.ELEMENT_TYPE_ARRAY: int rank = ct.Rank; sb.Append('['); for (int i = 0; i < rank - 1; i++) { sb.Append(','); } sb.Append(']'); return; case CorElementType.ELEMENT_TYPE_BYREF: sb.Append("&"); return; case CorElementType.ELEMENT_TYPE_PTR: sb.Append("*"); return; } Debug.Assert(false); // shouldn't have gotten here. return; case CorElementType.ELEMENT_TYPE_FNPTR: sb.Append("*(...)"); return; case CorElementType.ELEMENT_TYPE_TYPEDBYREF: sb.Append("typedbyref"); return; default: sb.Append("<unknown>"); return; } } // end PrintClass
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 string ToString(TypeFormatFlags flags) => debugger.Dispatcher.UI(() => CorClass.ToString((TypePrinterFlags)flags));
public DnModule TryGetModule(CorAppDomain appDomain, CorClass cls) { if (appDomain == null || cls == null) return null; var clsMod = cls.Module; if (clsMod == null) return null; var ad = TryGetAppDomain(appDomain.RawObject); if (ad == null) return null; var asm = TryGetValidAssembly(appDomain.RawObject, clsMod.RawObject); if (asm == null) return null; return asm.TryGetModule(clsMod.RawObject); }
/// <summary> /// Create a new instance of the ClassLoadedStopReason class. /// </summary> /// <param name="managedClass">The class that has been loaded.</param> public ClassLoadedStopReason(CorClass managedClass) { Debug.Assert(managedClass != null); m_class = managedClass; }
public bool HasAttribute(string attributeName) => debugger.Dispatcher.UI(() => CorClass.HasAttribute(attributeName));
public DebuggerClass(Debugger debugger, CorClass cls) { debugger.Dispatcher.VerifyAccess(); this.debugger = debugger; this.cls = cls; this.hashCode = cls.GetHashCode(); this.token = cls.Token; this.attributes = cls.GetTypeAttributes(); }
public bool SetJustMyCode(bool jmc) => debugger.Dispatcher.UI(() => CorClass.SetJustMyCode(jmc));
public bool IsSystem(string name) => debugger.Dispatcher.UI(() => CorClass.IsSystem(name));
public void Write(IOutputWriter output, TypeFormatFlags flags) => debugger.Dispatcher.UI(() => CorClass.Write(new OutputWriterConverter(output), (TypePrinterFlags)flags));
// 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 override string ToString() => debugger.Dispatcher.UI(() => CorClass.ToString(DEFAULT_FLAGS));
public IDebuggerField GetField(string name, bool checkBaseClasses) => debugger.Dispatcher.UI(() => { var field = CorClass.FindField(name, checkBaseClasses); return(field == null ? null : new DebuggerField(debugger, field)); });
private MDbgValue[] InternalGetFields() { ArrayList al = new ArrayList(); //dereference && (unbox); CorValue value = Dereference(CorValue); 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) { cFrame = Process.Threads.Active.CurrentFrame.CorFrame; } } MDbgModule classModule; // initialization CorClass corClass = ov.Class; classModule = Process.Modules.Lookup(corClass.Module); // iteration through class hierarchy do { Type classType; //int parentToken; classType = classModule.Importer.GetType(corClass.Token); //classModule.Importer.GetTypeNameFromDef(classToken,out parentToken); 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) { fieldValue = cType.GetStaticFieldValue(fi.MetadataToken, cFrame); } else // we are asuming normal field value // GetFieldValueForTYpe Supersedes GetFieldValue // Will replace when all issues are resolved. //fieldValue = ov.GetFieldValueForType(cType, (uint)fi.Token); { 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); }while (true); return((MDbgValue[])al.ToArray(typeof(MDbgValue))); }
public CorValue CreateValue(CorElementType et, CorClass cls = null) => eval.CreateValue(et, cls);