private ThreadPoolItem GetThreadPoolItem(ClrObject item)
        {
            ClrType itemType = item.Type;

            if (itemType.Name == "System.Threading.Tasks.Task")
            {
                return(GetTask(item));
            }

            if (
                (string.CompareOrdinal(itemType.Name, "System.Threading.QueueUserWorkItemCallback") == 0) ||
                // new to .NET Core
                (string.CompareOrdinal(itemType.Name, "System.Threading.QueueUserWorkItemCallbackDefaultContext") == 0)
                )
            {
                return(GetQueueUserWorkItemCallback(item));
            }

            // create a raw information
            ThreadPoolItem tpi = new ThreadPoolItem()
            {
                Type       = ThreadRoot.Raw,
                Address    = item.Address,
                MethodName = itemType.Name
            };

            return(tpi);
        }
        private ThreadPoolItem GetQueueUserWorkItemCallback(ClrObject element)
        {
            ThreadPoolItem tpi = new ThreadPoolItem()
            {
                Address = (ulong)element,
                Type    = ThreadRoot.WorkItem
            };

            // look for the callback given to ThreadPool.QueueUserWorkItem()
            // for .NET Core, the callback is stored in a different field _callback
            var       elementType = element.Type;
            ClrObject callback;

            if (elementType.GetFieldByName("_callback") != null)
            {
                callback = element.ReadObjectField("_callback");
            }
            else if (elementType.GetFieldByName("callback") != null)
            {
                callback = element.ReadObjectField("callback");
            }
            else
            {
                tpi.MethodName = "[no callback]";
                return(tpi);
            }

            var target = callback.ReadObjectField("_target");

            if (!target.IsValid)
            {
                tpi.MethodName = "[no callback target]";
                return(tpi);
            }

            ClrType targetType = target.Type;

            if (targetType == null)
            {
                tpi.MethodName = $" [target=0x{target.Address}]";
            }
            else
            {
                // look for method name
                tpi.MethodName = BuildDelegateMethodName(targetType, callback);
            }

            return(tpi);
        }
Exemple #3
0
        private void DisplayItem(ThreadPoolItem item, Dictionary <string, WorkInfo> tasks, ref int taskCount, Dictionary <string, WorkInfo> workItems, ref int workItemCount)
        {
            switch (item.Type)
            {
            case ThreadRoot.Task:
                WriteLine($"0x{item.Address:X16} Task | {item.MethodName}");
                UpdateStats(tasks, item.MethodName, ref taskCount);
                break;

            case ThreadRoot.WorkItem:
                WriteLine($"0x{item.Address:X16} Work | {item.MethodName}");
                UpdateStats(workItems, item.MethodName, ref workItemCount);
                break;

            default:
                WriteLine($"0x{item.Address:X16} {item.MethodName}");
                break;
            }
        }
        private ThreadPoolItem GetTask(ClrObject task)
        {
            ThreadPoolItem tpi = new ThreadPoolItem()
            {
                Address = task.Address,
                Type    = ThreadRoot.Task
            };

            // look for the context in m_action._target
            var action = task.ReadObjectField("m_action");

            if (!action.IsValid)
            {
                tpi.MethodName = " [no action]";
                return(tpi);
            }

            var target = action.ReadObjectField("_target");

            if (!target.IsValid)
            {
                tpi.MethodName = " [no target]";
                return(tpi);
            }

            tpi.MethodName = BuildDelegateMethodName(target.Type, action);

            // get the task scheduler if any
            var taskScheduler = task.ReadObjectField("m_taskScheduler");

            if (taskScheduler.IsValid)
            {
                var schedulerType = taskScheduler.Type.ToString();
                if (string.CompareOrdinal("System.Threading.Tasks.ThreadPoolTaskScheduler", schedulerType) != 0)
                {
                    tpi.MethodName = $"{tpi.MethodName} [{schedulerType}]";
                }
            }
            return(tpi);
        }