Chapter 10: Managed Exception Monitoring Testing Seminar 05 March 2004.
The Dilemma Win32 and COM programming benefits came with support costs. Limited ability to peek inside a process to investigate runtime problems. Crashes, hangs, heap corruption. Memory leaks, mismatched reference counts. Build your own instrumentation. Detours technology, many, many printf calls, custom crash handlers.
The Remedy MS .NET CLR profiling interface. Create one COM object to profile and .NET managed application. CLR provides dozens of built in metrics about runtime behavior.
Agenda Introduction to Profiling. Details about the profiling interface. Inside a profiling object. Details of profiling managed code. PROFILELIB & EXCEPTIONMON The FOUR checks.
Introduction to Profiling. The idea of watching someone’s moves. Types of Profiling Sampling. The profiler peeks at the profilee at a specific time interval and checks what’s running. Non-Sampling. The profiler monitors every call of the profilee and returns synchronously so that it can track everything that occurs in the profilee.
What all can be profiled? Runtime AppDomain Assembly Module Class Function Thread Remoting Transitions Runtime suspension Garbage Collection Exception.
The Profiling Interface
Development problem ! WHY????? Though we have profiling API defined….we cannot write profilers in Managed Code WHY?????
Answer The profiler runs in the address space of the managed application that is being profiled. Using managed code to profile managed code would lead into dirty problems.
Answer (cont’d) Example: If we were notified of the Garbage Collector being called, and we need to allocate managed memory to store the items being collected, you would end up a triggering a recursive call to the garbage collector.
BUT THIS WOULD SLOW DOWN THE PROFILEE An alternative (phew) To support managed profilers, all the notifications would have to occur cross process. BUT THIS WOULD SLOW DOWN THE PROFILEE
Most of the profilers are A Secret Most of the profilers are COM DLL’s !
It’s COM…so where is the CATCH? The profiler COM code is called in a completely free threaded model. So, all the work needed to protect data structures from multi-threaded corruption needs to be taken care of.
ICorProfilerCallback 2 methods sure to be called … ALWAYS Initialize The first method to be called. Shutdown The last method to be called.
Initialize method Functionality Communication is via ID’s. Use the QueryInterface of the IUnknown interface and query for ICorProfileInfo. Interface. Stores the returned interface to request info about the profilee. Communication is via ID’s. Appropriate functions are present that take in the ID and give out the method details.
Example ICorProfileCallback :: ModuleLoadFinished(ModuleID) ICorProfileCallback :: GetModuleInfo(ModuleID) Gives module name, load address and assembly ID.
What does the initialize do? Inform to the CLR the notifications that we are interested in. to minimize resource usage. Done using ::SetEventMask(…) Some modifications need to be set via the Initialize method itself. Non immutable ones can be toggled during run time.
Shutdown method For managed applications SHUTDOWN is always called. For application starts running as a native application, it loads the CLR (eg. VS.NET IDE), the shut down method will never be called. => the profiler WILL NOT STOP.
The Execute method (cont’d) Only way is to process the DLL_PROCESS_DETACH in the DllMain() and check whether the shutdown has been called. If not called, the clean up is manually done (via code).
Passing of ID’s
Getting the profiler started. Set up environment variables: Cor_Enable_Profiling Tells the CLR that it needs to turn on profiling. COR_PROFILER Set the CLSID or the ProgID of the profiler.
BUT WHAT ABT ASP.NET applications? Application Range Setting up of environment variables is good for Windows Forms and ConsoleApplications. BUT WHAT ABT ASP.NET applications?
Profiling for ASP.NET applications ASPNET_WP.EXE / W3WP.EXE Set up the system environment variables. Restart IIS after running this.
The BAD part All process that load the CLR will automatically be profiled. It’s ok for a few processes, but trouble comes when more processes are loaded ….eventually clogging resources.
The way around it…. Pass the Environment variables to check such that: The environment variable is not set, which assumes that you want to profile all the processes. The value of the environment variable matches the current process drive path and name completely. It matches just the file name of the current process.
PROFILELIB
EXCEPTIONMON To be started after PROFILELIB is up and running. STDMETHOD (ExceptionThrown) (ObjectID thrownObjID) STDMETHOD (ExceptionUnwindFinallyEnter) (FunctionID fID) STDMETHOD (ExceptionCatchEnter) (FunctionID fID, ObjectID oID)
EXCEPTIONMON To start the EXCEPTIONMON along with the profilee, use EXPMONBREAK in the environment variables. EXPMONFLUSH : flushes all the writes immediately. EXPMONFILENAME : output file for EXPMONFLUSH writes.
BAD PROGRAMMING Exception Handling IS NOT TO BE USED INSTEAD OF switch-case. Basic reason for using exception blocks: Developers don’t check for method return values. (FIRE THEM)
The FINAL FOUR Rules FINALLY blocks are not HANDLES to base resources. Catch{…} are actually doing a throw. Rethrows should never happen. Else information of the origin of the exception is lost. In C#.NET, “using” expands into the same IL code as try…finally block and calls Dispose method.