public void AsEnumTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule typesModule = runtime.GetModule(ModuleName); ClrType type = typesModule.GetTypeByName("Types"); ClrStaticField field = type.GetStaticFieldByName("s_enum"); Assert.True(field.Type.IsEnum); ClrEnum clrEnum = field.Type.AsEnum(); Assert.NotNull(clrEnum); string[] propertyNames = clrEnum.GetEnumNames().ToArray(); Assert.NotEmpty(propertyNames); Assert.Contains(nameof(FileAccess.Read), propertyNames); Assert.Contains(nameof(FileAccess.Write), propertyNames); Assert.Contains(nameof(FileAccess.ReadWrite), propertyNames); Assert.Equal(ClrElementType.Int32, clrEnum.ElementType); Assert.Equal(FileAccess.Read, clrEnum.GetEnumValue <FileAccess>(nameof(FileAccess.Read))); Assert.Equal(FileAccess.Write, clrEnum.GetEnumValue <FileAccess>(nameof(FileAccess.Write))); Assert.Equal(FileAccess.ReadWrite, clrEnum.GetEnumValue <FileAccess>(nameof(FileAccess.ReadWrite))); }
public void NoTypeCachingTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); dt.CacheOptions.CacheTypes = false; dt.CacheOptions.CacheTypeNames = 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 ClrType type2 = runtime.GetTypeByMethodTable(type.MethodTable); Assert.Equal(type, type2); Assert.NotSame(type, type2); Assert.NotNull(type.Name); Assert.Equal(type.Name, type.Name); Assert.NotSame(type.Name, type.Name); dt.CacheOptions.CacheTypeNames = StringCaching.Intern; Assert.Same(type.Name, type.Name); Assert.Same(type.Name, string.Intern(type.Name)); }
public void MethodHandleMultiDomainTests() { ulong[] methodDescs; using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); methodDescs = method.EnumerateMethodDescs().ToArray(); Assert.Equal(2, methodDescs.Length); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[0]); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDescs[1]); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } }
public void TestGetTypeByName() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrModule shared = runtime.GetModule("sharedlibrary.dll"); Assert.NotNull(shared.GetTypeByName("Foo")); Assert.Null(shared.GetTypeByName("Types")); ClrModule types = runtime.GetModule("types.exe"); Assert.NotNull(types.GetTypeByName("Types")); Assert.Null(types.GetTypeByName("Foo")); } }
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.NotSame(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 void MethodCachingTest() { // Test that when we cache method names they are not re-read using DataTarget dt = TestTargets.Types.LoadFullDump(); dt.CacheOptions.CacheMethods = true; // We want to make sure we are getting the same string because it was cached, // not because it was interned dt.CacheOptions.CacheMethodNames = StringCaching.Cache; using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); Assert.NotEqual(0ul, method.MethodDesc); // Sanity test ClrMethod method2 = type.GetMethod("Bar"); Assert.Equal(method, method2); Assert.Same(method, method2); string signature1 = method.Signature; string signature2 = method2.Signature; Assert.NotNull(signature1); Assert.Equal(signature1, signature2); Assert.Equal(signature1, method.Signature); Assert.Same(signature1, method.Signature); }
public void TypeEqualityTest() { // This test ensures that only one ClrType is created when we have a type loaded into two different AppDomains with two different // method tables. const string TypeName = "Foo"; using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrType[] types = (from obj in heap.EnumerateObjectAddresses() let t = heap.GetObjectType(obj) where t.Name == TypeName select t).ToArray(); Assert.Equal(2, types.Length); Assert.NotSame(types[0], types[1]); ClrModule module = runtime.Modules.Single(m => Path.GetFileName(m.FileName).Equals("sharedlibrary.dll", StringComparison.OrdinalIgnoreCase)); ClrType typeFromModule = module.GetTypeByName(TypeName); Assert.Equal(TypeName, typeFromModule.Name); Assert.Equal(types[0], typeFromModule); } }
public void IntegerObjectClrType() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrModule module = runtime.GetModule(ModuleName); ClrType typesType = module.GetTypeByName("Types"); ClrStaticField field = typesType.GetStaticFieldByName("s_i"); ClrObject obj = field.ReadObject(); Assert.False(obj.IsNull); ClrType type = obj.Type; Assert.NotNull(type); Assert.True(type.IsPrimitive); Assert.False(type.IsObjectReference); Assert.False(type.IsValueType); var fds = obj.Type.Fields; int value = obj.ReadBoxed <int>(); Assert.Equal(42, value); Assert.Contains(obj.Address, heap.EnumerateObjects().Select(a => a.Address)); }
private static void GetKnownSourceAndTarget(ClrHeap heap, out ulong source, out ulong target) { ClrModule module = heap.Runtime.GetMainModule(); ClrType mainType = module.GetTypeByName("GCRootTarget"); source = mainType.GetStaticObjectValue("TheRoot").Address; target = heap.GetObjectsOfType("TargetType").Single(); }
private int GetClrModuleTypeByName(Tuple <int, ulong, string> input) { int runtimeId = input.Item1; ulong imageBase = input.Item2; string typeName = input.Item3; ClrRuntime clrRuntime = runtimesCache[runtimeId]; ClrModule clrModule = clrRuntime.Modules.FirstOrDefault(m => m.ImageBase == imageBase); return(GetClrTypeId(clrModule.GetTypeByName(typeName))); }
public void CompleteSignatureIsRetrievedForMethodsWithGenericParameters() { using DataTarget dt = TestTargets.AppDomains.LoadFullDump(); ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod genericMethod = type.GetMethod("GenericBar"); string methodName = genericMethod.GetFullSignature(); Assert.Equal(')', methodName.Last()); }
public void TestTypeModifiers() { using DataTarget dt = TestTargets.NestedTypes.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule(NestedTypesModuleName); ClrType program = module.GetTypeByName("Program"); Assert.True(program.IsPublic); Assert.False(program.IsAbstract); Assert.False(program.IsSealed); ClrType publicClass = module.GetTypeByName("Program+PublicClass"); Assert.True(publicClass.IsPublic); ClrType privateClass = module.GetTypeByName("Program+PrivateClass"); Assert.True(privateClass.IsPrivate); ClrType internalClass = module.GetTypeByName("Program+InternalClass"); Assert.True(internalClass.IsInternal); ClrType protectedClass = module.GetTypeByName("Program+ProtectedClass"); Assert.True(protectedClass.IsProtected); ClrType abstractClass = module.GetTypeByName("Program+AbstractClass"); Assert.True(abstractClass.IsAbstract); Assert.False(abstractClass.IsSealed); ClrType sealedClass = module.GetTypeByName("Program+SealedClass"); Assert.True(sealedClass.IsSealed); Assert.False(sealedClass.IsAbstract); ClrType staticClass = module.GetTypeByName("Program+StaticClass"); Assert.True(staticClass.IsAbstract); Assert.True(staticClass.IsSealed); }
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); } } } }
public void GetDelegateTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule typesModule = runtime.GetModule(TypeTests.ModuleName); ClrType Types = typesModule.GetTypeByName("Types"); ClrDelegate TestDelegate = Types.GetStaticFieldByName("TestDelegate").ReadObject(runtime.AppDomains.Single()).AsDelegate(); ClrDelegateTarget delegateTarget = TestDelegate.GetDelegateTarget(); Assert.NotNull(delegateTarget); CompareToInner(Types, TestDelegate, delegateTarget); ClrDelegate TestEvent = Types.GetStaticFieldByName("TestEvent").ReadObject(runtime.AppDomains.Single()).AsDelegate(); ClrDelegateTarget eventTarget = TestEvent.GetDelegateTarget(); Assert.Null(eventTarget); }
public void EnumerateGCRefsArray() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrModule module = heap.Runtime.GetMainModule(); ClrType mainType = module.GetTypeByName("GCRootTarget"); ClrObject obj = mainType.GetStaticObjectValue("TheRoot"); obj = obj.GetObjectField("Item1"); Assert.Equal("System.Object[]", obj.Type.Name); ClrObject[] refs = obj.EnumerateReferences(false).ToArray(); Assert.Single(refs); Assert.Equal("DoubleRef", refs[0].Type.Name); }
/// <summary> /// Gets the type with the specified name. /// </summary> /// <param name="name">The CLR type name.</param> private CodeType GetClrTypeByName(string name) { try { // Try to find code type inside CLR module var clrType = ClrModule.GetTypeByName(name); if (clrType != null) { // Create a code type return(ClrTypes[clrType]); } } catch (Exception) { } return(null); }
public void IsDelegateTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule typesModule = runtime.GetModule(TypeTests.ModuleName); ClrType type = typesModule.GetTypeByName("Types"); ClrObject TestDelegate = type.GetStaticFieldByName("TestDelegate").ReadObject(runtime.AppDomains.Single()); Assert.True(TestDelegate.IsValid); Assert.True(TestDelegate.IsDelegate); Assert.False(TestDelegate.AsDelegate().HasMultipleTargets); ClrObject TestEvent = type.GetStaticFieldByName("TestEvent").ReadObject(runtime.AppDomains.Single()); Assert.True(TestEvent.IsValid); Assert.True(TestEvent.IsDelegate); Assert.True(TestEvent.AsDelegate().HasMultipleTargets); }
// 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 NoMethodCachingTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); dt.CacheOptions.CacheMethods = false; dt.CacheOptions.CacheMethodNames = StringCaching.None; using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); Assert.NotEqual(0ul, method.MethodDesc); // Sanity test ClrMethod method2 = type.GetMethod("Bar"); Assert.Equal(method, method2); Assert.NotSame(method, method2); string signature1 = method.Signature; string signature2 = method2.Signature; Assert.NotNull(signature1); Assert.Equal(signature1, signature2); Assert.Equal(signature1, method.Signature); Assert.NotSame(signature1, method.Signature); Assert.NotSame(method2.Signature, method.Signature); // Ensure that we can swap this at runtime and that we get interned strings dt.CacheOptions.CacheMethodNames = StringCaching.Intern; Assert.NotNull(method.Signature); Assert.Same(method2.Signature, method.Signature); Assert.Same(method.Signature, string.Intern(method.Signature)); }
/// <summary> /// Gets the CLR static variable. /// </summary> /// <param name="name">The name.</param> /// <param name="appDomain">The application domain.</param> /// <returns>Static variable if found</returns> public Variable GetClrVariable(string name, CsDebugScript.CLR.AppDomain appDomain) { int variableNameIndex = name.LastIndexOf('.'); string typeName = name.Substring(0, variableNameIndex); var clrType = ClrModule.GetTypeByName(typeName); if (clrType == null) { throw new Exception("CLR type not found " + typeName); } string variableName = name.Substring(variableNameIndex + 1); var staticField = clrType.GetStaticFieldByName(variableName); if (staticField == null) { throw new Exception("Field " + staticField + " wasn't found in CLR type " + typeName); } var address = staticField.GetAddress(appDomain.ClrAppDomain); return(Variable.CreateNoCast(FromClrType(clrType), address, variableName)); }
public void EnumerateDelegateTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule typesModule = runtime.GetModule(TypeTests.ModuleName); ClrType Types = typesModule.GetTypeByName("Types"); ClrDelegate TestDelegate = Types.GetStaticFieldByName("TestDelegate").ReadObject(runtime.AppDomains.Single()).AsDelegate(); ClrDelegateTarget[] methods = TestDelegate.EnumerateDelegateTargets().ToArray(); Assert.Single(methods); CompareToInner(Types, TestDelegate, methods[0]); ClrDelegate TestEvent = Types.GetStaticFieldByName("TestEvent").ReadObject(runtime.AppDomains.Single()).AsDelegate(); methods = TestEvent.EnumerateDelegateTargets().ToArray(); Assert.Equal(2, methods.Length); CompareToInner(Types, TestEvent, methods[0]); CompareToInstanceMethod(Types, TestEvent, methods[1]); }
public void MethodHandleSingleDomainTests() { ulong methodDesc; using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); methodDesc = method.MethodDesc; Assert.NotEqual(0ul, methodDesc); } using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrMethod method = runtime.GetMethodByHandle(methodDesc); Assert.NotNull(method); Assert.Equal("Bar", method.Name); Assert.Equal("Foo", method.Type.Name); } using (DataTarget dt = TestTargets.Types.LoadFullDump()) { using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule("sharedlibrary.dll"); ClrType type = module.GetTypeByName("Foo"); ClrMethod method = type.GetMethod("Bar"); Assert.Equal(methodDesc, method.MethodDesc); Assert.Equal(method, runtime.GetMethodByHandle(methodDesc)); } }
public void TestStaticFieldModifiers() { using DataTarget dt = TestTargets.NestedTypes.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.GetModule(TypeTests.NestedTypesModuleName); ClrType program = module.GetTypeByName("Program"); ClrStaticField publicField = program.GetStaticFieldByName("s_publicField"); Assert.True(publicField.IsPublic); ClrStaticField privateField = program.GetStaticFieldByName("s_privateField"); Assert.True(privateField.IsPrivate); ClrStaticField internalField = program.GetStaticFieldByName("s_internalField"); Assert.True(internalField.IsInternal); ClrStaticField protectedField = program.GetStaticFieldByName("s_protectedField"); Assert.True(protectedField.IsProtected); }
/// <summary> /// Gets the CLR static variable. /// </summary> /// <param name="name">The name.</param> /// <param name="appDomain">The application domain.</param> /// <returns>Static variable if found</returns> public Variable GetClrVariable(string name, IClrAppDomain appDomain) { int variableNameIndex = name.LastIndexOf('.'); string typeName = name.Substring(0, variableNameIndex); var clrType = ClrModule.GetTypeByName(typeName); if (clrType == null) { throw new Exception($"CLR type not found {typeName}"); } string variableName = name.Substring(variableNameIndex + 1); var staticField = clrType.GetStaticFieldByName(variableName); if (staticField == null) { throw new Exception($"Field {staticField} wasn't found in CLR type {typeName}"); } var address = staticField.GetAddress(appDomain); Variable field = Variable.CreateNoCast(FromClrType(clrType), address, variableName); return(Variable.UpcastClrVariable(field)); }
public void PdbMethodTest() { // Ensure all methods in our source file is in the pdb. using (DataTarget dt = TestTargets.NestedException.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrModule module = runtime.Modules.Where(m => m.Name.Equals(TestTargets.NestedException.Executable, StringComparison.OrdinalIgnoreCase)).Single(); ClrType type = module.GetTypeByName("Program"); using (PdbReader pdb = new PdbReader(TestTargets.NestedException.Pdb)) { foreach (ClrMethod method in type.Methods) { // ignore inherited methods and constructors if (method.Type != type || method.IsConstructor || method.IsClassConstructor) { continue; } Assert.IsNotNull(pdb.GetFunctionFromToken(method.MetadataToken)); } } } }
/// <summary> /// Attempts to obtain a ClrType based on the name of the type. Note this is a "best effort" due to /// the way that the dac handles types. This function will fail for Generics, and types which have /// never been constructed in the target process. Please be sure to null-check the return value of /// this function. /// </summary> /// <param name="name">The name of the type. (This would be the EXACT value returned by ClrType.Name.</param> /// <returns>The requested ClrType, or null if the type doesn't exist or couldn't be constructed.</returns> /// <exception cref="NotImplementedException"></exception> /// <inheritdoc /> public IClrType GetTypeByName(string name) => Converter.Convert(Module.GetTypeByName(name));
public void RunDone() { _workItems = new Dictionary <string, WorkInfo>(); _workItemCount = 0; _tasks = new Dictionary <string, WorkInfo>(); _taskCount = 0; ClrMDHelper helper = new ClrMDHelper(_host.Session.Clr); // 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 // try { var heap = _host.Session.Clr.Heap; var clr = _host.Session.Clr; _host.WriteLine("global work item queue________________________________"); // look for the ThreadPoolGlobals.workQueue static field ClrModule mscorlib = helper.GetMscorlib(); if (mscorlib == null) { return; } ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals"); if (queueType == null) { return; } ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue"); if (workQueueField == null) { return; } // the CLR keeps one static instance per application domain foreach (var appDomain in clr.AppDomains) { object workQueueValue = workQueueField.GetValue(appDomain); ulong workQueueRef = (workQueueValue == null) ? 0L : (ulong)workQueueValue; if (workQueueRef == 0) { continue; } // should be System.Threading.ThreadPoolWorkQueue ClrType workQueueType = heap.GetObjectType(workQueueRef); if (workQueueType == null) { continue; } if (workQueueType.Name != "System.Threading.ThreadPoolWorkQueue") { continue; } if (!DumpThreadPoolWorkQueue(workQueueType, workQueueRef)) { _host.WriteLine("Impossible to dump thread pool work queue @ 0x" + workQueueRef.ToString("X")); } } // 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> // _host.WriteLine("\r\nlocal per thread work items_____________________________________"); try { queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue"); if (queueType == null) { return; } ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues"); if (threadQueuesField == null) { return; } foreach (ClrAppDomain domain in clr.AppDomains) { ulong?threadQueue = (ulong?)threadQueuesField.GetValue(domain); if (!threadQueue.HasValue || threadQueue.Value == 0) { continue; } ClrType threadQueueType = heap.GetObjectType(threadQueue.Value); if (threadQueueType == null) { continue; } var sparseArrayRef = _host.Session.GetFieldValue(threadQueue.Value, "m_array"); _host.Session.ForEach((ulong)sparseArrayRef, stealingQueue => { if (stealingQueue != 0) { var arrayRef = _host.Session.GetFieldValue(stealingQueue, "m_array"); DumpThreadPoolWorkItems((ulong)arrayRef); } }); } } finally { // provide a summary sorted by count // tasks first if any if (_tasks.Values.Count > 0) { foreach (var item in _tasks.Values.OrderBy(wi => wi.Count)) { _host.WriteLine(string.Format(" {0,4} Task {1}", item.Count.ToString(), item.Name)); } _host.WriteLine(" ----"); _host.WriteLine(string.Format(" {0,4}\r\n", _taskCount.ToString())); } // then QueueUserWorkItem next if any if (_workItems.Values.Count > 0) { foreach (var item in _workItems.Values.OrderBy(wi => wi.Count)) { _host.WriteLine(string.Format(" {0,4} Work {1}", item.Count.ToString(), item.Name)); } _host.WriteLine(" ----"); _host.WriteLine(string.Format(" {0,4}\r\n", _workItemCount.ToString())); } var threadPool = _host.Session.Clr.ThreadPool; _host.WriteLine(string.Format( "\r\nCPU = {0}% for {1} threads (#idle = {2} + #running = {3} | #dead = {4} | #max = {5})", threadPool.CpuUtilization.ToString(), threadPool.TotalThreads.ToString(), threadPool.IdleThreads.ToString(), threadPool.RunningThreads.ToString(), _host.Session.Clr.Threads.Count(t => t.IsThreadpoolWorker && !t.IsThreadpoolCompletionPort && !t.IsAlive && !t.IsThreadpoolGate && !t.IsThreadpoolTimer && !t.IsThreadpoolWait).ToString(), threadPool.MaxThreads.ToString() )); // show the running worker threads DumpRunningThreadpoolThreads(helper); } } catch (Exception x) { _host.WriteLine(x.Message); } }
/// <summary> /// Attempts to obtain a <see cref="T:CsDebugScript.CLR.IClrType" /> based on the name of the type. /// Note this is a "best effort" due to the way that the DAC handles types. /// This function will fail for Generics, and types which have never been constructed in the target process. /// Please be sure to null-check the return value of this function. /// </summary> /// <param name="typeName">The name of the type. (This would be the EXACT value returned by <see cref="P:CsDebugScript.CLR.IClrType.Name" />).</param> public IClrType GetTypeByName(string typeName) { return(Provider.FromClrType(ClrModule.GetTypeByName(typeName))); }
private IEnumerable <ulong> EnumerateManagedThreadpoolObjects() { _heap = _runtime.GetHeap(); 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; ClrType queueHeadType; do { if (!GetFieldObject(workQueueType, workQueue, "queueHead", out queueHeadType, out queueHead)) { break; } ulong nodes; ClrType nodesType; 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; } ulong outerArray = 0; ClrType outerArrayType = null; 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; } ulong array; ClrType arrayType; 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); } } } } } } } }