How do I get the executing object for a stackframe?

只愿长相守 提交于 2019-11-30 12:58:41
Yona

I'm pretty sure that this is not possible. Here's why:

  1. This could break type safety, since anyone can lookup a frame, get the object regardless of which AppDomain\Thread they are executing on or permission they have.

  2. The 'this' (C#) identifier is really just an argument to the instance method (the first), so in reality there is no difference between static methods and instance methods, the compiler does its magic to pass the right this to an instance method, which of course means that you will need to have access to all method arguments to get the this object. (which StackFrame does not support)

It might be possible by using unsafe code to get the pointer of the first argument to an instance method and then casting it to the right type, but I have no knowledge of how to do that, just an idea.

BTW you can imagine instance methods after being compiled to be like C# 3.0 extension methods, they get the this pointer as their first argument.

SnarkOrBoojum

It's possible to obtain reference to thiscall object, but not with .NET code only. Native code must be involved. Even with using dynamic classes and System.Relection.Emit namespace .NET does not have instruments to access another methods evaluation stack and arguments.

On other side if you disassemble your .NET method you can see that this reference does not passed on physical stack at all. Thiscall reference is stored in ECX(RCX for x64) register instead. So it is possible climb up on stack from your method to method from which you want to obtain thiscall object. And then lookup inside that method's machine codes for instruction which save register ECX (RCX) in stack, and get from that instruction relative address where that reference lies.

Of course, the method of climbing is severely different in x32 and x64 application. To produce such function you must use not only C# but assembly code, and keep in mind that inline assembler is not allowed under x64; it must be a full assembler module.

I am not sure that I fully understand what you want, but if you want to know the type in which the method for a certain stack frame is declared, I think this code returns that:

StackTrace trace = new StackTrace();    
Type methodOwner = trace.GetFrame(0).GetMethod().DeclaringType;

You will of course need to pass the index for the frame that you are interested in (I use 0 as example).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!