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

Fix function pointer representation

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