private static void VerifyStringObjectSize(ClrRuntime runtime, ClrType type, ulong obj, string text) { var objSize = type.GetSize(obj); var objAsHex = obj.ToString("x"); var rawBytes = Encoding.Unicode.GetBytes(text); if (runtime.ClrInfo.Version.Major == 2) { // This only works in .NET 2.0, the "m_array_Length" field was removed in .NET 4.0 var arrayLength = (int)type.GetFieldByName("m_arrayLength").GetValue(obj); var stringLength = (int)type.GetFieldByName("m_stringLength").GetValue(obj); var calculatedSize = (((ulong)arrayLength - 1) * 2) + HeaderSize; if (objSize != calculatedSize) { Console.WriteLine("Object Size Mismatch: arrayLength: {0,4}, stringLength: {1,4}, Object Size: {2,4}, Object: {3} -> \n\"{4}\"", arrayLength, stringLength, objSize, objAsHex, text); } } else { // In .NET 4.0 we can do a more normal check, i.e. ("object size" - "raw byte array length") should equal the expected header size var theRest = objSize - (ulong)rawBytes.Length; if (theRest != HeaderSize) { Console.WriteLine("Object Size Mismatch: Raw Bytes Length: {0,4}, Object Size: {1,4}, Object: {2} -> \n\"{3}\"", rawBytes.Length, objSize, objAsHex, text); } } }
public void InnerStructSizeTest() { // https://github.com/microsoft/clrmd/issues/101 using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule sharedLibrary = runtime.GetModule("sharedlibrary.dll"); ClrType structTestClass = sharedLibrary.GetTypeByName("StructTestClass"); ClrType structTest = sharedLibrary.GetTypeByName("Struct"); Assert.NotNull(structTest); ClrInstanceField field = structTestClass.GetFieldByName("s"); if (dt.CacheOptions.CacheTypes) { Assert.Same(structTest, field.Type); } else { Assert.Equal(structTest, field.Type); } Assert.Equal(sizeof(int), field.Size); ClrInstanceField nes = structTestClass.GetFieldByName("nes"); Assert.Equal(0, nes.Size); ClrInstanceField es = nes.Type.GetFieldByName("es"); Assert.Equal(0, es.Size); }
private Dictionary <int, string> GetManagedThreadNames(ClrHeap heap) { var result = new Dictionary <int, string>(); if (heap == null || !heap.CanWalkHeap) { return(result); } var threadObjects = from obj in heap.EnumerateObjectAddresses() let type = heap.GetObjectType(obj) where type != null && type.Name == "System.Threading.Thread" select obj; ClrType threadType = heap.GetTypeByName("System.Threading.Thread"); ClrInstanceField nameField = threadType.GetFieldByName("m_Name"); ClrInstanceField managedIdField = threadType.GetFieldByName("m_ManagedThreadId"); foreach (var threadObject in threadObjects) { string name = (string)nameField.GetValue(threadObject); int id = (int)managedIdField.GetValue(threadObject); result[id] = name; } return(result); }
public ValuePointer?this[string fieldName] { get { var field = Type.GetFieldByName(fieldName); if (field == null) { throw new Exception("No field with this name"); } ulong address; if (field.IsObjectReference()) { var fieldValue = field.GetValue(Address); if (fieldValue == null) { return(null); } address = (ulong)fieldValue; } else { address = field.GetAddress(Address, false); } if (address == 0) { return(null); } return(new ValuePointer(address, field.Type, this.Heap)); } }
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 static string GetStringContents(ClrHeap heap, ulong strAddr) { if (strAddr == 0L) { return(null); } ClrType clrType = heap.GetObjectType(strAddr); var firstCharField = clrType.GetFieldByName("m_firstChar"); var stringLengthField = clrType.GetFieldByName("m_stringLength"); int length = 0; if (stringLengthField != null) { length = (int)stringLengthField.GetValue(strAddr); } if (length == 0) { return(""); } ulong data2 = firstCharField.GetAddress(strAddr); byte[] buffer = new byte[length * 2]; if (!heap.Runtime.ReadMemory(data2, buffer, buffer.Length, out int _)) { return(null); } return(Encoding.Unicode.GetString(buffer)); }
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)); }
public static long CountTargets(ClrDump clrDump, ClrType clrType) { long count = 0; var targetField = clrType.GetFieldByName(TargetFieldName); var invocCountField = clrType.GetFieldByName(InvocationCountFieldName); foreach (ulong address in clrDump.EnumerateInstances(clrType)) { count += CountTargets(address, clrType, targetField, invocCountField); } return(count); }
private bool FindThread(ulong start, ulong stop, out ulong threadAddr, out ClrThread target) { ClrHeap heap = _runtime.Heap; foreach (ulong obj in EnumerateObjectsOfType(start, stop, "System.Threading.Thread")) { ClrType type = heap.GetObjectType(obj); ClrInstanceField threadIdField = type.GetFieldByName("m_ManagedThreadId"); if (threadIdField != null && threadIdField.ElementType == ClrElementType.Int32) { int id = (int)threadIdField.GetValue(obj); ClrThread thread = GetThreadById(id); if (thread != null) { threadAddr = obj; target = thread; return(true); } } } threadAddr = 0; target = null; return(false); }
public static KcpUserAccount GetKcpUserAccountInfo(ulong KcpUserAccountAddr, ClrType KcpUserAccountType, ClrHeap Heap, string databaseLocation) { KcpUserAccount UserAccountInfo = new KcpUserAccount(); // Get the embedded ProtectedBinary ClrInstanceField KcpProtectedBinaryField = KcpUserAccountType.GetFieldByName("m_pbKeyData"); ulong KcpProtectedBinaryAddr = KcpProtectedBinaryField.GetAddress(KcpUserAccountAddr); ulong KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpUserAccountAddr); ClrInstanceField EncDataField = KcpProtectedBinaryField.Type.GetFieldByName("m_pbData"); ulong EncDataAddr = EncDataField.GetAddress(KcpProtectedBinaryObjAddr); ulong EncDataArrayAddr = (ulong)EncDataField.GetValue(KcpProtectedBinaryObjAddr); ClrType EncDataArrayType = Heap.GetObjectType(EncDataArrayAddr); int len = EncDataField.Type.GetArrayLength(EncDataArrayAddr); if (len <= 0 || len % 16 != 0) // Small sanity check to make sure everything's ok { return(null); } byte[] EncData = new byte[len]; for (int i = 0; i < len; i++) { EncData[i] = (byte)EncDataArrayType.GetArrayElementValue(EncDataArrayAddr, i); } UserAccountInfo.databaseLocation = databaseLocation; UserAccountInfo.encryptedBlob = EncData; UserAccountInfo.encryptedBlobAddress = (IntPtr)KcpUserAccountType.GetArrayElementAddress(EncDataArrayAddr, 0); UserAccountInfo.encryptedBlobLen = len; return(UserAccountInfo); }
private static void HandleEsentTable(ClrType clrType, BulkInsertOperation bulkInsert, ulong finalizerObj) { const string propName = "name"; var tableNameField = clrType.GetFieldByName(propName); if (tableNameField == null) { bulkInsert.Store(new FinalizerQueueObject { TypeName = clrType.Name, Size = clrType.BaseSize, PropertyData = "<no table name field>", PropertyName = propName }); } else { var tableName = tableNameField.GetValue(finalizerObj); var name = (tableName != null) ? tableName.ToString() : "<empty table name field>"; bulkInsert.Store(new FinalizerQueueObject { TypeName = clrType.Name, Size = clrType.BaseSize, PropertyData = String.IsNullOrWhiteSpace(name) ? "<empty table name field>" : name, PropertyName = propName }); } }
private static void HandleStreamObject(ClrType clrType, BulkInsertOperation bulkInsert, ulong finalizerObj) { const string propName = "_fileName"; var filenameField = clrType.GetFieldByName(propName); if (filenameField == null) { bulkInsert.Store(new FinalizerQueueObject { TypeName = clrType.Name, Size = clrType.BaseSize, PropertyData = "<no filename field>", PropertyName = propName }); } else { var filename = filenameField.GetValue(finalizerObj) ?? string.Empty; bulkInsert.Store(new FinalizerQueueObject { TypeName = clrType.Name, Size = clrType.BaseSize, PropertyData = filename.ToString(), PropertyName = propName }); } }
public static ulong GetLastObjectInHierarchy(ClrHeap heap, ulong heapobject, string[] hierarchy, int currentIndex) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(hierarchy[currentIndex]); if (field == null) { Console.WriteLine($"ERROR: type '{type.Name}' does not have a field '{hierarchy[currentIndex]}'"); return(0L); } ulong fieldValue = (ulong)field.GetValue(heapobject, false, false); if (fieldValue == 0) { Console.WriteLine($"ERROR: the field value for '{hierarchy[currentIndex]}' was null on type '{type.Name}' "); return(0L); } currentIndex++; if (currentIndex == hierarchy.Length) { return(fieldValue); } return(GetLastObjectInHierarchy(heap, fieldValue, hierarchy, currentIndex)); }
public void GetObjectField_WhenTypeHasFieldWithName_FindsField(ClrHeap heap, ClrType objectType, ClrInstanceField clrField, ulong clrObj, ulong fieldAddress, ulong fieldValue, string fieldName) { // Arrange heap.GetObjectType(Arg.Is <ulong>(address => address == clrObj || address == fieldValue)).Returns(objectType); objectType.GetFieldByName(fieldName).Returns(clrField); clrField.IsObjectReference.Returns(true); objectType.Heap.Returns(heap); clrField.GetAddress(clrObj).Returns(fieldAddress); heap.ReadPointer(fieldAddress, out var whatever) .Returns (call => { call[1] = fieldValue; return(true); }); // Act var fieldFoundByName = new ClrObject(clrObj, objectType).GetObjectField(fieldName); // Assert fieldFoundByName.Address.Should().Be(fieldValue); }
public void NoFieldCachingTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); dt.CacheOptions.CacheFields = false; dt.CacheOptions.CacheFieldNames = StringCaching.None; using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); Assert.NotEqual(0ul, type.MethodTable); // Sanity test Assert.NotEqual(type.Fields, type.Fields); ClrField field = type.GetFieldByName("o"); ClrField field2 = type.Fields.Single(f => f.Name == "o"); Assert.NotSame(field, field2); Assert.NotSame(field.Name, field.Name); dt.CacheOptions.CacheFieldNames = StringCaching.Intern; Assert.Same(field.Name, field.Name); Assert.Same(field.Name, string.Intern(field.Name)); }
public static T GetObjectAs <T>(ClrHeap heap, ulong heapobject, string fieldName) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(fieldName); T fieldValue = (T)field.GetValue(heapobject); return(fieldValue); }
static protected T GetObjectValue <T>(ulong objAddress, ClrType type, string fieldName) { var fieldType = type.GetFieldByName(fieldName); if (fieldType == null) { throw new ArgumentException(String.Format("Could not get field value of object 0x{0:X} for of field {1} of type {2}", objAddress, fieldName, type)); } return((T)fieldType.GetValue(objAddress)); }
public NetFrameworkClrDriver(ClrRuntime runtime) : base(runtime) { typeTimerQueue = heap.GetTypeByName("System.Threading.TimerQueue"); fieldSQueue = typeTimerQueue.GetStaticFieldByName("s_queue"); fieldTimers = typeTimerQueue.GetFieldByName("m_timers"); typeTimerQueueTimer = heap.GetTypeByName("System.Threading.TimerQueueTimer"); fieldNext = typeTimerQueueTimer.GetFieldByName("m_next"); fieldState = typeTimerQueueTimer.GetFieldByName("m_state"); typeMoveNextRunner = heap.GetTypeByName("System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner"); fieldStateMachine = typeMoveNextRunner.GetFieldByName("m_stateMachine"); }
private static void CheckField(ClrType type, string fieldName, ClrElementType element, string typeName, int size) { ClrInstanceField field = type.GetFieldByName(fieldName); Assert.NotNull(field); Assert.NotNull(field.Type); Assert.Equal(element, field.ElementType); Assert.Equal(typeName, field.Type.Name); Assert.Equal(size, field.Size); }
// // based on https://stackoverflow.com/questions/33290941/how-to-inspect-weakreference-values-with-windbg-sos-and-clrmd // private static readonly ClrType WeakRefType = Heap.GetTypeByName("System.WeakReference"); // private static readonly ClrInstanceField WeakRefHandleField = WeakRefType.GetFieldByName("m_handle"); // private static readonly ClrType IntPtrType = Heap.GetTypeByName("System.IntPtr"); // private static readonly ClrInstanceField IntPtrValueField = IntPtrType.GetFieldByName("m_value"); // // private static ulong GetWeakRefValue(ulong weakRefAddr) // { // var handleAddr = (long) WeakRefHandleField.GetValue(weakRefAddr); // var value = (ulong) IntPtrValueField.GetValue((ulong) handleAddr, true); // // return value; // } // based on https://stackoverflow.com/questions/33290941/how-to-inspect-weakreference-values-with-windbg-sos-and-clrmd public ulong GetWeakRefValue(ClrObject weakRefObject) { var weakRefHandleField = weakRefObject.Type.GetFieldByName("m_handle"); ClrType intPtrType = Heap.GetTypeByName("System.IntPtr"); var valueField = IsCoreRuntime ? "_value" : "m_value"; ClrInstanceField intPtrValueField = intPtrType.GetFieldByName(valueField); var handleAddr = weakRefHandleField.Read <long>(weakRefObject.Address, true); var value = intPtrValueField.Read <ulong>((ulong)handleAddr, true); return(value); }
public ClrInstanceField TestFieldNameAndValue(ClrType type, ulong obj, string name, string value) { ClrInstanceField field = type.GetFieldByName(name); Assert.NotNull(field); Assert.Equal(name, field.Name); string str = field.ReadString(obj, interior: false); Assert.Equal(value, str); return(field); }
public object GetFieldValue(ulong Address, string FieldName, ClrType TheType = null) { string[] fields = FieldName.Split('.'); ulong address = Address; ClrType type = TheType; if (type == null) { type = heap.GetObjectType(Address); } ClrInstanceField field; for (int i = 0; i < fields.Length - 1; i++) { field = type.GetFieldByName(fields[i]); // At this level we cannot have a simple value if (!field.IsObjectReference()) { return(null); } address = (ulong)field.GetFieldValue(address); if (address == 0) { return(null); } type = heap.GetObjectType(address); } field = type.GetFieldByName(fields[fields.Length - 1]); object value = null; value = field.GetFieldValue(address); if (field.Type.IsEnum) { value = field.Type.GetEnumName(value); } return(value); }
internal static string?GetStringContents(ClrType stringType, IDataReader reader, ulong strAddr, int maxLen) { if (strAddr == 0) { return(null); } if (!_initializedStringFields) { _firstChar = stringType.GetFieldByName("m_firstChar"); _stringLength = stringType.GetFieldByName("m_stringLength"); // .Type being null can happen in minidumps. In that case we will fall back to // hardcoded values and hope they don't get out of date. if (_firstChar?.Type is null) { _firstChar = null; } if (_stringLength?.Type is null) { _stringLength = null; } _initializedStringFields = true; } if (_firstChar is null || _stringLength is null) { return(string.Empty); } int length = _stringLength.Read <int>(strAddr, interior: false); ulong data = _firstChar.GetAddress(strAddr); length = Math.Min(length, maxLen); return(ReadString(reader, data, length)); }
public void Can_cast_to_string() { var proxy = GetProxy <ClassWithStringField>(); ClrType type = proxy.GetClrType(); var address = type.GetFieldByName("Value").GetAddress((ulong)proxy); ulong stringAddress; _heap.ReadPointer(address, out stringAddress); Assert.AreEqual("OK", (string)_heap.GetProxy(stringAddress)); }
public ClrInstanceField TestFieldNameAndValue <T>(ClrType type, ulong obj, string name, T value) where T : unmanaged { ClrInstanceField field = type.GetFieldByName(name); Assert.NotNull(field); Assert.Equal(name, field.Name); T t = field.Read <T>(obj, interior: false); Assert.Equal(value, t); return(field); }
public static ulong GetLastObjectInHierarchy(ClrHeap heap, ulong heapobject, string[] hierarchy, int currentIndex) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(hierarchy[currentIndex]); ulong fieldValue = (ulong)field.GetValue(heapobject, false, false); currentIndex++; if (currentIndex == hierarchy.Length) { return(fieldValue); } return(GetLastObjectInHierarchy(heap, fieldValue, hierarchy, currentIndex)); }
private void InitThreadProperties() { ClrType threadType = GetClrType(typeof(Thread).FullName); var threadsInstances = GetInstances(threadType); var nameField = threadType.GetFieldByName("m_Name"); var priorityField = threadType.GetFieldByName("m_Priority"); var idField = threadType.GetFieldByName("m_ManagedThreadId"); threadProperties = new Dictionary <int, ThreadProperty>(); foreach (ulong threadAddress in threadsInstances) { string name = (string)GetFieldValue(threadAddress, threadType, nameField); int priority = (int)GetFieldValue(threadAddress, threadType, priorityField); int id = idField != null ? (int)GetFieldValue(threadAddress, threadType, idField) : 0; threadProperties[id] = new ThreadProperty { Address = threadAddress, ManagedId = id, Priority = priority, Name = name }; } }
static void ReadExceptionHResult(ClrType type, ulong obj) { ClrInstanceField field = type.GetFieldByName("_HResult"); Debug.Assert(field.ElementType == ClrElementType.Int32); int value = (int)field.GetValue(obj); Console.WriteLine(" Exception 0x{0:X} hresult: 0x{1:X}", obj, value); // get value detail var output = GetOutput(obj, field); Console.WriteLine(" " + output); }
public void TestInstanceFieldModifiers() { using DataTarget dt = TestTargets.NestedTypes.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule(TypeTests.NestedTypesModuleName); ClrType program = module.GetTypeByName("Program"); ClrField publicField = program.GetFieldByName("publicField"); Assert.True(publicField.IsPublic); ClrField privateField = program.GetFieldByName("privateField"); Assert.True(privateField.IsPrivate); ClrField internalField = program.GetFieldByName("internalField"); Assert.True(internalField.IsInternal); ClrField protectedField = program.GetFieldByName("protectedField"); Assert.True(protectedField.IsProtected); }
public ClrInstanceField TestFieldNameAndValue <T>(ClrType type, ulong obj, string name, T value) { ClrInstanceField field = type.GetFieldByName(name); Assert.NotNull(field); Assert.Equal(name, field.Name); object v = field.GetValue(obj); Assert.NotNull(v); Assert.IsType <T>(v); Assert.Equal(value, (T)v); return(field); }
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; }
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; }
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); }
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); }