Beispiel #1
0
        private DesktopBlockingObject CreateRWSObject(ulong obj, ClrType type)
        {
            if (type == null)
            {
                return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None));
            }

            ClrInstanceField field = type.GetFieldByName("writeLockOwnerId");

            if (field != null && field.ElementType == ClrElementType.Int32)
            {
                int       id     = (int)field.GetValue(obj);
                ClrThread thread = GetThreadById(id);
                if (thread != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired));
                }
            }

            field = type.GetFieldByName("upgradeLockOwnerId");
            if (field != null && field.ElementType == ClrElementType.Int32)
            {
                int       id     = (int)field.GetValue(obj);
                ClrThread thread = GetThreadById(id);
                if (thread != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired));
                }
            }

            field = type.GetFieldByName("rwc");
            if (field != null)
            {
                List <ClrThread> threads      = null;
                ulong            rwc          = (ulong)field.GetValue(obj);
                ClrType          rwcArrayType = _heap.GetObjectType(rwc);
                if (rwcArrayType != null && rwcArrayType.IsArray && rwcArrayType.ComponentType != null)
                {
                    ClrType          rwcType  = rwcArrayType.ComponentType;
                    ClrInstanceField threadId = rwcType.GetFieldByName("threadid");
                    ClrInstanceField next     = rwcType.GetFieldByName("next");
                    if (threadId != null && next != null)
                    {
                        int count = rwcArrayType.GetArrayLength(rwc);
                        for (int i = 0; i < count; ++i)
                        {
                            ulong entry = (ulong)rwcArrayType.GetArrayElementValue(rwc, i);
                            GetThreadEntry(ref threads, threadId, next, entry, false);
                        }
                    }
                }

                if (threads != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, BlockingReason.ReaderAcquired, threads.ToArray()));
                }
            }

            return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None));
        }
Beispiel #2
0
        private static void PrintArray(ClrRuntime runtime)

        {
            var heap = runtime.Heap;

            var intArrays = from o in heap.EnumerateObjects()
                            let t = heap.GetObjectType(o)
                                    where t.IsArray && t.Name == "System.Int32[]"
                                    select new { Address = o, Type = t };

            foreach (var item in intArrays)
            {
                ClrType type = item.Type;
                ulong   obj  = item.Address;

                int len = type.GetArrayLength(obj);

                Console.WriteLine("Object: {0:X}", obj);
                Console.WriteLine("Length: {0}", len);
                Console.WriteLine("Elements:");

                for (int i = 0; i < len; i++)
                {
                    Console.WriteLine("{0,3} - {1}", i, type.GetArrayElementValue(obj, i));
                }
            }
        }
Beispiel #3
0
        static void ReadComplexArray(ClrType type, ulong obj)
        {
            int len = type.GetArrayLength(obj);

            Console.WriteLine("Object: {0:X}", obj);
            Console.WriteLine("Type:   {0}", type.Name);
            Console.WriteLine("Length: {0}", len);
            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(obj, i);
                foreach (var field in type.ComponentType.Fields)
                {
                    string output;
                    if (field.HasSimpleValue)
                    {
                        var tmpOutput = field.GetValue(addr, true);
                        if (tmpOutput == null)
                        {
                            continue;
                        }
                        output = tmpOutput.ToString();        // <- true here, as this is an embedded struct
                    }
                    else
                    {
                        output = field.GetAddress(addr, true).ToString("X");   // <- true here as well
                    }

                    Console.WriteLine("{0}  +{1,2:X2} {2} {3} = {4}", i, field.Offset, field.Type.Name, field.Name, output);
                }
            }
        }
Beispiel #4
0
        public static List <KVP> GetKVPs(ClrType type, ulong items)
        {
            int length = type.GetArrayLength(items);
            var ret    = new List <KVP>();

            for (int i = 0; i < length; i++)
            {
                ulong addr = type.GetArrayElementAddress(items, i);

                var keyField = type.ComponentType.GetFieldByName("key");
                var key      = (ulong)keyField.GetValue(addr - (ulong)IntPtr.Size);

                // no need to add these pre-allocated entries
                if (key == 0)
                {
                    continue;
                }

                var valueField = type.ComponentType.GetFieldByName("value");
                var value      = (ulong)valueField.GetValue(addr - (ulong)IntPtr.Size);

                ret.Add(new KVP(key, value));
            }

            return(ret);
        }
