提交 b9da72dd 编写于 作者: I Ivan Basov

EE formatters for IntPtr and UIntPtr

上级 a571221b
......@@ -50,5 +50,17 @@ protected static string PointerToString(IntPtr pointer)
return string.Format("0x{0:x8}", pointer.ToInt32());
}
}
protected static string PointerToString(UIntPtr pointer)
{
if (Environment.Is64BitProcess)
{
return string.Format("0x{0:x16}", pointer.ToUInt64());
}
else
{
return string.Format("0x{0:x8}", pointer.ToUInt32());
}
}
}
}
......@@ -743,11 +743,47 @@ internal C(long p)
string fullName = string.Format("*({0}).p", rootExpr);
children = GetChildren(children[0]);
Verify(children,
EvalResult(fullName, "{4}", "System.IntPtr", fullName, DkmEvaluationResultFlags.Expandable));
EvalResult(fullName, "0x00000004", "System.IntPtr", fullName, DkmEvaluationResultFlags.None));
}
}
[Fact]
public void UIntPtrPointer()
{
var source = @"
using System;
unsafe class C
{
internal C(ulong p)
{
this.p = (UIntPtr*)p;
}
UIntPtr* p;
UIntPtr* q;
}";
var assembly = GetUnsafeAssembly(source);
unsafe
{
// NOTE: We're depending on endian-ness to put
// the interesting bytes first when we run this
// test as 32-bit.
ulong i = 4;
ulong p = (ulong)&i;
var type = assembly.GetType("C");
var rootExpr = string.Format("new C({0})", p);
var value = CreateDkmClrValue(type.Instantiate(p));
var evalResult = FormatResult(rootExpr, value);
Verify(evalResult,
EvalResult(rootExpr, "{C}", "C", rootExpr, DkmEvaluationResultFlags.Expandable));
var children = GetChildren(evalResult);
Verify(children,
EvalResult("p", PointerToString(new UIntPtr(p)), "System.UIntPtr*", string.Format("({0}).p", rootExpr), DkmEvaluationResultFlags.Expandable),
EvalResult("q", PointerToString(UIntPtr.Zero), "System.UIntPtr*", string.Format("({0}).q", rootExpr)));
string fullName = string.Format("*({0}).p", rootExpr);
children = GetChildren(children[0]);
Verify(children,
EvalResult("m_value", PointerToString(new IntPtr(i)), "void*", string.Format("({0}).m_value", fullName)),
EvalResult("Static members", null, "", "System.IntPtr", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class));
EvalResult(fullName, "0x00000004", "System.UIntPtr", fullName, DkmEvaluationResultFlags.None));
}
}
......
......@@ -32,17 +32,18 @@ internal sealed class MemberExpansion : Expansion
// For members of type DynamicProperty (part of Dynamic View expansion), we want
// to expand the underlying value (not the members of the DynamicProperty type).
var type = value.Type;
var isDynamicProperty = type.GetLmrType().IsDynamicProperty();
var runtimeType = type.GetLmrType();
var isDynamicProperty = runtimeType.IsDynamicProperty();
if (isDynamicProperty)
{
Debug.Assert(!value.IsNull);
value = value.GetFieldValue("value", inspectionContext);
}
var runtimeType = type.GetLmrType();
// Primitives, enums, function pointers, and null values with a declared type that is an interface have no visible members.
// Primitives, enums, function pointers, IntPtr, UIntPtr and null values with a declared type that is an interface have no visible members.
Debug.Assert(!runtimeType.IsInterface || value.IsNull);
if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer())
if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer() ||
runtimeType.IsIntPtr() || runtimeType.IsUIntPtr())
{
return null;
}
......
......@@ -100,6 +100,11 @@ private string GetValueString(DkmClrValue value, DkmInspectionContext inspection
? _nullString
: GetValueString(nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
}
else if (lmrType.IsIntPtr() || lmrType.IsUIntPtr())
{
var fieldValue = value.GetFieldValue(InternalWellKnownMemberNames.IntPtrAndUIntPtrStringValue, inspectionContext);
return FormatPrimitive(fieldValue, ObjectDisplayOptions.UseHexadecimalNumbers, inspectionContext);
}
else
{
int cardinality;
......
......@@ -7,5 +7,6 @@ internal static class InternalWellKnownMemberNames
public const string NullableHasValue = "hasValue";
public const string NullableValue = "value";
public const string SqlStringValue = "m_value";
public const string IntPtrAndUIntPtrStringValue = "m_value";
}
}
......@@ -272,6 +272,12 @@ internal static bool IsIEnumerable(this Type type)
return type.IsMscorlibType("System.Collections", "IEnumerable");
}
internal static bool IsIntPtr(this Type type)
=> type.IsMscorlibType("System", "IntPtr");
internal static bool IsUIntPtr(this Type type)
=> type.IsMscorlibType("System", "UIntPtr");
internal static bool IsIEnumerableOfT(this Type type)
{
return type.IsMscorlibType("System.Collections.Generic", "IEnumerable`1");
......
......@@ -130,7 +130,7 @@ End Class"
EvalResult("q", PointerToString(IntPtr.Zero), "Integer*", String.Format("({0}).q", rootExpr)))
Dim fullName = String.Format("*({0}).p", rootExpr)
Verify(GetChildren(children(0)),
EvalResult(fullName, "4", "Integer", fullName))
EvalResult(fullName, "4", "Integer", fullName, DkmEvaluationResultFlags.None))
End Sub
<Fact>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册