4

我正在使用 MDBG 示例制作托管的 .NET 调试器。

MDBG 不支持我正在尝试添加的属性获取器评估。请考虑以下类结构:

    public abstract class Base<T>{
        public string SomeProp {get;set;}
    }

    public class A : Base<int>{

    }

在某个时间点,我正在创建 A 的一个实例并在断点处停止以评估它的状态。

在我的调试器的监视窗口中,我介绍了“this.SomeProp”,它应该在这个对象上执行 get_SomeProp 方法的 func-eval 并为给定的情况返回一个空值。

我遇到的第一个问题是 get_SomeProp 是在基类上定义的,因此我必须遍历类层次结构中的所有 TypeDefs/TypeRefs/TypeSpecs 才能找到该函数。

但是找到之后,打电话

   ICorDebugEval.CallFunction(function.CorFunction, new[] {@object.CorValue});

导致:TypeLoadException: 泛型类型在程序集中使用了错误数量的泛型参数

正如我所意识到的那样,因为非泛型函数是在泛型类(Base)中定义的,所以当我评估它时,我还应该指出类的泛型参数。

这可以使用

  ICorDebugEval2.CallParameterizedFunction(function.CorFunction,
    genericArguments,
    functionArguments);

问题是我不知道如何提取类泛型参数的类型,只有我想要评估的函数和我想要评估它的实例。

这是我目前正在使用的一些代码:

    private MDbgValue EvaluatePropertyGetter(MDbgFrame scope, MDbgValue @object, string propertyName) {
        var propertyGetter = $"get_{propertyName}";
        var function = ResolveFunctionName(
            scope.Function.Module.CorModule.Name,
            @object.TypeName,
            propertyGetter,
            scope.Thread.CorThread.AppDomain);

        if (function == null) {
            throw new MDbgValueException("Function '" + propertyGetter + "' not found.");
        }

        var eval = Threads.Active.CorThread.CreateEval();
        var typeToken = function.CorFunction.Class.Token;
        var type = function.Module.Importer.GetType(typeToken); //checked that type containing function is generic
        if (type.IsGenericType) {
            //------------->need to get class'es generic param types<------------
            var genericType1 = this.ResolveType("System.Object"); // just a stub
            eval.CallParameterizedFunction(function.CorFunction, new CorType[] {genericType1}, new[] {@object.CorValue});
        }
        else {
            eval.CallFunction(function.CorFunction, new[] {@object.CorValue});
        }

        Go().WaitOne();
        if (!(StopReason is EvalCompleteStopReason)) {
            // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason
            Console.WriteLine("Func-eval not fully completed and debuggee has stopped");
            Console.WriteLine("Result of funceval won't be printed when finished.");
        }
        else {
            eval = (StopReason as EvalCompleteStopReason).Eval;
            Debug.Assert(eval != null);

            var cv = eval.Result;
            if (cv != null) {
                var mv = new MDbgValue(this, cv);
                return mv;
            }
        }
        return null;
    }

非常感谢任何建议/建议!

问候,


解决方案

感谢@Brian Reichle 出色的回答,我想出了这个解决方案:

 if (type.IsGenericType) {
            //getting Type's Generic parameters
            var typeParams = GetGenericArgs(@object.CorValue.ExactType, function.CorFunction.Class.Token);
            eval.CallParameterizedFunction(function.CorFunction, typeParams.ToArray(), new[] {@object.CorValue});
        }

以及函数本身:

 private List<CorType> GetGenericArgs(CorType corType, int classTk) {
        if (corType == null)
            return null;
        List<CorType> list = new List<CorType>();

        var param =corType.TypeParameters;
        var args = GetGenericArgs(corType.Base, classTk);

        if (classTk == corType.Class.Token) {
            list.AddRange(param.Cast<CorType>());
        }

        if (args != null) {
            list.AddRange(args);}

        return list;
    }
4

1 回答 1

2

您可以在表示的实例的值对象上使用ICorDebugValue2::GetExactTypeA来获取 type 的 ICorDebugType A,使用ICorDebugType::GetBase()来获取其基类 ( Base<int>),并在基类型上使用ICorDebugType::EnumerateTypeParameters来获取它的类型参数。

于 2016-08-02T22:03:39.257 回答