Beispiel #5
0
        private int GetClrTypeArrayLength(Tuple <int, ulong> input)
        {
            int     clrTypeId = input.Item1;
            ulong   address   = input.Item2;
            ClrType clrType   = clrTypesCache[clrTypeId];

            return(clrType.GetArrayLength(address));
        }
Beispiel #6
0
        static void ReadSimpleArray(ClrType type, ulong obj)
        {
            int len = type.GetArrayLength(obj);

            Console.WriteLine("Object: {0:X}", obj);
            Console.WriteLine("Length: {0}", len);
            Console.WriteLine("Elements:");

            for (int i = 0; i < len; i++)
            {
                Console.WriteLine("{0,3} - {1}", i, type.GetArrayElementValue(obj, i));
            }
        }
Beispiel #7
0
        public string GetFieldNameReferenceImpl(ulong refAddress, ulong address, bool prefixWithType)
        {
            ClrType type = GetObjectTypeImpl(address);

            if (type == null)
            {
                return("Unknown");
            }
            string    fieldName = "???";
            ClrObject obj       = new ClrObject(address, type);

            if (type.IsArray)
            {
                fieldName = "[ ? ]";
                var length = type.GetArrayLength(address);
                for (int i = 0; i < length; i++)
                {
                    if (obj[i].Address == refAddress)
                    {
                        fieldName = $"[ {i} ]";
                    }
                }
            }
            else
            {
                foreach (var field in type.Fields)
                {
                    switch (field.ElementType)
                    {
                    case ClrElementType.Struct:
                    case ClrElementType.String:
                    case ClrElementType.Array:
                    case ClrElementType.SZArray:
                    case ClrElementType.Object:
                        var fieldValue = obj[field];
                        if (fieldValue.Address == refAddress)
                        {
                            fieldName = field.Name;
                        }
                        break;
                    }
                }
            }
            if (prefixWithType)
            {
                fieldName = $"{fieldName}@{type.Name}";
            }

            return(fieldName);
        }
Beispiel #8
0
        public static List <ulong> GetArrayItems(ClrType type, ulong items)
        {
            int length = type.GetArrayLength(items);
            var ret    = new List <ulong>();

            for (int i = 0; i < length; i++)
            {
                var val = (ulong)type.GetArrayElementValue(items, i);

                if (val != 0)
                {
                    ret.Add(val);
                }
            }

            return(ret);
        }
Beispiel #9
0
        public void ForEach(ulong arrayAddress, Action <ulong> action)
        {
            ClrType type   = ManagedHeap.GetObjectType(arrayAddress);
            int     length = type.GetArrayLength(arrayAddress);

            for (int element = 0; element < length; element++)
            {
                var   val            = type.GetArrayElementValue(arrayAddress, element);
                ulong elementAddress = (ulong)val;
                if (elementAddress == 0)
                {
                    continue;
                }

                action(elementAddress);
            }
        }
Beispiel #10
0
        public void ArrayLengthTest()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrAppDomain domain = runtime.AppDomains.Single();

                ClrModule typesModule = runtime.GetModule("types.exe");
                ClrType   type        = heap.GetTypeByName("Types");

                ulong   s_array   = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain);
                ClrType arrayType = heap.GetObjectType(s_array);

                Assert.Equal(3, arrayType.GetArrayLength(s_array));
            }
        }
        public List <T> Read <T>() where T : new()
        {
            ClrType type = Heap.GetObjectType(Value.Address);

            // Only consider types which are arrays that do not have simple values (I.E., are structs).
            if (!type.IsArray || type.ComponentType.HasSimpleValue)
            {
                return(null);
            }

            int len = type.GetArrayLength(Value.Address);

            List <T> list = new List <T>();

            FieldInfo[] fields = typeof(T).GetFields();

            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(Value.Address, i);

                T item = new T();
                foreach (var field in type.ComponentType.Fields)
                {
                    if (!field.HasSimpleValue)
                    {
                        continue;
                    }

                    for (int j = 0; j < fields.Length; j++)
                    {
                        if (fields[j].Name == field.Name)
                        {
                            var val = field.GetValue(addr, true);
                            typeof(T).GetField(field.Name).SetValueDirect(__makeref(item), val);
                        }
                    }
                }
                list.Add(item);
            }

            return(list);
        }
