Пример #1
0
        public static ClrObject GetStaticObjectValue(this ClrType mainType, string fieldName)
        {
            ClrStaticField field = mainType.GetStaticFieldByName(fieldName);
            ulong          obj   = (ulong)field.GetValue(field.Type.Heap.Runtime.AppDomains.Single());

            return(new ClrObject(obj, mainType.Heap.GetObjectType(obj)));
        }
        public static ClrObject GetStaticFldValue(this ClrRuntime runtime, [NotNull] ClrType clrType,
                                                  [NotNull] string fieldName)
        {
            Assert.ArgumentNotNull(clrType, "typeName");
            Assert.ArgumentNotNullOrEmpty(fieldName, "fieldName");

            ClrStaticField fld = clrType.GetStaticFieldByName(fieldName);

            if (fld == null)
            {
                throw new MissingFieldException(clrType.Name, fieldName);
            }

            var domains = runtime.AppDomains.ToArray();

            if ((domains == null) || (domains.Length == 0))
            {
                throw new ArgumentException("No domains are found inside runtime!");
            }

            ulong?resultAddress = (from domain in domains
                                   where !string.IsNullOrWhiteSpace(domain.Name)
                                   where !domain.Name.Contains("Default") && fld.IsInitialized(domain)
                                   select(ulong?) fld.GetValue(domain)).FirstOrDefault();

            return(resultAddress.HasValue ? (new ClrObject(resultAddress.Value, clrType.Heap))
        : ClrObject.NullObject);
        }
Пример #3
0
        public dynamic GetValue(ClrAppDomain appDomain)
        {
            if (m_field.IsPrimitive())
            {
                object value = m_field.GetValue(appDomain);
                if (value != null)
                {
                    return(new ClrPrimitiveValue(value, m_field.ElementType));
                }
            }
            else if (m_field.IsValueClass())
            {
                ulong addr = m_field.GetAddress(appDomain);
                if (addr != 0)
                {
                    return(new ClrObject(m_heap, m_field.Type, addr, true));
                }
            }
            else if (m_field.ElementType == ClrElementType.String)
            {
                ulong addr = m_field.GetAddress(appDomain);
                if (m_heap.GetRuntime().ReadPointer(addr, out addr))
                {
                    return(new ClrObject(m_heap, m_field.Type, addr));
                }
            }
            else
            {
                object value = m_field.GetValue(appDomain);
                if (value != null)
                {
                    return(new ClrObject(m_heap, m_field.Type, (ulong)value));
                }
            }

            return(new ClrNullValue(m_heap));
        }
Пример #4
0
        public void IntegerObjectClrType()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrStaticField field = runtime.GetModule("types.exe").GetTypeByName("Types").GetStaticFieldByName("s_i");

                ulong   addr = (ulong)field.GetValue(runtime.AppDomains.Single());
                ClrType type = heap.GetObjectType(addr);
                Assert.True(type.IsPrimitive);
                Assert.False(type.IsObjectReference);
                Assert.False(type.IsValueClass);

                object value = type.GetValue(addr);
                Assert.Equal("42", value.ToString());
                Assert.IsType <int>(value);
                Assert.Equal(42, (int)value);

                Assert.Contains(addr, heap.EnumerateObjectAddresses());
            }
        }
Пример #5
0
        public IEnumerable <ObjectInfo> EnumerateManagedWorkItems()
        {
            ClrStaticField workQueueField = ClrMdUtils.GetCorlib(runtime).GetTypeByName("System.Threading.ThreadPoolGlobals")?.GetStaticFieldByName("workQueue");

            if (workQueueField != null)
            {
                object workQueueValue = workQueueField.GetValue(domain);
                ulong  workQueueRef   = (workQueueValue == null) ? 0L : (ulong)workQueueValue;
                if (workQueueRef != 0)
                {
                    ClrType workQueueType = heap.GetObjectType(workQueueRef);                   // should be System.Threading.ThreadPoolWorkQueue
                    if (workQueueType?.Name == "System.Threading.ThreadPoolWorkQueue")
                    {
                        foreach (var item in EnumerateThreadPoolWorkQueue(workQueueRef))
                        {
                            yield return(new ObjectInfo {
                                Address = item, Type = heap.GetObjectType(item)
                            });
                        }
                    }
                }
            }
        }
