This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public IEnumerable<ThreadPoolItem> EnumerateGlobalThreadPoolItems() | |
| { | |
| // look for the ThreadPoolGlobals.workQueue static field | |
| ClrModule mscorlib = GetMscorlib(); | |
| if (mscorlib == null) | |
| throw new InvalidOperationException("Impossible to find mscorlib.dll"); | |
| ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals"); | |
| if (queueType == null) | |
| yield break; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private IEnumerable<ThreadPoolItem> EnumerateThreadPoolWorkQueue(ulong workQueueRef) | |
| { | |
| // start from the tail and follow the Next | |
| var proxy = _heap.GetProxy(workQueueRef); | |
| var currentQueueSegment = proxy.queueTail; | |
| while (currentQueueSegment != null) | |
| { | |
| // get the System.Threading.ThreadPoolWorkQueue+QueueSegment nodes array | |
| var nodes = currentQueueSegment.nodes; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public IEnumerable<ThreadPoolItem> EnumerateLocalThreadPoolItems() | |
| { | |
| var queueType = GetMscorlib().GetTypeByName("System.Threading.ThreadPoolWorkQueue"); | |
| if (queueType == null) | |
| yield break; | |
| ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues"); | |
| if (threadQueuesField == null) | |
| yield break; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private IEnumerable<ThreadPoolItem> EnumerateThreadPoolStealingQueue(dynamic stealingQueue) | |
| { | |
| var array = stealingQueue.m_array; | |
| if (array == null) | |
| yield break; | |
| foreach (var item in array) | |
| { | |
| if (item == null) | |
| continue; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private ThreadPoolItem GetThreadPoolItem(dynamic item) | |
| { | |
| // get the ClrType directly from the dynamic proxy | |
| ClrType itemType = item.GetClrType(); | |
| if (itemType.Name == "System.Threading.Tasks.Task") | |
| { | |
| return GetTask(item); | |
| } | |
| else if (itemType.Name == "System.Threading.QueueUserWorkItemCallback") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private ThreadPoolItem GetTask(dynamic task) | |
| { | |
| ThreadPoolItem tpi = new ThreadPoolItem() | |
| { | |
| Address = (ulong)task, | |
| Type = ThreadRoot.Task | |
| }; | |
| // look for the context in m_action._target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| internal string BuildDelegateMethodName(ClrType targetType, dynamic action) | |
| { | |
| var methodPtr = action._methodPtr; | |
| if (methodPtr != null) | |
| { | |
| ClrMethod method = _clr.GetMethodByAddress((ulong)methodPtr); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if (method == null) | |
| { | |
| // could happen in case of static method | |
| methodPtr = action._methodPtrAux; | |
| method = _clr.GetMethodByAddress((ulong)methodPtr); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // anonymous method | |
| if (method.Type.Name == targetType.Name) | |
| { | |
| return $"{targetType.Name}.{method.Name}"; | |
| } | |
| else | |
| // method is implemented by an class inherited from targetType | |
| // ... or a simple delegate indirection to a static/instance method | |
| { | |
| if ( |