Beispiel #12
0
        internal override IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type)
        {
            // TODO: Review this and if it works on v4.5, merge the two implementations back into RuntimeBase.
            List <ClrStackFrame> result = new List <ClrStackFrame>();

            if (type == null)
            {
                return(result);
            }

            if (!GetStackTraceFromField(type, obj, out ulong _stackTrace))
            {
                if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace))
                {
                    return(result);
                }
            }

            if (_stackTrace == 0)
            {
                return(result);
            }

            ClrHeap heap           = Heap;
            ClrType stackTraceType = heap.GetObjectType(_stackTrace);

            if (stackTraceType == null || !stackTraceType.IsArray)
            {
                return(result);
            }

            int len = stackTraceType.GetArrayLength(_stackTrace);

            if (len == 0)
            {
                return(result);
            }

            int   elementSize = IntPtr.Size * 4;
            ulong dataPtr     = _stackTrace + (ulong)(IntPtr.Size * 2);

            if (!ReadPointer(dataPtr, out ulong count))
            {
                return(result);
            }

            // Skip size and header
            dataPtr += (ulong)(IntPtr.Size * 2);

            DesktopThread thread = null;

            for (int i = 0; i < (int)count; ++i)
            {
                if (!ReadPointer(dataPtr, out ulong ip))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out ulong sp))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out ulong md))
                {
                    break;
                }

                if (i == 0 && sp != 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                // it seems that the first frame often has 0 for IP and SP.  Try the 2nd frame as well
                if (i == 1 && thread == null && sp != 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                result.Add(new DesktopStackFrame(this, thread, null, ip, sp, md));

                dataPtr += (ulong)elementSize;
            }

            return(result);
        }
Beispiel #13
0
        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            if (IsNull())
            {
                result = new ClrNullValue(m_heap);
                return(true);
            }

            if (m_type.IsArray)
            {
                // Populate length for bounds check.
                if (m_len == -1)
                {
                    m_len = m_type.GetArrayLength(m_addr);
                }

                int index = GetIndexFromObjects(indexes);
                return(GetArrayValue(m_type, m_addr, index, out result));
            }

            // Dictionary
            if (IsDictionary())
            {
                if (indexes.Length != 1)
                {
                    throw new ArgumentException("Only one index is allowed for Dictionary indexing.");
                }

                dynamic          dict    = ((dynamic)this);
                dynamic          entries = dict.entries;
                ClrInstanceField key     = ((ClrType)entries).ArrayComponentType.GetFieldByName("key");

                // Two cases:  The key is an object or string, denoted by "System.__Canon", or it's a primitive.
                //             otherwise we don't support it.
                var keyType = key.Type;
                if (keyType.IsObjectReference)
                {
                    Debug.Assert(keyType.Name == "System.__Canon");
                    if (indexes[0].GetType() == typeof(string))
                    {
                        string index = (string)indexes[0];
                        int    len   = dict.count;
                        for (int i = 0; i < len; ++i)
                        {
                            if ((string)entries[i].key == index)
                            {
                                result = entries[i].value;
                                return(true);
                            }
                        }

                        throw new KeyNotFoundException();
                    }
                    else
                    {
                        ulong addr;
                        if (indexes[0].GetType() == typeof(long))
                        {
                            addr = (ulong)(long)indexes[0];
                        }
                        else if (indexes[0].GetType() == typeof(ulong))
                        {
                            addr = (ulong)indexes[0];
                        }
                        else
                        {
                            addr = (ulong)(dynamic)indexes[0];
                        }

                        int len = dict.count;
                        for (int i = 0; i < len; ++i)
                        {
                            if ((ulong)entries[i].key == addr)
                            {
                                result = entries[i].value;
                                return(true);
                            }
                        }
                    }
                }
                else if (keyType.IsPrimitive)
                {
                    object index = indexes[0];
                    if (index is ClrPrimitiveValue)
                    {
                        index = ((ClrPrimitiveValue)index).GetValue();
                    }
                    Type type = index.GetType();
                    int  len  = dict.count;
                    for (int i = 0; i < len; ++i)
                    {
                        ClrPrimitiveValue value = entries[i].key;
                        if (value.GetValue().Equals(index))
                        {
                            result = entries[i].value;
                            return(true);
                        }
                    }

                    throw new KeyNotFoundException();
                }
            }

            if (IsList())
            {
                int   index      = GetIndexFromObjects(indexes);
                var   itemsField = m_type.GetFieldByName("_items");
                ulong addr       = (ulong)itemsField.GetFieldValue(m_addr);

                // Populate length for bounds check.
                if (m_len == -1)
                {
                    var sizeField = m_type.GetFieldByName("_size");
                    m_len = (int)sizeField.GetFieldValue(m_addr);
                }

                // If type is null, then we've hit a dac bug.  Attempt to work around it,
                // but we'll have to give up if getting the object type directly doesn't work.
                ClrType type = itemsField.Type;
                if (type == null || type.ArrayComponentType == null)
                {
                    type = m_heap.GetObjectType(addr);
                    if (type == null || type.ArrayComponentType == null)
                    {
                        result = new ClrNullValue(m_heap);
                        return(true);
                    }
                }

                return(GetArrayValue(type, addr, index, out result));
            }

            throw new InvalidOperationException(string.Format("Object of type '{0}' is not indexable.", m_type.Name));
        }
