/// <summary>
        /// Gets the field value from <see cref="IAddressableTypedEntity"/> with respect to field nature (either reference, or value type).
        /// </summary>
        /// <param name="entity">The entity to read field value from.</param>
        /// <param name="fieldName">The name of the field to get value.</param>
        /// <exception cref="ArgumentNullException">if entity has no type.</exception>
        /// <exception cref="ArgumentException">Thrown when field with matching name was not found.</exception>
        /// <returns></returns>
        public static IAddressableTypedEntity GetFieldFrom(this IAddressableTypedEntity entity, string fieldName)
        {
            ClrType entityType = entity?.Type ?? throw new ArgumentNullException(nameof(entity), "No associated type");

            ClrInstanceField field = entityType.GetFieldByName(fieldName) ?? throw new ArgumentException($"Type '{entityType}' does not contain a field named '{fieldName}'");

            return(field.IsObjectReference ? (IAddressableTypedEntity)entity.GetObjectField(fieldName) : entity.GetValueClassField(fieldName));
        }
Пример #2
0
        public IEnumerable <KeyValuePair <string, string> > EnumerateConcurrentDictionary(ulong address)
        {
            bool isNetCore        = IsNetCore();
            var  tablesFieldName  = isNetCore ? "_tables" : "m_tables";
            var  bucketsFieldName = isNetCore ? "_buckets" : "m_buckets";
            var  keyFieldName     = isNetCore ? "_key" : "m_key";
            var  valueFieldName   = isNetCore ? "_value" : "m_value";
            var  nextFieldName    = isNetCore ? "_next" : "m_next";

            var cd = _heap.GetObject(address);

            if (!cd.IsValid)
            {
                throw new InvalidOperationException("Adress does not correspond to a ConcurrentDictionary");
            }
            var tables = cd.ReadObjectField(tablesFieldName);

            if (!tables.IsValid)
            {
                throw new InvalidOperationException($"ConcurrentDictionary does not own {tablesFieldName} attribute");
            }
            var buckets = tables.ReadObjectField(bucketsFieldName);

            if (!buckets.IsValid)
            {
                throw new InvalidOperationException($"ConcurrentDictionary tables does not own {bucketsFieldName} attribute");
            }
            var bucketsArray = buckets.AsArray();

            for (int i = 0; i < bucketsArray.Length; i++)
            {
                var node = bucketsArray.GetObjectValue(i);
                IAddressableTypedEntity keyField = null, valueField = null;
                if (!node.IsNull && node.IsValid)
                {
                    keyField   = node.GetFieldFrom(keyFieldName);
                    valueField = node.GetFieldFrom(valueFieldName);

                    if (keyField == null || valueField == null)
                    {
                        throw new InvalidOperationException($"Concurrent dictionary doesn't contain {keyFieldName} and {valueFieldName} attributes. This command may not be compatible with the current runtime");
                    }
                }
                // Node is at the head object of a linked list
                while (!node.IsNull && node.IsValid)
                {
                    var key   = DumpPropertyValue(node, keyFieldName);
                    var value = DumpPropertyValue(node, valueFieldName);

                    yield return(new KeyValuePair <string, string>(key, value));

                    node = node.ReadObjectField(nextFieldName);
                }
            }
        }
        public void GetFieldFrom_WhenNullTypePassed_ThrowsArgumentNullException(IAddressableTypedEntity entity, string fieldName)
        {
            // Arrange
            entity.Type.Returns((ClrType)null);

            Action getFieldFromTypelessEntity = () => entity.GetFieldFrom(fieldName);

            getFieldFromTypelessEntity
            .Should().Throw <ArgumentNullException>()
            .And.ParamName.Should().Be(nameof(entity));
        }
        public void GetFieldFrom_WhenStructureHasStructureField_ReturnsField(ClrValueClass target, [Frozen] ClrType structType, ClrValueClass rawStruct, ClrInstanceField structValueField)
        {
            // Arrange
            IAddressableTypedEntity entity = rawStruct;

            structValueField.IsValueClass.Returns(true);
            structValueField.Type.Returns(entity.Type);
            structValueField.GetAddress(entity.Address, Arg.Any <bool>()).Returns(target.Address);

            // Act
            var structFromStruct = entity.GetFieldFrom(structValueField.Name);

            // Assert
            structFromStruct.Address.Should().Be(target.Address);
        }
        public void GetFieldFrom_WhenFieldFound_ReturnsField([Frozen] ClrHeap heap, ClrValueClass target, [Frozen] ClrType clrObjectType, ClrObject rawClrObject, ClrInstanceField clrObjValueField)
        {
            // Arrange
            IAddressableTypedEntity entity = rawClrObject;

            clrObjValueField.IsValueClass.Returns(true);
            clrObjValueField.Type.Returns(target.Type);

            clrObjValueField
            .GetAddress(rawClrObject.Address)
            .Returns(target.Address);

            // Act
            var structRefFieldTarget = rawClrObject.GetFieldFrom(clrObjValueField.Name);

            // Assert
            structRefFieldTarget.Equals(target).Should().BeTrue();
        }
        public void GetFieldFrom_WhenStructureHasReferenceField_ReturnsField([Frozen] ClrHeap heap, ClrObject target, [Frozen] ClrType structType, ClrValueClass rawStruct, ClrInstanceField structReferenceField, ulong fieldAddress)
        {
            // Arrange
            IAddressableTypedEntity entity = rawStruct;

            structReferenceField.IsObjectReference.Returns(true);
            structReferenceField.GetAddress(entity.Address, Arg.Any <bool>()).Returns(fieldAddress);

            heap.ReadPointer(fieldAddress, out var whatever)
            .Returns(call =>
            {
                call[1] = target.Address;
                return(true);
            });

            // Act
            var fieldByName = entity.GetFieldFrom(structReferenceField.Name);

            // Assert
            fieldByName.Address.Should().Be(target.Address);
        }
        public void GetFieldFrom_WhenClrObjectHasReferenceField_ReturnsField([Frozen] ClrHeap heap, [Frozen] ClrType objectType, ClrObject rawClrObject, ClrInstanceField clrField, ulong fieldAddress, ClrObject target)
        {
            // Arrange
            IAddressableTypedEntity entity = rawClrObject;

            clrField.IsObjectReference.Returns(true);
            clrField.GetAddress(entity.Address).Returns(fieldAddress);

            heap.ReadPointer(fieldAddress, out var whatever)
            .Returns(call =>
            {
                call[1] = target.Address;
                return(true);
            });

            // Act
            var fieldFoundByName = entity.GetFieldFrom(clrField.Name);

            // Assert
            fieldFoundByName.Address.Should().Be(target.Address);
        }
