I'm making a managed .NET debugger using MDBG sample.
MDBG sample operates only on top level class of given instance, not searching deep inside class hierarchy. I was able to go through hierarchy and get all available methods. But a problem occurs in such case:
public abstract class Base{
public Base() {SomeProp = "Base"}
public string SomeProp {get;set;}
}
public class A : Base{
public Base() {SomeProp = "A"}
public new string SomeProp {get;set;}
}
public static void Main(){
var a = new A();
var castedToBase = (Base)a;
//castedToBase.SomeProp -- expect result to be "Base" when debugging
}
The problem is when I'm getting castedToBase as ICorDebugValue and query for it's ICorDebugValue2::GetExactType I get A class instead of Base class. At that point I cannot distinguish any more which method get_SomeProp to invoke. I would expect ICorDebugValue2::GetExactType to take in consideration performed casts and not return always the underlying type.
How can I understand which method I should invoke?
Some code of what I'm doing now is listed below. mdbgValue represents castedToBase object. szTypedef returns "A" instead of expected "Base"
IMetadataImport importer;
var classToken = mdbgValue.CorValue.ExactType.Class.Token;
int size;
int ptkExtends;
TypeAttributes pdwTypeDefFlags;
importer.GetTypeDefProps(classToken,
null,
0,
out size,
out pdwTypeDefFlags,
out ptkExtends
);
StringBuilder szTypedef = new StringBuilder(size);
importer.GetTypeDefProps(classToken,
szTypedef,
szTypedef.Capacity,
out size,
out pdwTypeDefFlags,
out ptkExtends
);
Casting an object to it's base class doesn't change the type of the object, only how it is perceived. I would suggest you need to pass the "perceived" type around along with the value, and use that instead of the actual type for the purpose of finding the correct method.
The "perceived" type is the statically determined type based on where you got the value from.
ICorDebugILFrame::GetArgument()
, then extract the corresponding argument type from the method signature.
HasThis
flag but not the ExplicitThis
flag then get the type from the value instead.ICorDebugILFrame::GetLocalVariable()
then extract the type from the methods locals signature (the metadata token of the locals signature needs to be extracted from the method header.)ICorDebugEval
(eg. a property getter), then you should use the return type of the method you called (also extracted from the method signature.)