Prevent JIT implementation by method

I have a unique situation. I am working on an open source library for sending emails. In this library, I need a reliable way to get the invocation method. I did this using StackTrace by parsing the StackFrame objects inside it. This works without problems in a debug-mode project where optimization is disabled.

The problem arises when I switch to release mode in which optimizations are enabled. The stack trace looks like this:

 > FindActionName at offset 66 in file:line:column <filename unknown>:0:0 > Email at offset 296 in file:line:column <filename unknown>:0:0 > CallingEmailFromRealControllerShouldFindMailersActionName at offset 184 in file:line:column <filename unknown>:0:0 > _InvokeMethodFast at offset 0 in file:line:column <filename unknown>:0:0 > InvokeMethodFast at offset 152 in file:line:column <filename unknown>:0:0 ... 

This is taken from unit test failure. On line 3 of this trace, I should see a method called TestEmail , which is defined elsewhere, but I believe the JITter inserts it. I read that you can prevent inlining by making the method virtual, but that will not work. Does anyone know of a reliable method to prevent the implementation of a method so that your method is detected in the stack trace?

+22
c # inlining jit
Mar 02 2018-11-11T00:
source share
2 answers

You can use MethodImplAttribute and specify MethodImplOptions.NoInlining .

 [MethodImpl(MethodImplOptions.NoInlining)] void YourMethod() { // do something } 

Note that this still does not guarantee that you can get the actual invocation method, as shown in the source code. Your method will not be inline, but your calling method can be embedded in its own caller, etc. Etc.

+28
Mar 02 2018-11-11T00:
source share

You can use additional parameters marked with System.Runtime.CompilerServices.CallerMemberNameAttribute , and these are siblings CallerFilePath and CallerLineNumber . If I understand it correctly, this should lead to the correct method name, regardless of what lies in what is not specified. You will only get the method name, but I do not see anything to get the class name / assembly, etc.

This should be taken for granted, but just to be sure ... something like this should not be used outside of the protocols / diagnostics.

The correct ways to do this are likely to be as follows:

  • Pass the required information as a parameter
  • Temporarily save the required information in Thread.ExecutionContext when calling the function

I understand that this probably will not help Scott all this time, but perhaps it will help someone.

+4
Jan 11 '13 at 15:19
source share



All Articles