提交 1882b7f3 编写于 作者: C Charles Stoner

Fix function pointer representation

上级 4c98b4b9
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
using Microsoft.CodeAnalysis.ExpressionEvaluator; using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Clr; using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation; using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Microsoft.VisualStudio.Debugger.Metadata;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Xunit; using Xunit;
...@@ -12,40 +14,71 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests ...@@ -12,40 +14,71 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{ {
public class FunctionPointerTests : CSharpResultProviderTestBase public class FunctionPointerTests : CSharpResultProviderTestBase
{ {
[Fact(Skip = "Tests are failing in Jenkins queues")] [Fact]
public void Root() public void Root()
{ {
const int ptr = 0x1234; var source =
var value = CreateDkmClrValue(ptr, type: new DkmClrType(FunctionPointerType.Instance)); @"unsafe class C
var evalResult = FormatResult("pfn", value); {
Verify(evalResult, internal C(long p)
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "System.Object*", "pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other)); {
this.pfn = (int*)p;
}
int* pfn;
}";
var assembly = GetUnsafeAssembly(source);
unsafe
{
int i = 0x1234;
long ptr = (long)&i;
var type = assembly.GetType("C");
var value = GetFunctionPointerField(CreateDkmClrValue(type.Instantiate(ptr)), "pfn");
var evalResult = FormatResult("pfn", value);
Verify(evalResult,
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "System.Object*", "pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other));
}
} }
[Fact(Skip = "Tests are failing in Jenkins queues")] [Fact]
public void Member() public void Member()
{ {
var source = var source =
@"class C @"unsafe class C
{ {
object pfn; internal C(long p)
{
this.pfn = (int*)p;
}
int* pfn;
}"; }";
const int ptr = 0x0; var assembly = GetUnsafeAssembly(source);
GetMemberValueDelegate getMemberValue = (v, m) => (m == "pfn") ? CreateDkmClrValue(ptr, type: new DkmClrType(FunctionPointerType.Instance)) : null; unsafe
var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(GetAssembly(source)), getMemberValue: getMemberValue);
using (runtime.Load())
{ {
var type = runtime.GetType("C"); const long ptr = 0x0;
var value = CreateDkmClrValue(type.Instantiate(), type: type); GetMemberValueDelegate getMemberValue = (v, m) => (m == "pfn") ? GetFunctionPointerField(v, m) : null;
var evalResult = FormatResult("o", value); var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(assembly), getMemberValue: getMemberValue);
Verify(evalResult, using (runtime.Load())
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Other)); {
var children = GetChildren(evalResult); var type = runtime.GetType("C");
Verify(children, var value = CreateDkmClrValue(type.Instantiate(ptr), type);
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "object {System.Object*}", "o.pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other)); var evalResult = FormatResult("o", value);
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Other));
var children = GetChildren(evalResult);
Verify(children,
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "int*", "o.pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other));
}
} }
} }
private DkmClrValue GetFunctionPointerField(DkmClrValue value, string fieldName)
{
var valueType = value.Type.GetLmrType();
var fieldInfo = valueType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var fieldValue = fieldInfo.GetValue(value.RawValue);
return CreateDkmClrValue(DkmClrValue.UnboxPointer(fieldValue), new DkmClrType(FunctionPointerType.Instance));
}
// Function pointer type has IsPointer == true and GetElementType() == null. // Function pointer type has IsPointer == true and GetElementType() == null.
private sealed class FunctionPointerType : TypeImpl private sealed class FunctionPointerType : TypeImpl
{ {
......
...@@ -501,17 +501,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -501,17 +501,7 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
Type type; Type type;
if (value is System.Reflection.Pointer) if (value is System.Reflection.Pointer)
{ {
unsafe value = UnboxPointer(value);
{
if (Environment.Is64BitProcess)
{
value = (long)System.Reflection.Pointer.Unbox(value);
}
else
{
value = (int)System.Reflection.Pointer.Unbox(value);
}
}
type = declaredType; type = declaredType;
} }
else if (value == null || declaredType.IsNullable()) else if (value == null || declaredType.IsNullable())
...@@ -535,6 +525,21 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare ...@@ -535,6 +525,21 @@ public DkmClrValue GetMemberValue(string MemberName, int MemberType, string Pare
access: access); access: access);
} }
internal static unsafe object UnboxPointer(object value)
{
unsafe
{
if (Environment.Is64BitProcess)
{
return (long)System.Reflection.Pointer.Unbox(value);
}
else
{
return (int)System.Reflection.Pointer.Unbox(value);
}
}
}
public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext) public DkmClrValue GetArrayElement(int[] indices, DkmInspectionContext inspectionContext)
{ {
if (inspectionContext == null) if (inspectionContext == null)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册