Question

A method could get inlined; there is an attribute to prevent that ("there's an att for that"). However, apparently a method may also not get its own stack frame on x64 due to tail-call optimization by the JITter (http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx). Would this affect the behavior of MethodBase.GetCurrentMethod?

The discussions that I can find are mostly about inlining (When is a method eligible to be inlined by the CLR?). While those discussions are interesting in their own right, my problem is really about under what circumstances -- if any -- that MethodBase.GetCurrentMethod can be relied upon to identify the same method where the programmer placed the call (e.g., for late binding to a method for which the current method is really a surrogate). Inlining is a way that MethodBase.GetCurrentMethod could be fooled, but I wonder if it is the only way?

Was it helpful?

Solution

No - a method is either inlined at run time or it isn't.

It can be fooled, I believe, if somebody were to implement their own runtime - as MethodBase.GetCurrentMethod ultimately boils down to this, declared in RuntimeMethodHandle:

[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern IRuntimeMethodInfo 
  _GetCurrentMethod(ref StackCrawlMark stackMark);

In a custom runtime, that could do anything - and in the future it could also do anything too. At the moment, I believe the only way that the Microsoft runtime(s) will not return the correct method is if the code is inlined; can't speak for Mono, for example. Relying on that always to be the case, however, is like relying on a reflected private field of an internal type always to be present to enable a piece of code to work, I think.

In nearly every case where I have tried (I no longer worry about it now) or someone tries to justify needing to be able to reliably identify the calling method, outside of profiling, the issue of inlined methods always comes up.

The reality is, though, how important is it to worry about those methods?

If reliability is absolutely crucial, you will get more luck Using an IL-rewriter post compilation to inject the logging calls; this can be necessarily method-aware and therefore can subvert the inlining, even if it takes place (which it might not if the rewritten IL becomes bulky enough, thus hurting performance). Or if you don't fancy rolling your own, an AOP library might be in order - such as PostSharp.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top