2016-08-02 4 views
4

MDBG 샘플을 사용하여 관리되는 .NET 디버거를 만들고 있습니다.ICorDebugEval을 사용하는 일반 유형 func-eval

MDBG는 속성 게터 평가를 지원하지 않으므로 추가하려고합니다. 클래스 구조 다음 사항을 고려하십시오 : 시간의 어느 시점에서

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

    public class A : Base<int>{ 

    } 

을 I가의 인스턴스를 생성하고 그 상태를 평가하기 위해 중단 점에서 중지하고 있습니다.

내 디버거의 감시 윈도우에서이 객체에 대해 get_SomeProp 메서드의 func-eval을 수행하고 주어진 경우에 null 값을 반환해야하는 "this.SomeProp"을 소개합니다.

첫 번째 문제는 get_SomeProp이 기본 클래스에 정의되어 있으므로 함수를 찾기 위해 클래스 계층 구조의 모든 TypeDefs/TypeRefs/TypeSpec을 실행해야한다는 사실이었습니다. TypeLoadException이 : 일반 유형 어셈블리 제네릭 인수의 잘못된 번호로 사용

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

이 결과 호출

그러나이 발견 된 후

.

제네릭 클래스 (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; 
    } 

어떤 제안이/조언이 크게 감사합니다 : 여기

내가 현재 사용하고 일부 코드입니다!

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; 
    } 

감사합니다, @ 브라이언 REICHLE 뛰어난 대답


솔루션

덕분에 나는이 솔루션을 함께했다

답변

2

A의 인스턴스를 나타내는 값 개체에 ICorDebugValue2::GetExactType을 사용하여 A, ICorDebugType::GetBase()의 ICorDebugType을 가져 와서 기본 형식 (Base<int>) 및 ICorDebugType::EnumerateTypeParameters을 형식 인수로 가져올 수 있습니다.

+0

다시 한번 Brian, 나를 도와 주셔서 감사합니다! 아쉽게도 GetExactType을 사용하면 닫힌 형식 A가 반환되고 EnumerateTypeParameters는 0 매개 변수를 반환합니다.이 형식에는 일반 매개 변수가 없기 때문입니다. 나는베이스 을 어떻게 든 EnumerateTypeParams를 사용해야 만한다고 생각합니다.그 유형을 얻기 위해 상속 계층 구조를 내려야합니까, 아니면 뭔가 빠졌는가? – 3615

+0

죄송합니다, GetBase()에 대한 전화를 잊어 버렸습니다 : –

+0

Thanks! 나는 이미 GetBase를 사용해 보았고,이 질문에 대한 간단한 시나리오를 위해 노력했다. 현재 A : B 을 사용하는보다 복잡한 시나리오를 시도하고 있으며 B : C 입니다. 이 경우 B 으로 이동하여 일반 매개 변수를 가져옵니다. 그러나이 경우의 평가 결과는 ** TargetParameterCountException **입니다 : 지정된 매개 변수의 수가 예상 수치와 일치하지 않습니다. – 3615