/// <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)); }
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); }
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); }
public bool Equals(IAddressableTypedEntity other) => other is ClrObject && Equals((ClrObject)other);
public bool Equals(IAddressableTypedEntity other) => other != null && Address == other.Address && Type == other.Type;