Beispiel #14
0
        private static Dictionary <string, HeapObjectCounter> GetObjectOwners(ClrRuntime runtime, HashSet <ulong> instances)
        {
            Dictionary <string, HeapObjectCounter> dict = new Dictionary <string, HeapObjectCounter>();

            if (!runtime.Heap.CanWalkHeap)
            {
                Console.WriteLine("Cannot walk the heap!");
            }
            else
            {
                foreach (ClrSegment seg in runtime.Heap.Segments)
                {
                    for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj))
                    {
                        ClrType type = runtime.Heap.GetObjectType(obj);

                        if (type == null || type.IsFree == true)
                        {
                            continue;
                        }

                        string typeName = type.ToString();

                        int gen = runtime.Heap.GetGeneration(obj);
                        if (gen != 2)
                        {
                            continue;
                        }

                        if (type.IsArray == true)
                        {
                            int arrayLength = type.GetArrayLength(obj);
                            for (int i = 0; i < arrayLength; i++)
                            {
                                ulong elemAddress = type.GetArrayElementAddress(obj, i);

                                ClrType elemType = type.ComponentType;
                                if (elemType.IsValueClass == false)
                                {
                                    ulong elemRef = ReadMemory(runtime, elemAddress);
                                    if (instances.Contains(elemRef) == true)
                                    {
                                        if (dict.ContainsKey(typeName) == true)
                                        {
                                            dict[typeName].AddCount(obj);
                                        }
                                        else
                                        {
                                            dict.Add(typeName, new HeapObjectCounter(obj));
                                        }
                                    }
                                }
                                else
                                {
                                    AddItem(type, typeName, obj);
                                }
                            }
                        }
                        else
                        {
                            AddItem(type, typeName, obj);
                        }
                    }
                }
            }

            return(dict);

            void AddItem(ClrType type, string typeName, ulong objAddress)
            {
                foreach (ClrInstanceField field in type.Fields)
                {
                    ulong fieldAddress = GetFieldAddressValue(runtime, field, objAddress);

                    if (instances.Contains(fieldAddress) == true)
                    {
                        if (dict.ContainsKey(typeName) == true)
                        {
                            dict[typeName].AddCount(objAddress);
                        }
                        else
                        {
                            dict.Add(typeName, new HeapObjectCounter(objAddress));
                        }
                    }
                }
            }
        }