Пример #6
0
 public override IEnumerable <ObjectInfo> EnumerateTimerTasks()
 {
     if (fieldSQueue.IsInitialized(domain))
     {
         var timeQueue = (ulong)fieldSQueue.GetValue(domain);
         for (ulong timer = (ulong)fieldTimers.GetValue(timeQueue); timer != 0; timer = (ulong)fieldNext.GetValue(timer))
         {
             var state = (ulong)fieldState.GetValue(timer);
             if (state != 0)
             {
                 var typeState = heap.GetObjectType(state);
                 if (typeState == typeDelayPromise)
                 {
                     var continuation = (ulong)fieldTaskContinuationObject.GetValue(state);
                     var target       = (ulong)fieldDelegateTarget.GetValue(continuation);
                     var stateMachine = (ulong)fieldStateMachine.GetValue(target);
                     yield return(new ObjectInfo {
                         Address = stateMachine, Type = heap.GetObjectType(stateMachine)
                     });
                 }
             }
         }
     }
 }
Пример #7
0
        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);
            }
        }
Пример #8
0
 /// <summary>
 ///     Gets the value of the static field.
 /// </summary>
 /// <param name="appDomain">The AppDomain in which to get the value.</param>
 /// <returns>The value of this static field.</returns>
 /// <inheritdoc />
 public object GetValue(IClrAppDomain appDomain) =>
 StaticField.GetValue((appDomain as ClrAppDomainAdapter)?.AppDomain);
Пример #9
0
        private static IEnumerable <TimerInfo> EnumerateTimers(ClrRuntime clr)
        {
            var timerQueueType = Utils.GetMscorlib(clr).GetTypeByName("System.Threading.TimerQueue");

            if (timerQueueType == null)
            {
                yield break;
            }

            ClrStaticField instanceField = timerQueueType.GetStaticFieldByName("s_queue");

            if (instanceField == null)
            {
                yield break;
            }

            var heap = clr.Heap;

            foreach (ClrAppDomain domain in clr.AppDomains)
            {
                ulong?timerQueue = (ulong?)instanceField.GetValue(domain);
                if (!timerQueue.HasValue || timerQueue.Value == 0)
                {
                    continue;
                }

                ClrType t = heap.GetObjectType(timerQueue.Value);
                if (t == null)
                {
                    continue;
                }

                // m_timers is the start of the list of TimerQueueTimer
                var currentPointer = Utils.GetFieldValue(heap, timerQueue.Value, "m_timers");

                while ((currentPointer != null) && (((ulong)currentPointer) != 0))
                {
                    // currentPointer points to a TimerQueueTimer instance
                    ulong currentTimerQueueTimerRef = (ulong)currentPointer;

                    TimerInfo ti = new TimerInfo()
                    {
                        TimerQueueTimerAddress = currentTimerQueueTimerRef
                    };

                    var val = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_dueTime");
                    ti.DueTime       = (uint)val;
                    val              = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_period");
                    ti.Period        = (uint)val;
                    val              = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_canceled");
                    ti.Cancelled     = (bool)val;
                    val              = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_state");
                    ti.StateTypeName = "";
                    if (val == null)
                    {
                        ti.StateAddress = 0;
                    }
                    else
                    {
                        ti.StateAddress = (ulong)val;
                        var stateType = heap.GetObjectType(ti.StateAddress);
                        if (stateType != null)
                        {
                            ti.StateTypeName = stateType.Name;
                        }
                    }

                    // decypher the callback details
                    val = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_timerCallback");
                    if (val != null)
                    {
                        ulong elementAddress = (ulong)val;
                        if (elementAddress == 0)
                        {
                            continue;
                        }

                        var elementType = heap.GetObjectType(elementAddress);
                        if (elementType != null)
                        {
                            if (elementType.Name == "System.Threading.TimerCallback")
                            {
                                ti.MethodName = Utils.BuildTimerCallbackMethodName(clr, heap, elementAddress);
                            }
                            else
                            {
                                ti.MethodName = "<" + elementType.Name + ">";
                            }
                        }
                        else
                        {
                            ti.MethodName = "{no callback type?}";
                        }
                    }
                    else
                    {
                        ti.MethodName = "???";
                    }

                    yield return(ti);

                    currentPointer = Utils.GetFieldValue(heap, currentTimerQueueTimerRef, "m_next");
                }
            }
        }
Пример #10
0
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }