public void IntegerObjectClrType() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrAppDomain domain = runtime.AppDomains.Single(); ClrModule module = runtime.GetModule(ModuleName); ClrType typesType = module.GetTypeByName("Types"); ClrStaticField field = typesType.GetStaticFieldByName("s_i"); ClrObject obj = field.ReadObject(domain); Assert.False(obj.IsNull); ClrType type = obj.Type; Assert.NotNull(type); Assert.True(type.IsPrimitive); Assert.False(type.IsObjectReference); Assert.True(type.IsValueType); var fds = obj.Type.Fields; Assert.True(obj.IsBoxedValue); int value = obj.ReadBoxedValue <int>(); Assert.Equal(42, value); Assert.Contains(obj.Address, heap.EnumerateObjects().Select(a => a.Address)); }
private IEnumerable <ThreadPoolItem> EnumerateLocalThreadPoolItemsInNetFramework(ClrModule mscorlib) { // look into the local stealing queues in each thread TLS // hopefully, they are all stored in static (one per app domain) instance // of ThreadPoolWorkQueue.SparseArray<ThreadPoolWorkQueue.WorkStealingQueue> // var queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue"); if (queueType == null) { yield break; } ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues"); if (threadQueuesField == null) { yield break; } foreach (ClrAppDomain domain in _clr.AppDomains) { var threadQueue = threadQueuesField.ReadObject(domain); if (!threadQueue.IsValid) { continue; } var sparseArray = threadQueue.ReadObjectField("m_array").AsArray(); for (int current = 0; current < sparseArray.Length; current++) { var stealingQueue = sparseArray.GetObjectValue(current); if (!stealingQueue.IsValid) { continue; } foreach (var item in EnumerateThreadPoolStealingQueue(stealingQueue)) { yield return(item); } } } }
// The ThreadPool is keeping track of the pending work items into two different areas: // - a global queue: stored by ThreadPoolWorkQueue instances of the ThreadPoolGlobals.workQueue static field // - several per thread (TLS) local queues: stored in SparseArray<ThreadPoolWorkQueue+WorkStealingQueue> linked from ThreadPoolWorkQueue.allThreadQueues static fields // both are using arrays of Task or QueueUserWorkItemCallback // // NOTE: don't show other thread pool related topics such as timer callbacks or wait objects // private IEnumerable <ThreadPoolItem> EnumerateGlobalThreadPoolItemsInNetFramework(ClrModule mscorlib) { ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals"); if (queueType == null) { yield break; } ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue"); if (workQueueField == null) { yield break; } // the CLR keeps one static instance per application domain foreach (var appDomain in _clr.AppDomains) { var workQueue = workQueueField.ReadObject(appDomain); if (!workQueue.IsValid) { continue; } // should be System.Threading.ThreadPoolWorkQueue var workQueueType = workQueue.Type; if (workQueueType == null) { continue; } if (string.CompareOrdinal(workQueueType.Name, "System.Threading.ThreadPoolWorkQueue") != 0) { continue; } foreach (var item in EnumerateThreadPoolWorkQueue(workQueue)) { yield return(item); } } }
public void ComponentTypeEventuallyFilledTest() { // https://github.com/microsoft/clrmd/issues/108 // Ensure that a previously created type with a erronous null ComponentType eventually // gets its ComponentType set. using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrType fooType = runtime.GetModule(ModuleName).GetTypeByName("Types"); ClrStaticField cq = fooType.GetStaticFieldByName("s_cq"); Assert.NotNull(cq); ClrInstanceField m_head = cq.Type.GetFieldByName("m_head"); ClrInstanceField m_array = m_head.Type.GetFieldByName("m_array"); bool hasSimpleValue = m_array.HasSimpleValue; ClrElementType elementType = m_array.ElementType; ClrType componentType = m_array.Type.ComponentType; // If this assert fails, remove the test. This value is null because currently CLR's // debugging layer doesn't tell us the component type of an array. If we eventually // fix that issue, we would return a non-null m_array.Type.ComponentType, causing // this test to fail but the underlying issue would be fixed. Assert.Null(componentType); ClrObject m_arrayObj = cq.ReadObject().GetObjectField("m_head").GetObjectField("m_array"); // Ensure we are looking at the same ClrType if (dt.CacheOptions.CacheTypes) { Assert.Same(m_array.Type, m_arrayObj.Type); } else { Assert.Equal(m_array.Type, m_arrayObj.Type); } // Assert that we eventually filled in ComponentType after we got a real object for the type Assert.NotNull(m_arrayObj.Type.ComponentType); }
public static ClrObject GetStaticObjectValue(this ClrType mainType, string fieldName) { ClrStaticField field = mainType.GetStaticFieldByName(fieldName); return(field.ReadObject()); }