Ask a questionAsk a question
 

AnswerInstrumentation problem

  • Tuesday, October 27, 2009 1:08 PMGiantBrain Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Using .NET profiling, we've discovered that methods can be added to a class during the ModuleAttachedToAssembly callback, but not during the ClassLoadStarted callback. If we try to add a new method during ClassLoadStarted, then references to that method in instrumented code result in Missing Method exceptions from the JIT compiler.

    However, other threads may cause ClassLoadStarted events to be delivered even before we have finished instrumenting a module that contains the class being loaded. This seems to result in a race condition in which the class has been partially instrumented in one thread, but JIT compilation occurs in another thread before the instrumentation is complete.

    Is our observation correct, and if so, is the inability to instrument during ClassLoadStarted a bug? I know that in Java instrumentation, we can instrument a class when we receive a notification from the class loader, so we don't have to instrument unnecessary classes.

    Thanks,

    Bob Meagher

Answers

All Replies

  • Thursday, October 29, 2009 11:21 PMDavid BromanMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hi, Bob.

    The best place to add a new method is during ModuleLoadFinished.  Take a look at this:

    http://blogs.msdn.com/davbr/archive/2007/03/06/creating-an-il-rewriting-profiler.aspx

    and some of the forum entries it references for more information.  Classes should not load from a module until after you have returned from ModuleLoadFinished.  However, there is a bug in the CLR (fixed for CLR V4) where occasionally this invariant is broken in some multithreaded scenarios.
  • Monday, November 02, 2009 1:32 PMGiantBrain Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi David, thanks for your reply and explanation.

    One thing for the profiling team to consider is that, if ClassLoadStarted is only invoked when a class is to be loaded and one or more of its methods JITted, it would be better (from a performance and resource allocation point of view) to allow IL rewriting to occur at this event. Then only classes that had any chance of their code being executed would be instrumented. In our case, instrumentation involves generation of wrapper methods, which leads us to define a new method for each method to be instrumented.

    Currently, we have no clue which classes and methods to instrument at ModuleLoadFinished time, so we are forced to instrument all of them (or at least what we hope is an interesting subset). If our instrumentation were only a matter of rewriting IL in place, then we wouldn't have a problem, I think. I found out the hard way that methods defined later than the ModuleLoadFinished event (e.g. ClassLoadStarted) are ignored by the JIT compiler, leading to missing method exceptions.

    By the way, the Java profilers (JVMPI and JVMTI) freely permit the modification of classes during an event known as ClassLoadHook.

    Thanks,

    Bob
  • Monday, November 02, 2009 7:40 PMDavid BromanMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi, Bob, thanks for the suggestion.  I agree that it is rather unfortunate that, in order to add new methods, the profiler must do so at ModuleLoadFinished time, and not later than that.  Lifting this restriction is indeed something I'd like us to consider for a future version, though I can't say yet when or if this will actually happen.  In the meantime, is there a way for you not to use wrapper methods, but instead to directly modify the IL as it gets JITted?  For example, you could add some custom IL at the beginning and end of the original IL to simulate what would have happened if you wrote a wrapper method which called the original method (with potentially custom code before and after the call).

    Thanks,
    Dave