Beispiel #15
0
        internal override IList <ClrStackFrame> GetExceptionStackTrace(ulong obj, ClrType type)
        {
            List <ClrStackFrame> result = new List <ClrStackFrame>();

            if (!GetStackTraceFromField(type, obj, out ulong _stackTrace))
            {
                if (!ReadPointer(obj + GetStackTraceOffset(), out _stackTrace))
                {
                    return(result);
                }
            }

            if (_stackTrace == 0)
            {
                return(result);
            }

            DesktopGCHeap heap           = (DesktopGCHeap)Heap;
            ClrType       stackTraceType = heap.GetObjectType(_stackTrace);

            if (stackTraceType == null)
            {
                stackTraceType = heap.ArrayType;
            }

            if (!stackTraceType.IsArray)
            {
                return(result);
            }

            int len = stackTraceType.GetArrayLength(_stackTrace);

            if (len == 0)
            {
                return(result);
            }

            int   elementSize = CLRVersion == DesktopVersion.v2 ? IntPtr.Size * 4 : IntPtr.Size * 3;
            ulong dataPtr     = _stackTrace + (ulong)(IntPtr.Size * 2);

            if (!ReadPointer(dataPtr, out ulong count))
            {
                return(result);
            }

            // Skip size and header
            dataPtr += (ulong)(IntPtr.Size * 2);

            DesktopThread thread = null;

            for (int i = 0; i < (int)count; ++i)
            {
                if (!ReadPointer(dataPtr, out ulong ip))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)IntPtr.Size, out ulong sp))
                {
                    break;
                }
                if (!ReadPointer(dataPtr + (ulong)(2 * IntPtr.Size), out ulong md))
                {
                    break;
                }

                if (i == 0)
                {
                    thread = (DesktopThread)GetThreadByStackAddress(sp);
                }

                result.Add(new DesktopStackFrame(this, thread, null, ip, sp, md));

                dataPtr += (ulong)elementSize;
            }

            return(result);
        }
Beispiel #16
0
 /// <summary>
 ///     If the type is an array, then GetArrayLength returns the number of elements in the array.  Undefined
 ///     behavior if this type is not an array.
 /// </summary>
 /// <param name="objRef">The object reference.</param>
 /// <returns>System.Int32.</returns>
 public int GetArrayLength(ulong objRef) => ClrType.GetArrayLength(objRef);
        public override IClrObjMappingModel ReadEntity(ClrObject obj, ModelMapperFactory factory)
        {
            var hashtableModel = new HashtableMappingModel
            {
                Obj = obj
            };

            ClrObject entriesField = obj.GetRefFld(entriesFldName);

            if (entriesField == null || entriesField.Type == null)
            {
                // Object contains this field, but value is null.
                // Most likely dictionary is either in the middle of construction, or destruction.
                // Anyway we can assume it is empty.
                return(hashtableModel);
            }

            ClrType type = entriesField.Type;

            ClrHeap heap = type.Heap;

            var componentType = type.ComponentType;

            if (componentType == null)
            {
                // TODO :Try reload type.
                return(null);
            }

            ClrInstanceField valueField = componentType.GetFieldByName("value");

            ClrInstanceField keyField = componentType.GetFieldByName("key");

            int len = type.GetArrayLength(entriesField.Address);

            ulong entriesFieldAddress = entriesField.Address;

            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(entriesFieldAddress, i);

                if (addr == 0)
                {
                    continue;
                }
                try
                {
                    var key = keyField.GetValue(addr, true);
                    if (!(key is ulong))
                    {
                        continue;
                    }
                    var keyPointer = (ulong)key;
                    if (keyPointer == 0)
                    {
                        continue;
                    }

                    var val = valueField.GetValue(addr, true);

                    ulong valuePointer;
                    if (val is ulong)
                    {
                        valuePointer = (ulong)val;
                    }
                    else
                    {
                        valuePointer = 0;
                    }

                    var keyObj = new ClrObject(keyPointer, heap);
                    var valObj = new ClrObject(valuePointer, heap);

                    hashtableModel.Elements.Add(factory.BuildModel(keyObj),
                                                factory.BuildModel(valObj));
                }
                catch (Exception)
                {
                    Trace.TraceError("Count not read {0} object", obj.HexAddress);

                    // Do nothing for now
                }
            }

            return(hashtableModel);
        }
