Skip to content

Commit 08bdc66

Browse files
authored
EE formatters for IntPtr and UIntPtr
2 parents a393757 + f91dc7e commit 08bdc66

File tree

6 files changed

+89
-8
lines changed

6 files changed

+89
-8
lines changed

src/ExpressionEvaluator/CSharp/Test/ResultProvider/CSharpResultProviderTestBase.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,17 @@ protected static string PointerToString(IntPtr pointer)
5050
return string.Format("0x{0:x8}", pointer.ToInt32());
5151
}
5252
}
53+
54+
protected static string PointerToString(UIntPtr pointer)
55+
{
56+
if (Environment.Is64BitProcess)
57+
{
58+
return string.Format("0x{0:x16}", pointer.ToUInt64());
59+
}
60+
else
61+
{
62+
return string.Format("0x{0:x8}", pointer.ToUInt32());
63+
}
64+
}
5365
}
5466
}

src/ExpressionEvaluator/CSharp/Test/ResultProvider/ExpansionTests.cs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -743,11 +743,47 @@ internal C(long p)
743743
string fullName = string.Format("*({0}).p", rootExpr);
744744
children = GetChildren(children[0]);
745745
Verify(children,
746-
EvalResult(fullName, "{4}", "System.IntPtr", fullName, DkmEvaluationResultFlags.Expandable));
746+
EvalResult(fullName, IntPtr.Size == 8 ? "0x0000000000000004" : "0x00000004", "System.IntPtr", fullName, DkmEvaluationResultFlags.None));
747+
}
748+
}
749+
750+
[Fact]
751+
public void UIntPtrPointer()
752+
{
753+
var source = @"
754+
using System;
755+
756+
unsafe class C
757+
{
758+
internal C(ulong p)
759+
{
760+
this.p = (UIntPtr*)p;
761+
}
762+
UIntPtr* p;
763+
UIntPtr* q;
764+
}";
765+
var assembly = GetUnsafeAssembly(source);
766+
unsafe
767+
{
768+
// NOTE: We're depending on endian-ness to put
769+
// the interesting bytes first when we run this
770+
// test as 32-bit.
771+
ulong i = 4;
772+
ulong p = (ulong)&i;
773+
var type = assembly.GetType("C");
774+
var rootExpr = string.Format("new C({0})", p);
775+
var value = CreateDkmClrValue(type.Instantiate(p));
776+
var evalResult = FormatResult(rootExpr, value);
777+
Verify(evalResult,
778+
EvalResult(rootExpr, "{C}", "C", rootExpr, DkmEvaluationResultFlags.Expandable));
779+
var children = GetChildren(evalResult);
780+
Verify(children,
781+
EvalResult("p", PointerToString(new UIntPtr(p)), "System.UIntPtr*", string.Format("({0}).p", rootExpr), DkmEvaluationResultFlags.Expandable),
782+
EvalResult("q", PointerToString(UIntPtr.Zero), "System.UIntPtr*", string.Format("({0}).q", rootExpr)));
783+
string fullName = string.Format("*({0}).p", rootExpr);
747784
children = GetChildren(children[0]);
748785
Verify(children,
749-
EvalResult("m_value", PointerToString(new IntPtr(i)), "void*", string.Format("({0}).m_value", fullName)),
750-
EvalResult("Static members", null, "", "System.IntPtr", DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class));
786+
EvalResult(fullName, UIntPtr.Size == 8 ? "0x0000000000000004" : "0x00000004", "System.UIntPtr", fullName, DkmEvaluationResultFlags.None));
751787
}
752788
}
753789

src/ExpressionEvaluator/Core/Source/ResultProvider/Expansion/MemberExpansion.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,18 @@ internal static Expansion CreateExpansion(
3232
// For members of type DynamicProperty (part of Dynamic View expansion), we want
3333
// to expand the underlying value (not the members of the DynamicProperty type).
3434
var type = value.Type;
35-
var isDynamicProperty = type.GetLmrType().IsDynamicProperty();
35+
var runtimeType = type.GetLmrType();
36+
var isDynamicProperty = runtimeType.IsDynamicProperty();
3637
if (isDynamicProperty)
3738
{
3839
Debug.Assert(!value.IsNull);
3940
value = value.GetFieldValue("value", inspectionContext);
4041
}
4142

42-
var runtimeType = type.GetLmrType();
43-
// Primitives, enums, function pointers, and null values with a declared type that is an interface have no visible members.
43+
// Primitives, enums, function pointers, IntPtr, UIntPtr and null values with a declared type that is an interface have no visible members.
4444
Debug.Assert(!runtimeType.IsInterface || value.IsNull);
45-
if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer())
45+
if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer() ||
46+
runtimeType.IsIntPtr() || runtimeType.IsUIntPtr())
4647
{
4748
return null;
4849
}

src/ExpressionEvaluator/Core/Source/ResultProvider/Formatter.Values.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ private string GetValueString(DkmClrValue value, DkmInspectionContext inspection
100100
? _nullString
101101
: GetValueString(nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
102102
}
103+
else if (lmrType.IsIntPtr())
104+
{
105+
if (IntPtr.Size == 8)
106+
{
107+
var intPtr = ((IntPtr)value.HostObjectValue).ToInt64();
108+
return FormatPrimitiveObject(intPtr, ObjectDisplayOptions.UseHexadecimalNumbers);
109+
}
110+
else
111+
{
112+
var intPtr = ((IntPtr)value.HostObjectValue).ToInt32();
113+
return FormatPrimitiveObject(intPtr, ObjectDisplayOptions.UseHexadecimalNumbers);
114+
}
115+
}
116+
else if (lmrType.IsUIntPtr())
117+
{
118+
if (UIntPtr.Size == 8)
119+
{
120+
var uIntPtr = ((UIntPtr)value.HostObjectValue).ToUInt64();
121+
return FormatPrimitiveObject(uIntPtr, ObjectDisplayOptions.UseHexadecimalNumbers);
122+
}
123+
else
124+
{
125+
var uIntPtr = ((UIntPtr)value.HostObjectValue).ToUInt32();
126+
return FormatPrimitiveObject(uIntPtr, ObjectDisplayOptions.UseHexadecimalNumbers);
127+
}
128+
}
103129
else
104130
{
105131
int cardinality;

src/ExpressionEvaluator/Core/Source/ResultProvider/Helpers/TypeHelpers.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ internal static bool IsIEnumerable(this Type type)
272272
return type.IsMscorlibType("System.Collections", "IEnumerable");
273273
}
274274

275+
internal static bool IsIntPtr(this Type type)
276+
=> type.IsMscorlibType("System", "IntPtr");
277+
278+
internal static bool IsUIntPtr(this Type type)
279+
=> type.IsMscorlibType("System", "UIntPtr");
280+
275281
internal static bool IsIEnumerableOfT(this Type type)
276282
{
277283
return type.IsMscorlibType("System.Collections.Generic", "IEnumerable`1");

src/ExpressionEvaluator/VisualBasic/Test/ResultProvider/ExpansionTests.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ End Class"
130130
EvalResult("q", PointerToString(IntPtr.Zero), "Integer*", String.Format("({0}).q", rootExpr)))
131131
Dim fullName = String.Format("*({0}).p", rootExpr)
132132
Verify(GetChildren(children(0)),
133-
EvalResult(fullName, "4", "Integer", fullName))
133+
EvalResult(fullName, "4", "Integer", fullName, DkmEvaluationResultFlags.None))
134134
End Sub
135135

136136
<Fact>

0 commit comments

Comments
 (0)