Пример #8
0
        private static bool TryGetSimpleValue(IAddressableTypedEntity item, ClrType type, string fieldName, out string content)
        {
            content = null;
            var typeName = type.Name;

            switch (typeName)
            {
            case "System.Char":
                content = $"'{item.ReadField<System.Char>(fieldName)}'";
                break;

            case "System.Boolean":
                content = item.ReadField <System.Boolean>(fieldName).ToString();
                break;

            case "System.SByte":
                content = item.ReadField <System.SByte>(fieldName).ToString();
                break;

            case "System.Byte":
                content = item.ReadField <System.Byte>(fieldName).ToString();
                break;

            case "System.Int16":
                content = item.ReadField <System.Int16>(fieldName).ToString();
                break;

            case "System.UInt16":
                content = item.ReadField <System.UInt16>(fieldName).ToString();
                break;

            case "System.Int32":
                content = item.ReadField <System.Int32>(fieldName).ToString();
                break;

            case "System.UInt32":
                content = item.ReadField <System.UInt32>(fieldName).ToString();
                break;

            case "System.Int64":
                content = item.ReadField <System.Int64>(fieldName).ToString();
                break;

            case "System.UInt64":
                content = item.ReadField <System.UInt64>(fieldName).ToString();
                break;

            case "System.Single":
                content = item.ReadField <System.Single>(fieldName).ToString();
                break;

            case "System.Double":
                content = item.ReadField <System.Double>(fieldName).ToString();
                break;

            case "System.IntPtr":
            {
                var val = item.ReadField <System.IntPtr>(fieldName);
                content = (val == IntPtr.Zero) ? "null" : $"0x{val.ToInt64():x}";
            }
            break;

            case "System.UIntPtr":
            {
                var val = item.ReadField <System.UIntPtr>(fieldName);
                content = (val == UIntPtr.Zero) ? "null" : $"0x{val.ToUInt64():x}";
            }
            break;

            default:
                return(false);
            }

            return(true);
        }
Пример #9
0
 public bool Equals(IAddressableTypedEntity other)
 => other is ClrObject && Equals((ClrObject)other);
Пример #10
0
 public bool Equals(IAddressableTypedEntity other)
 => other != null && Address == other.Address && Type == other.Type;