Skip to content

Instantly share code, notes, and snippets.

View Criteo-dotnet-blog's full-sized avatar

Criteo-dotnet-blog

View GitHub Profile
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;
        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")
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;
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;
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;
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")
private ThreadPoolItem GetTask(dynamic task)
{
    ThreadPoolItem tpi = new ThreadPoolItem()
    {
        Address = (ulong)task,
        Type = ThreadRoot.Task
    };
 
    // look for the context in m_action._target
internal string BuildDelegateMethodName(ClrType targetType, dynamic action)
{
    var methodPtr = action._methodPtr;
    if (methodPtr != null)
    {
        ClrMethod method = _clr.GetMethodByAddress((ulong)methodPtr);
if (method == null)
        {
            // could happen in case of static method
            methodPtr = action._methodPtrAux;
            method = _clr.GetMethodByAddress((ulong)methodPtr);
        }
// 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 (