public IColumnModel Build(string databaseName, ClrType clrType) { return new ColumnModel { DatabaseName = databaseName, ParameterName = _nameConverter.ToParameterName(databaseName), PropertyName = _nameConverter.ToPropertyName(databaseName), ClrType = clrType }; }
static Platform() { #if IOS || UNITY_IPHONE _os = OS.IOS; _runtime = ClrType.Mono; #elif ANDROID || UNITY_ANDROID _os = OS.Android; _runtime = ClrType.Mono; #elif WINDOWS_PHONE_APP _os = OS.WindowsPhone; _runtime = ClrType.NetFxCore; #elif NETFX_CORE _os = OS.Windows; _runtime = ClrType.NetFxCore; #else PlatformID pid = Environment.OSVersion.Platform; if (pid == PlatformID.MacOSX) { //This never works, it is a bug in Mono _os = OS.MacOSX; } else { int p = (int)pid; _os = ((p == 4) || (p == 128)) ? OS.Linux : OS.Windows; if (_os == OS.Linux) { //Check if the OS is Mac OSX IntPtr buf = IntPtr.Zero; try { buf = Marshal.AllocHGlobal(8192); // This is a hacktastic way of getting sysname from uname () if (uname(buf) == 0) { string os = Marshal.PtrToStringAnsi(buf); if (os == "Darwin") _os = OS.MacOSX; } } catch { //Some unix system may not be able to call "libc" //such as Ubuntu 13.04, we provide a safe catch here } finally { if (buf != IntPtr.Zero) Marshal.FreeHGlobal(buf); } } } _runtime = (Type.GetType("System.MonoType", false) != null) ? ClrType.Mono : ClrType.DotNet; #endif }
public NativeException( ClrType clrType, Address ccwPtr, ulong hResult, ulong threadId, ulong exceptionId, ulong innerExceptionId, ulong nestingLevel, IList<ClrStackFrame> stackFrames) { _type = clrType; _ccwPtr = ccwPtr; _hResult = hResult; _threadId = threadId; _exceptionId = exceptionId; _innerExceptionId = innerExceptionId; _nestingLevel = nestingLevel; _stackFrames = stackFrames; }
internal abstract IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type);
public override ulong GetFirstObject(out ClrType type) { throw new NotImplementedException(); }
protected override void EnumerateObjectReferences(ulong obj, ClrType type, bool carefully, Action <ulong, int> callback) { throw new NotImplementedException(); }
private bool GetStackTraceFromField(ClrType type, ulong obj, out ulong stackTrace) { stackTrace = 0; var field = type.GetFieldByName("_stackTrace"); if (field == null) return false; object tmp = field.GetValue(obj); if (tmp == null || !(tmp is ulong)) return false; stackTrace = (ulong)tmp; return true; }
public NativeHandleRoot(Address addr, Address obj, ClrType type, int hndType, ClrAppDomain domain, string name) { Init(addr, obj, 0, type, hndType, domain, name); }
private DesktopBlockingObject CreateRWSObject(ulong obj, ClrType type) { if (type == null) return new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None); ClrInstanceField field = type.GetFieldByName("writeLockOwnerId"); if (field != null && field.ElementType == ClrElementType.Int32) { int id = (int)field.GetValue(obj); ClrThread thread = GetThreadById(id); if (thread != null) return new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired); } field = type.GetFieldByName("upgradeLockOwnerId"); if (field != null && field.ElementType == ClrElementType.Int32) { int id = (int)field.GetValue(obj); ClrThread thread = GetThreadById(id); if (thread != null) return new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired); } field = type.GetFieldByName("rwc"); if (field != null) { List<ClrThread> threads = null; ulong rwc = (ulong)field.GetValue(obj); ClrType rwcArrayType = _heap.GetObjectType(rwc); if (rwcArrayType != null && rwcArrayType.IsArray && rwcArrayType.ComponentType != null) { ClrType rwcType = rwcArrayType.ComponentType; ClrInstanceField threadId = rwcType.GetFieldByName("threadid"); ClrInstanceField next = rwcType.GetFieldByName("next"); if (threadId != null && next != null) { int count = rwcArrayType.GetArrayLength(rwc); for (int i = 0; i < count; ++i) { ulong entry = (ulong)rwcArrayType.GetArrayElementValue(rwc, i); GetThreadEntry(ref threads, threadId, next, entry, false); } } } if (threads != null) return new DesktopBlockingObject(obj, true, 0, BlockingReason.ReaderAcquired, threads.ToArray()); } return new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None); }
public override ClrType GetObjectType(ulong objRef) { ulong eeType; if (m_lastObj == objRef) return m_lastType; var cache = MemoryReader; if (!cache.Contains(objRef)) cache = m_runtime.MemoryReader; if (!cache.ReadPtr(objRef, out eeType)) return null; if ((((int)eeType) & 3) != 0) eeType &= ~3UL; ClrType last = null; int index; if (m_indices.TryGetValue(eeType, out index)) last = m_types[index]; else last = ConstructObjectType(eeType); m_lastObj = objRef; m_lastType = last; return last; }
internal List <FieldInfo> GetFieldInfos(ClrType type) { List <FieldInfo> fieldNames = Eval(() => GetFieldNamesImpl(type)); return(fieldNames); }
public object GetFieldValue(ulong address, ClrType type, ClrInstanceField field) { var obj = Eval(() => GetFieldValueImpl(address, type, field)); return(obj); }
public object GetFieldValue(ulong address, ClrType type, List <string> fieldNames) { var obj = Eval(() => GetFieldValueImpl(address, type, fieldNames)); return(obj); }
public object GetSimpleValue(ulong address, ClrType type) { var obj = Eval(() => GetSimpleValueImpl(address, type)); return(obj); }
public bool IsPrimitive(ClrType type) { var res = Eval(() => type.IsPrimitive); return(res); }
public bool IsString(ClrType type) { var res = Eval(() => type.IsString); return(res); }
public int CountInstances(ClrType type) { int typeId = cache.GetTypeId(type.Name); return(cache.CountInstances(typeId)); }
public override IEnumerable <ClrReference> EnumerateReferencesWithFields(ulong obj, ClrType type, bool carefully, bool considerDependantHandles) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (considerDependantHandles) { ImmutableArray <(ulong Source, ulong Target)> dependent = GetHeapData().GetDependentHandles(_helpers); if (dependent.Length > 0) { int index = dependent.Search(obj, (x, y) => x.Source.CompareTo(y)); if (index != -1) { while (index >= 1 && dependent[index - 1].Source == obj) { index--; } while (index < dependent.Length && dependent[index].Source == obj) { ulong dependantObj = dependent[index++].Target; ClrObject target = new ClrObject(dependantObj, GetObjectType(dependantObj)); yield return(ClrReference.CreateFromDependentHandle(target)); } } } } if (type.ContainsPointers) { GCDesc gcdesc = type.GCDesc; if (!gcdesc.IsEmpty) { ulong size = GetObjectSize(obj, type); if (carefully) { ClrSegment?seg = GetSegmentByAddress(obj); if (seg is null || obj + size > seg.End || (!seg.IsLargeObjectSegment && size > MaxGen2ObjectSize)) { yield break; } } foreach ((ulong reference, int offset) in gcdesc.WalkObject(obj, size, _helpers.DataReader)) { ClrObject target = new ClrObject(reference, GetObjectType(reference)); yield return(ClrReference.CreateFromFieldOrArray(target, type, offset)); } } } }
public DesktopManagedWorkItem(ClrType type, ulong addr) { m_type = type; m_addr = addr; }
public FieldInfo(string name, ClrType fieldType) { Name = name; FieldType = fieldType; }
public RhStaticVar(RhRuntime runtime, Address addr, Address obj, ClrType type, string name, bool pinned, bool interior) { Address = addr; Object = obj; m_type = type; m_name = name; m_pinned = pinned; m_interior = interior; m_type = runtime.GetHeap().GetObjectType(obj); m_appDomain = runtime.GetRhAppDomain(); }
/// <nodoc /> public ClrEnumTypeInfo(ClrType clrType) => ClrType = clrType;
public DesktopInterfaceData(ClrType type, Address ptr) { _type = type; _interface = ptr; }
public TypeStat(ClrType clrObjectType) { MethodTable = clrObjectType?.MethodTable; }
public NativeStaticVar(NativeRuntime runtime, Address addr, Address obj, ClrType type, string name, bool pinned, bool interior) { Address = addr; Object = obj; _type = type; _name = name; _pinned = pinned; _interior = interior; _type = runtime.GetHeap().GetObjectType(obj); _appDomain = runtime.GetRhAppDomain(); }
public override int GetHashCode() { // 一个CLR类型至多映射为一种实体类型 return(ClrType.GetHashCode()); }
internal override IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type) { List <ClrStackFrame> result = new List <ClrStackFrame>(); if (!GetStackTraceFromField(type, obj, out ulong _stackTrace)) { if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace)) { return(result); } } if (_stackTrace == 0) { return(result); } DesktopGCHeap heap = (DesktopGCHeap)Heap; ClrType stackTraceType = heap.GetObjectType(_stackTrace); if (stackTraceType == null) { stackTraceType = heap.ArrayType; } if (!stackTraceType.IsArray) { return(result); } int len = stackTraceType.GetArrayLength(_stackTrace); if (len == 0) { return(result); } int elementSize = CLRVersion == DesktopVersion.v2 ? IntPtr.Size * 4 : IntPtr.Size * 3; ulong dataPtr = _stackTrace + (ulong)(IntPtr.Size * 2); if (!ReadPointer(dataPtr, out ulong count)) { return(result); } // Skip size and header dataPtr += (ulong)(IntPtr.Size * 2); DesktopThread thread = null; for (int i = 0; i < (int)count; ++i) { if (!ReadPointer(dataPtr, out ulong ip)) { break; } if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out ulong sp)) { break; } if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out ulong md)) { break; } if (i == 0) { thread = (DesktopThread)GetThreadByStackAddress(sp); } result.Add(new DesktopStackFrame(this, thread, null, ip, sp, md)); dataPtr += (ulong)elementSize; } return(result); }
private void SetThreadWaiters() { HashSet <string> eventTypes = null; List <BlockingObject> blobjs = new List <BlockingObject>(); foreach (DesktopThread thread in _runtime.Threads) { int max = thread.StackTrace.Count; if (max > 10) { max = 10; } blobjs.Clear(); for (int i = 0; i < max; ++i) { DesktopBlockingObject blockingObj = null; ClrMethod method = thread.StackTrace[i].Method; if (method == null) { continue; } ClrType type = method.Type; if (type == null) { continue; } switch (method.Name) { case "AcquireWriterLockInternal": case "FCallUpgradeToWriterLock": case "UpgradeToWriterLock": case "AcquireReaderLockInternal": case "AcquireReaderLock": if (type.Name == "System.Threading.ReaderWriterLock") { blockingObj = FindLocks(thread.StackLimit, thread.StackTrace[i].StackPointer, IsReaderWriterLock); if (blockingObj == null) { blockingObj = FindLocks(thread.StackTrace[i].StackPointer, thread.StackBase, IsReaderWriterLock); } if (blockingObj != null && (blockingObj.Reason == BlockingReason.Unknown || blockingObj.Reason == BlockingReason.None)) { // This should have already been set correctly when the BlockingObject was created. This is just a best-guess. if (method.Name == "AcquireReaderLockInternal" || method.Name == "AcquireReaderLock") { blockingObj.Reason = BlockingReason.WriterAcquired; } else { blockingObj.Reason = BlockingReason.ReaderAcquired; } } } break; case "TryEnterReadLockCore": case "TryEnterReadLock": case "TryEnterUpgradeableReadLock": case "TryEnterUpgradeableReadLockCore": case "TryEnterWriteLock": case "TryEnterWriteLockCore": if (type.Name == "System.Threading.ReaderWriterLockSlim") { blockingObj = FindLocks(thread.StackLimit, thread.StackTrace[i].StackPointer, IsReaderWriterSlim); if (blockingObj == null) { blockingObj = FindLocks(thread.StackTrace[i].StackPointer, thread.StackBase, IsReaderWriterSlim); } if (blockingObj != null && (blockingObj.Reason == BlockingReason.Unknown || blockingObj.Reason == BlockingReason.None)) { // This should have already been set correctly when the BlockingObject was created. This is just a best-guess. if (method.Name == "TryEnterWriteLock" || method.Name == "TryEnterWriteLockCore") { blockingObj.Reason = BlockingReason.ReaderAcquired; } else { blockingObj.Reason = BlockingReason.WriterAcquired; } } } break; case "JoinInternal": case "Join": if (type.Name == "System.Threading.Thread") { ulong threadAddr; ClrThread target; if (FindThread(thread.StackLimit, thread.StackTrace[i].StackPointer, out threadAddr, out target) || FindThread(thread.StackTrace[i].StackPointer, thread.StackBase, out threadAddr, out target)) { if (!_joinLocks.TryGetValue(target, out blockingObj)) { _joinLocks[target] = blockingObj = new DesktopBlockingObject(threadAddr, true, 0, target, BlockingReason.ThreadJoin); } } } break; case "Wait": case "ObjWait": if (type.Name == "System.Threading.Monitor") { blockingObj = FindMonitor(thread.StackLimit, thread.StackTrace[i].StackPointer); if (blockingObj == null) { blockingObj = FindMonitor(thread.StackTrace[i].StackPointer, thread.StackBase); } blockingObj.Reason = BlockingReason.MonitorWait; } break; case "WaitAny": case "WaitAll": if (type.Name == "System.Threading.WaitHandle") { ulong obj = FindWaitObjects(thread.StackLimit, thread.StackTrace[i].StackPointer, "System.Threading.WaitHandle[]"); if (obj == 0) { obj = FindWaitObjects(thread.StackTrace[i].StackPointer, thread.StackBase, "System.Threading.WaitHandle[]"); } if (obj != 0) { BlockingReason reason = method.Name == "WaitAny" ? BlockingReason.WaitAny : BlockingReason.WaitAll; if (!_waitLocks.TryGetValue(obj, out blockingObj)) { _waitLocks[obj] = blockingObj = new DesktopBlockingObject(obj, true, 0, null, reason); } } } break; case "WaitOne": case "InternalWaitOne": case "WaitOneNative": if (type.Name == "System.Threading.WaitHandle") { if (eventTypes == null) { eventTypes = new HashSet <string>(); eventTypes.Add("System.Threading.Mutex"); eventTypes.Add("System.Threading.Semaphore"); eventTypes.Add("System.Threading.ManualResetEvent"); eventTypes.Add("System.Threading.AutoResetEvent"); eventTypes.Add("System.Threading.WaitHandle"); eventTypes.Add("Microsoft.Win32.SafeHandles.SafeWaitHandle"); } ulong obj = FindWaitHandle(thread.StackLimit, thread.StackTrace[i].StackPointer, eventTypes); if (obj == 0) { obj = FindWaitHandle(thread.StackTrace[i].StackPointer, thread.StackBase, eventTypes); } if (obj != 0) { if (_waitLocks == null) { _waitLocks = new Dictionary <ulong, DesktopBlockingObject>(); } if (!_waitLocks.TryGetValue(obj, out blockingObj)) { _waitLocks[obj] = blockingObj = new DesktopBlockingObject(obj, true, 0, null, BlockingReason.WaitOne); } } } break; case "TryEnter": case "ReliableEnterTimeout": case "TryEnterTimeout": case "Enter": if (type.Name == "System.Threading.Monitor") { blockingObj = FindMonitor(thread.StackLimit, thread.StackTrace[i].StackPointer); if (blockingObj != null) { blockingObj.Reason = BlockingReason.Monitor; } } break; } if (blockingObj != null) { bool alreadyEncountered = false; foreach (var blobj in blobjs) { if (blobj.Object == blockingObj.Object) { alreadyEncountered = true; break; } } if (!alreadyEncountered) { blobjs.Add(blockingObj); } } } foreach (DesktopBlockingObject blobj in blobjs) { blobj.AddWaiter(thread); } thread.SetBlockingObjects(blobjs.ToArray()); } }
protected override IEnumerable <ClrObjectReference> EnumerateObjectReferencesWithFields(ulong obj, ClrType type, bool carefully) { throw new NotImplementedException(); }
internal DesktopBlockingObject[] InitLockInspection() { if (_result != null) { return(_result); } // First, enumerate all thinlocks on the heap. foreach (var seg in _heap.Segments) { for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj)) { ClrType type = _heap.GetObjectType(obj); if (IsReaderWriterLock(obj, type)) { _locks[obj] = CreateRWLObject(obj, type); } else if (IsReaderWriterSlim(obj, type)) { _locks[obj] = CreateRWSObject(obj, type); } // Does this object have a syncblk with monitor associated with it? uint header; if (!_heap.GetObjectHeader(obj, out header)) { continue; } if ((header & (BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_SPIN_LOCK)) != 0) { continue; } uint threadId = header & SBLK_MASK_LOCK_THREADID; if (threadId == 0) { continue; } ClrThread thread = _runtime.GetThreadFromThinlockID(threadId); if (thread != null) { int recursion = ((int)header & SBLK_MASK_LOCK_RECLEVEL) >> SBLK_RECLEVEL_SHIFT; _monitors[obj] = new DesktopBlockingObject(obj, true, recursion + 1, thread, BlockingReason.Monitor); } } } // Enumerate syncblocks to find locks int syncblkCnt = _runtime.GetSyncblkCount(); for (int i = 0; i < syncblkCnt; ++i) { ISyncBlkData data = _runtime.GetSyncblkData(i); if (data == null || data.Free) { continue; } _syncblks[data.Address] = data.Object; _syncblks[data.Object] = data.Object; ClrThread thread = null; if (data.MonitorHeld) { ulong threadAddr = data.OwningThread; foreach (var clrThread in _runtime.Threads) { if (clrThread.Address == threadAddr) { thread = clrThread; break; } } } _monitors[data.Object] = new DesktopBlockingObject(data.Object, data.MonitorHeld, (int)data.Recursion, thread, BlockingReason.Monitor); } SetThreadWaiters(); int total = _monitors.Count + _locks.Count + _joinLocks.Count + _waitLocks.Count; _result = new DesktopBlockingObject[total]; int j = 0; foreach (DesktopBlockingObject blocker in _monitors.Values) { _result[j++] = blocker; } foreach (DesktopBlockingObject blocker in _locks.Values) { _result[j++] = blocker; } foreach (DesktopBlockingObject blocker in _joinLocks.Values) { _result[j++] = blocker; } foreach (DesktopBlockingObject blocker in _waitLocks.Values) { _result[j++] = blocker; } Debug.Assert(j == _result.Length); // Free up some memory. _monitors = null; _locks = null; _joinLocks = null; _waitLocks = null; _syncblks = null; return(_result); }
public override ulong NextObject(ulong objRef, out ClrType type) { throw new NotImplementedException(); }
public static string ManageAlias(ClrType type) { return(type != null?ManageAlias(type.Name) : "????"); }
static Platform() { #if __IOS__ || UNITY_IPHONE _os = OS.IOS; _runtime = ClrType.Mono; #elif __ANDROID__ || UNITY_ANDROID _os = OS.Android; _runtime = ClrType.Mono; #elif WINDOWS_PHONE_APP _os = OS.WindowsPhone; _runtime = ClrType.NetFxCore; #elif NETFX_CORE _os = OS.Windows; _runtime = ClrType.NetFxCore; #elif NETSTANDARD1_4 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { _os = OS.Windows; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { _os = OS.Linux; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { _os = OS.MacOS; } else { //unknown } //how??? _runtime = ClrType.NetFxCore; #else PlatformID pid = Environment.OSVersion.Platform; if (pid == PlatformID.MacOSX) { //This never works, it is a bug in Mono _os = OS.MacOS; } else { int p = (int)pid; _os = ((p == 4) || (p == 128)) ? OS.Linux : OS.Windows; if (_os == OS.Linux) { //Check if the OS is Mac OSX IntPtr buf = IntPtr.Zero; try { buf = Marshal.AllocHGlobal(8192); // This is a hacktastic way of getting sysname from uname () if (uname(buf) == 0) { string os = Marshal.PtrToStringAnsi(buf); if (os == "Darwin") { _os = OS.MacOS; } } } catch { //Some unix system may not be able to call "libc" //such as Ubuntu 13.04, we provide a safe catch here } finally { if (buf != IntPtr.Zero) { Marshal.FreeHGlobal(buf); } } } } _runtime = (Type.GetType("System.MonoType", false) != null) ? ClrType.Mono : ClrType.DotNet; #endif }
/// <summary> /// Initializes a new instance of the <see cref="FilteredObjectProviderByTypeName"/> class. /// </summary> /// <param name="clrType">Type of the color.</param> public FilteredObjectProviderByTypeName([NotNull] ClrType clrType) : this(clrType.Name) { }
bool GetFieldObject(ClrType type, ulong obj, string fieldName, out ClrType valueType, out ulong value) { value = 0; valueType = null; ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) return false; value = (ulong)field.GetValue(obj); if (value == 0) return false; valueType = m_heap.GetObjectType(value); return valueType != null; }
protected FrameworkInfo(SerializationInfo info, StreamingContext context) { _name = info.GetString("Name"); _family = info.GetString("Family"); _description = info.GetString("Description"); _status = (InitStatus) info.GetValue("Status", typeof(InitStatus)); _clrType = (ClrType) info.GetValue("ClrType", typeof(ClrType)); _version = (Version) info.GetValue("Version", typeof(Version)); _clrVersion = (Version) info.GetValue("ClrVersion", typeof(Version)); _vendor = (VendorType) info.GetValue("Vendor", typeof(VendorType)); if (_status != InitStatus.Valid) { return; } _frameworkDirectory = (DirectoryInfo) info.GetValue("FrameworkDirectory", typeof(DirectoryInfo)); _sdkDirectory = (DirectoryInfo) info.GetValue("SdkDirectory", typeof(DirectoryInfo)); _frameworkAssemblyDirectory = (DirectoryInfo) info.GetValue("FrameworkAssemblyDirectory", typeof(DirectoryInfo)); _runtime = (Runtime) info.GetValue("Runtime", typeof(Runtime)); _project = (Project) info.GetValue("Project", typeof(Project)); _taskAssemblies = (FileSet) info.GetValue("TaskAssemblies", typeof(FileSet)); _referenceAssemblies = (FileSet[]) info.GetValue("ReferenceAssemblies", typeof(FileSet[])); _toolPaths = (string[]) info.GetValue("ToolPaths", typeof(string[])); }
public RhFinalizerRoot(Address obj, ClrType type, ClrAppDomain domain, string name) { Object = obj; m_name = name; m_type = type; m_appDomain = domain; }
private bool IsReaderWriterSlim(ulong obj, ClrType type) { if (type == null) return false; if (_rwsType == null) { if (type.Name != "System.Threading.ReaderWriterLockSlim") return false; _rwsType = type; return true; } return _rwsType == type; }
public DesktopStaticField(DesktopGCHeap heap, IFieldData field, BaseDesktopHeapType containingType, string name, FieldAttributes attributes, object defaultValue, IntPtr sig, int sigLen) { _field = field; _name = name; _attributes = attributes; _type = (BaseDesktopHeapType)heap.GetTypeByMethodTable(field.TypeMethodTable, 0); _defaultValue = defaultValue; _heap = heap; _token = field.FieldToken; if (_type != null && ElementType != ClrElementType.Class) { _type.ElementType = ElementType; } _containingType = containingType; if (_type == null) { if (sig != IntPtr.Zero && sigLen > 0) { SigParser sigParser = new SigParser(sig, sigLen); bool res; int etype = 0; if (res = sigParser.GetCallingConvInfo(out int sigType)) { Debug.Assert(sigType == SigParser.IMAGE_CEE_CS_CALLCONV_FIELD); } res = res && sigParser.SkipCustomModifiers(); res = res && sigParser.GetElemType(out etype); if (res) { ClrElementType type = (ClrElementType)etype; if (type == ClrElementType.Array) { res = sigParser.PeekElemType(out etype); res = res && sigParser.SkipExactlyOne(); int ranks = 0; res = res && sigParser.GetData(out ranks); if (res) { _type = heap.GetArrayType((ClrElementType)etype, ranks, null); } } else if (type == ClrElementType.SZArray) { res = sigParser.PeekElemType(out etype); type = (ClrElementType)etype; if (DesktopRuntimeBase.IsObjectReference(type)) { _type = (BaseDesktopHeapType)heap.GetBasicType(ClrElementType.SZArray); } else { _type = (BaseDesktopHeapType)heap.GetArrayType(type, -1, null); } } else if (type == ClrElementType.Pointer) { // Only deal with single pointers for now and types that have already been constructed res = sigParser.GetElemType(out etype); type = (ClrElementType)etype; sigParser.GetToken(out int token); BaseDesktopHeapType innerType = (BaseDesktopHeapType)heap.GetGCHeapTypeFromModuleAndToken(field.Module, Convert.ToUInt32(token)); if (innerType == null) { innerType = (BaseDesktopHeapType)heap.GetBasicType(type); } _type = heap.CreatePointerType(innerType, type, null); } } } } if (_type == null) { _typeResolver = new Lazy <ClrType>(() => { ClrType type = (BaseDesktopHeapType)TryBuildType(_heap); if (type == null) { type = (BaseDesktopHeapType)heap.GetBasicType(ElementType); } return(type); }); } }
public RhHandleRoot(Address addr, Address obj, Address dependentTarget, ClrType type, int hndType, ClrAppDomain domain, string name) { Init(addr, obj, dependentTarget, type, hndType, domain, name); }
public NativeFinalizerRoot(Address obj, ClrType type, ClrAppDomain domain, string name) { Object = obj; _name = name; _type = type; _appDomain = domain; }
private DesktopBlockingObject CreateRWLObject(ulong obj, ClrType type) { if (type == null) return new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None); ClrInstanceField writerID = type.GetFieldByName("_dwWriterID"); if (writerID != null && writerID.ElementType == ClrElementType.Int32) { int id = (int)writerID.GetValue(obj); if (id > 0) { ClrThread thread = GetThreadById(id); if (thread != null) return new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.ReaderAcquired); } } ClrInstanceField uLock = type.GetFieldByName("_dwULockID"); ClrInstanceField lLock = type.GetFieldByName("_dwLLockID"); if (uLock != null && uLock.ElementType == ClrElementType.Int32 && lLock != null && lLock.ElementType == ClrElementType.Int32) { int uId = (int)uLock.GetValue(obj); int lId = (int)lLock.GetValue(obj); List<ClrThread> threads = null; foreach (ClrThread thread in _runtime.Threads) { foreach (IRWLockData l in _runtime.EnumerateLockData(thread.Address)) { if (l.LLockID == lId && l.ULockID == uId && l.Level > 0) { if (threads == null) threads = new List<ClrThread>(); threads.Add(thread); break; } } } if (threads != null) return new DesktopBlockingObject(obj, true, 0, BlockingReason.ReaderAcquired, threads.ToArray()); } return new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None); }
/// <summary> /// Code from http://stackoverflow.com/questions/2057781/is-there-a-way-to-get-the-stacktraces-for-all-threads-in-c-like-java-lang-thre/24315960#24315960 /// also see http://stackoverflow.com/questions/31633541/clrmd-throws-exception-when-creating-runtime/31745689#31745689 /// </summary> internal IList <OutputLine> PrintCodeForMethod(Benchmark benchmark, Process process, bool printAssembly, bool printIL, bool printDiagnostics) { this.process = process; logger.Clear(); //Method name format: "BenchmarkDotNet.Samples.Infra.RunFast()" (NOTE: WITHOUT the return type) var methodInfo = benchmark.Target.Method; fullTypeName = methodInfo.DeclaringType.FullName; var methodParams = string.Join(", ", methodInfo.GetParameters().Select(p => p.ParameterType.FullName)); fullMethodName = $"{fullTypeName}.{methodInfo.Name}({methodParams})"; logger?.WriteLine($"\nPrinting Code for Method: {fullMethodName}"); logger?.WriteLine($"\nPrintAssembly={printAssembly}, PrintIL={printIL}"); logger?.WriteLine($"Attaching to process {Path.GetFileName(process.MainModule.FileName)}, Pid={process.Id}"); logger?.WriteLine($"Path {process.MainModule.FileName}"); using (var dataTarget = DataTarget.AttachToProcess(process.Id, 5000, AttachFlag.NonInvasive)) { var runtime = SetupClrRuntime(dataTarget); if (printDiagnostics) { PrintRuntimeDiagnosticInfo(dataTarget, runtime); } if (printAssembly == false && printIL == false) { return(logger.CapturedOutput); } ClrType @class = runtime.GetHeap().GetTypeByName(fullTypeName); ClrMethod @method = @class.Methods.Single(m => m.GetFullSignature() == fullMethodName); DesktopModule module = (DesktopModule)@method.Type.Module; if (!module.IsPdbLoaded) { string pdbLocation = module.TryDownloadPdb(null); if (pdbLocation != null) { module.LoadPdb(pdbLocation); } } logger?.WriteLine($"Module: {Path.GetFileName(module.Name)}"); logger?.WriteLine($"Type: {method.Type.Name}"); logger?.WriteLine($"Method: {method.Name}"); // TODO work out why this returns locations inside OTHER methods, it's like it doesn't have an upper bound and just keeps going!? var ilOffsetLocations = module.GetSourceLocationsForMethod(@method.MetadataToken); string filePath = null; string[] lines = null; logger?.WriteLine(); for (int i = 0; i < ilOffsetLocations.Count; i++) { var location = ilOffsetLocations[i]; var ilMaps = @method.ILOffsetMap.Where(il => il.ILOffset == location.ILOffset).ToList(); if (ilMaps.Any() == false) { continue; } if (lines == null || location.SourceLocation.FilePath != filePath) { filePath = location.SourceLocation.FilePath; lines = File.ReadAllLines(filePath); logger?.WriteLine($"Parsing file {Path.GetFileName(location.SourceLocation.FilePath)}"); } PrintLocationAndILMapInfo(@method, location, ilMaps); PrintSourceCode(lines, location); if (printAssembly) { var debugControl = dataTarget.DebuggerInterface as IDebugControl; PrintAssemblyCode(@method, ilMaps, runtime, debugControl); } } return(logger.CapturedOutput); } }
public LocalVarRoot(ulong addr, ulong obj, ClrType type, ClrAppDomain domain, ClrThread thread, bool pinned, bool falsePos, bool interior) { Address = addr; Object = obj; _pinned = pinned; _falsePos = falsePos; _interior = interior; _domain = domain; _thread = thread; _type = type; }
public DesktopManagedWorkItem(ClrType type, ulong addr) { _type = type; _addr = addr; }
public NativeStackRoot(ClrThread thread, ulong addr, ulong obj, string name, ClrType type, ClrAppDomain domain, bool pinned, bool interior) { Address = addr; Object = obj; _name = name; _type = type; _appDomain = domain; _pinned = pinned; _interior = interior; _thread = thread; }
private IEnumerable <ulong> EnumerateManagedThreadpoolObjects() { _heap = _runtime.Heap; ClrModule mscorlib = GetMscorlib(); if (mscorlib != null) { ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals"); if (queueType != null) { ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue"); if (workQueueField != null) { foreach (var appDomain in _runtime.AppDomains) { object workQueueValue = workQueueField.GetValue(appDomain); ulong workQueue = workQueueValue == null ? 0L : (ulong)workQueueValue; ClrType workQueueType = _heap.GetObjectType(workQueue); if (workQueue == 0 || workQueueType == null) { continue; } ulong queueHead; do { ClrType queueHeadType, nodesType; ulong nodes; if (!GetFieldObject(workQueueType, workQueue, "queueHead", out queueHeadType, out queueHead)) { break; } if (GetFieldObject(queueHeadType, queueHead, "nodes", out nodesType, out nodes) && nodesType.IsArray) { int len = nodesType.GetArrayLength(nodes); for (int i = 0; i < len; ++i) { ulong addr = (ulong)nodesType.GetArrayElementValue(nodes, i); if (addr != 0) { yield return(addr); } } } if (!GetFieldObject(queueHeadType, queueHead, "Next", out queueHeadType, out queueHead)) { break; } } while (queueHead != 0); } } } queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue"); if (queueType != null) { ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues"); if (threadQueuesField != null) { foreach (ClrAppDomain domain in _runtime.AppDomains) { ulong?threadQueue = (ulong?)threadQueuesField.GetValue(domain); if (!threadQueue.HasValue || threadQueue.Value == 0) { continue; } ClrType threadQueueType = _heap.GetObjectType(threadQueue.Value); if (threadQueueType == null) { continue; } ClrType outerArrayType; ulong outerArray; if (!GetFieldObject(threadQueueType, threadQueue.Value, "m_array", out outerArrayType, out outerArray) || !outerArrayType.IsArray) { continue; } int outerLen = outerArrayType.GetArrayLength(outerArray); for (int i = 0; i < outerLen; ++i) { ulong entry = (ulong)outerArrayType.GetArrayElementValue(outerArray, i); if (entry == 0) { continue; } ClrType entryType = _heap.GetObjectType(entry); if (entryType == null) { continue; } ClrType arrayType; ulong array; if (!GetFieldObject(entryType, entry, "m_array", out arrayType, out array) || !arrayType.IsArray) { continue; } int len = arrayType.GetArrayLength(array); for (int j = 0; j < len; ++j) { ulong addr = (ulong)arrayType.GetArrayElementValue(array, i); if (addr != 0) { yield return(addr); } } } } } } } }
private void Init(Address addr, Address obj, Address dependentTarget, ClrType type, int hndType, ClrAppDomain domain, string name) { HandleType htype = (HandleType)hndType; switch (htype) { case HandleType.AsyncPinned: _kind = GCRootKind.AsyncPinning; break; case HandleType.Pinned: _kind = GCRootKind.Pinning; break; case HandleType.WeakShort: case HandleType.WeakLong: _kind = GCRootKind.Weak; break; default: _kind = GCRootKind.Strong; break; } Address = addr; _name = name; _type = type; _appDomain = domain; if (htype == HandleType.Dependent && dependentTarget != 0) Object = dependentTarget; else Object = obj; }
public static ClrMethod GetMethod(this ClrType type, string name) { return(GetMethods(type, name).Single()); }
internal abstract IList<ClrStackFrame> GetExceptionStackTrace(Address obj, ClrType type);
public static IEnumerable <ClrMethod> GetMethods(this ClrType type, string name) { return(type.Methods.Where(m => m.Name == name)); }
internal override IList<ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type) { // TODO: Review this and if it works on v4.5, merge the two implementations back into RuntimeBase. List<ClrStackFrame> result = new List<ClrStackFrame>(); if (type == null) return result; ulong _stackTrace; if (!GetStackTraceFromField(type, obj, out _stackTrace)) { if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace)) return result; } if (_stackTrace == 0) return result; ClrHeap heap = GetHeap(); ClrType stackTraceType = heap.GetObjectType(_stackTrace); if (stackTraceType == null || !stackTraceType.IsArray) return result; int len = stackTraceType.GetArrayLength(_stackTrace); if (len == 0) return result; int elementSize = IntPtr.Size * 4; ulong dataPtr = _stackTrace + (ulong)(IntPtr.Size * 2); ulong count = 0; if (!ReadPointer(dataPtr, out count)) return result; // Skip size and header dataPtr += (ulong)(IntPtr.Size * 2); DesktopThread thread = null; for (int i = 0; i < (int)count; ++i) { ulong ip, sp, md; if (!ReadPointer(dataPtr, out ip)) break; if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out sp)) break; if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out md)) break; if (i == 0) thread = (DesktopThread)GetThreadByStackAddress(sp); result.Add(new DesktopStackFrame(this, thread, ip, sp, md)); dataPtr += (ulong)elementSize; } return result; }
public override ClrType GetObjectType(ulong objRef) { ulong eeType; if (_lastObj == objRef) return _lastType; var cache = MemoryReader; if (!cache.Contains(objRef)) cache = NativeRuntime.MemoryReader; if (!cache.ReadPtr(objRef, out eeType)) return null; ClrType last = this.GetTypeByMethodTable(eeType); _lastObj = objRef; _lastType = last; return last; }