I am working with a bunch of really smart folks who have a ton of experience with profiling and diagnostics who have just open sourced CLR Instrumentation Engine (CLRIE).
“What is instrumentation?” I hear you cry. This is a more instructive and frankly invasive alternative to log debugging. The term commonly used is IL instrumentation, here is how it is described by my team:-
“IL instrumentation is a fundamental technique used by diagnostic tools for monitoring applications or extracting information out of a process. This allows a diagnostic tool the opportunity to modify or replace the IL form of a method before it is JIT compiled and executed.”
Lets do a quick reminder of the terms IL and JIT before I continue…
IL (Intermediate Language) - All .NET compilers generate Intermediate Language (IL) no matter what the underlying language used to develop the application. The CLR actually has no idea about the language used to develop a given application. All .NET compilers will generate a standard, common language we refer to as IL (aka, MSIL and CIL).
JIT (Just in Time) - Before Intermediate Language (IL) can be executed, it must converted by the .NET Framework's JIT compiler to native code, which is CPU specific code that run on some computer architecture as the JIT compiler. Rather than using time and memory to convert all the MSIL in portable executable (PE) file to native code, it converts the MSIL as it is needed during execution and stored in resulting native code so it is accessible for subsequent calls.
So how does this all work? There are several deep diagnostic profilers on the market and they all currently use the ICorProfiler to communicate with the common language runtime (CLR) in order to request additional information and control event monitoring. The CLR calls the methods in the interface to notify the profiler of events in the monitored process. The simplest example would be adding code to measure the time taken to enter and exit each method, or to count the number of times a method is actually executed. This kind of information might be quite useful when trying to assess the health of your application.
JIT compilation at run time provides the perfect opportunity for profiling, the ICoreProfiler API enables a profiler to change the in-memory IL code stream for a routine before it is JIT-compiled. The API can retrieve information about the following actions and events that occur in the CLR:-
- CLR startup and shutdown events
- Application domain creation and shutdown events.
- Assembly loading and unloading events
- Just-in-time (JIT) compilation and code-pitching events
- Class loading and unloading events
- Thread creation and destruction events
- Get notified on function entry and exit events.
- Information about the runtime memory heap and garbage collection activity
- Manipulate optimizations applied to be applied during the JIT compilation
More recently (as in .NET 4) the CLR allows a user to request a new JIT compilation by using “reJIT”, this provides additional opportunities to manipulate the IL. For example if an end user needs to modify the level instrumentation, you could request a reJIT and say add more logs at the start and end of methods.
Why the CLR Instrumentation Engine?
The CLR Instrumentation Engine is a cooperation profiler that allows multiple profiling extensions to coexist within the same process. It was originally created to ensure that both Application Insights and Snapshot Debugger could cooperate in tandem by acting as a host, and inverse multiplexes the APIs so multiple profiler clients can run in the same process. This has the added benefit of allowing competing profilers to instrument the same process which permits customer to truly select all the best in class profiling based on their specific needs.
How does a process load the CLR Instrumentation Engine? Well, when a managed process starts execution it first loads the CLR, and once loaded it checks environment variables to see if a Profiler should also be loaded.
This is definitely worth a read even if you do not plan to use it directly, the diagnostics team has even provided a simple example of an InstrumentationMethod for the more adventurous among us.