Beispiel #18
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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #19
0
    public static void PrintDict(ClrRuntime runtime, string args)
    {
        bool  failed = false;
        ulong obj    = 0;

        try
        {
            obj    = Convert.ToUInt64(args, 16);
            failed = obj == 0;
        }
        catch (ArgumentException)
        {
            failed = true;
        }

        if (failed)
        {
            Console.WriteLine("Usage: !PrintDict <dictionary>");
            return;
        }

        ClrHeap heap = runtime.GetHeap();
        ClrType type = heap.GetObjectType(obj);

        if (type == null)
        {
            Console.WriteLine("Invalid object {0:X}", obj);
            return;
        }

        if (!type.Name.StartsWith("System.Collections.Generic.Dictionary"))
        {
            Console.WriteLine("Error: Expected object {0:X} to be a dictionary, instead it's of type '{1}'.");
            return;
        }

        // Get the entries field.
        ulong entries = type.GetFieldValue(obj, "entries");

        if (entries == 0)
        {
            return;
        }

        ClrType          entryArray     = heap.GetObjectType(entries);
        ClrType          arrayComponent = entryArray.ComponentType;
        ClrInstanceField hashCodeField  = arrayComponent.GetFieldByName("hashCode");
        ClrInstanceField keyField       = arrayComponent.GetFieldByName("key");
        ClrInstanceField valueField     = arrayComponent.GetFieldByName("value");

        Console.WriteLine("{0,8} {1,16} : {2}", "hash", "key", "value");
        int len = entryArray.GetArrayLength(entries);

        for (int i = 0; i < len; ++i)
        {
            ulong arrayElementAddr = entryArray.GetArrayElementAddress(entries, i);

            int    hashCode = (int)hashCodeField.GetValue(arrayElementAddr, true);
            object key      = keyField.GetValue(arrayElementAddr, true);
            object value    = valueField.GetValue(arrayElementAddr, true);

            key   = Format(heap, key);
            value = Format(heap, value);

            bool skip = key is ulong && (ulong)key == 0 && value is ulong && (ulong)value == 0;

            if (!skip)
            {
                Console.WriteLine("{0,8:X} {1,16} : {2}", hashCode, key, value);
            }
        }
    }
Beispiel #20
0
        private List <ClrObjectModel> GetValues(ulong obj, ClrType type, string baseName, int offset, bool inner, List <ClrObjectModel> values)
        {
            if (type.Name == "System.String")
            {
                object value;
                try
                {
                    value = type.GetValue(obj);
                }
                catch (Exception ex)
                {
                    value = ex.Message;
                }
                values.Add(new ClrObjectModel {
                    Address = obj, BaseName = baseName, TypeName = type.Name, Value = value
                });
                values.AddRange(type.Fields.Select(field => new ClrObjectModel {
                    Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = field.GetValue(obj, inner).ToString()
                }));
            }
            else if (type.IsArray)
            {
                int len = type.GetArrayLength(obj);

                if (type.ComponentType == null)
                {
                    try
                    {
                        for (int i = 0; i < len; i++)
                        {
                            values.Add(new ClrObjectModel {
                                Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i)
                            });
                        }
                    }
                    catch { }
                }
                else if (type.ComponentType.HasSimpleValue)
                {
                    for (int i = 0; i < len; i++)
                    {
                        values.Add(new ClrObjectModel {
                            Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i)
                        });
                    }
                }
                else
                {
                    for (int i = 0; i < len; i++)
                    {
                        ulong arrAddress = type.GetArrayElementAddress(obj, i);

                        foreach (var field in type.ComponentType.Fields)
                        {
                            string value;
                            if (field.HasSimpleValue)
                            {
                                value = field.GetValue(arrAddress, inner).ToString();   // an embedded struct
                            }
                            else
                            {
                                value = field.GetAddress(arrAddress, inner).ToString();
                            }

                            values.Add(new ClrObjectModel {
                                Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = value
                            });

                            if (field.ElementType == ClrElementType.Struct)
                            {
                                values.AddRange(GetValues(arrAddress, field.Type, baseName + field.Name, offset + field.Offset, true, new List <ClrObjectModel>()));
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (var field in type.Fields)
                {
                    ulong addr = field.GetAddress(obj, inner);

                    object value;
                    if (field.HasSimpleValue)
                    {
                        try
                        {
                            value = field.GetValue(obj, inner);
                        }
                        catch (Exception)
                        {
                            value = "{Unknown}";
                        }
                    }
                    else
                    {
                        value = addr;
                    }

                    string sValue = value?.ToString() ?? "{Null}";
                    values.Add(new ClrObjectModel {
                        Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = sValue
                    });

                    if (field.ElementType == ClrElementType.Struct)
                    {
                        values.AddRange(GetValues(addr, field.Type, baseName + field.Name, offset + field.Offset, true, new List <ClrObjectModel>()));
                    }
                }
            }

            return(values);
        }
Beispiel #21
0
 public void GetArrayLength(ulong objRef, out int pLength)
 {
     pLength = m_type.GetArrayLength(objRef);
 }