ProfilerLib


Before we get into the guts of the ExceptionMon profiler, I want to spend a little time talking about ProfilerLib. As you can probably guess from the discussions about the COM Profiling API so far, there's a lot of boilerplate code. Since I'm not really into typing the same thing over and over when I develop software, I quickly realized that I needed a library to do the grunt work, especially given the large number of methods supported by the ICorProfilerCallback interface.

The two sample profilers that come with the Visual Studio .NET also take the tack of reusing all the COM goo code, but the way their code is written is a little ugly in that it mixes all the infrastructure stuff in with some helper data structures. I was working on fixing this when Matt Pietrek's December 2001 "Under the Hood" column came out in MSDN Magazine. Matt had taken the profiler sample code and cleaned out some of the messy stuff. I figured that was a good starting point, so I took Matt's code and spiffed it up even more, making the writing of a profiler even simpler.

Setting up to use ProfilerLib is quite easy. The first step is to create a DLL project and set it up to link against ProfilerLib.LIB, and in your project's STDAFX.H, include ProfileLib.H. In one of your CPP files, define the following variables and assign their values to the particular values necessary for your profiler:

//The profiler GUID string wchar_t * G_szProfilerGUID  // The profiler CLSID GUID G_CLSID_PROFILER  // The profiler ProgID prefix wchar_t * G_szProgIDPrefix // The profiler name wchar_t * G_szProfilerName     // As an example, here's the values specified for ExceptionMon wchar_t * G_szProfilerGUID =                           L"{F6F3B5B7-4EEC-48f6-82F3-A9CA97311A1D}" ;     GUID G_CLSID_PROFILER =     { 0xf6f3b5b7 , 0x4eec , 0x48f6 ,     { 0x82 , 0xf3 , 0xa9 , 0xca , 0x97 , 0x31 , 0x1a , 0x1d } } ;     wchar_t * G_szProgIDPrefix = L"ExceptionMonProfiler" ;     wchar_t * G_szProfilerName = L"ExceptionMon" ;

After declaring the unique COM goo values, add a DllMain to your CPP file, like the following:

    HINSTANCE G_hInst = NULL ;     extern "C" BOOL WINAPI DllMain ( HINSTANCE hInstance ,                                      DWORD     dwReason  ,                                      LPVOID               )     {         switch ( dwReason )         {             case DLL_PROCESS_ATTACH:                 DisableThreadLibraryCalls ( hInstance ) ;                 G_hInst = hInstance ;                 break ;             default :                 break ;         }         return( TRUE ) ;     } 

ProfilerLib has a base class in it, CBaseProfilerCallback, that implements all the methods necessary for the ICorProfilerCallback interface. You'll derive your particular profiler callback class from CBaseProfilerCallback and override the particular methods you're interested in receiving notifications for. That way you can concentrate on the important parts that you need, not the rest of the methods that will just get in the way.

After you've named your derived class, you'll need to implement a function, AllocateProfilerCallback, with the following prototype. In that function, allocate your CBaseProfilerCallback-derived class and return it. The rest of the code in ProfilerLib.h will take care of everything else.

ICorProfilerCallback * AllocateProfilerCallback ( ) ;

Finally, you'll need to take the EXAMPLE.DEF file out of ProfilerLib, copy it to your project, rename it, and replace the LIBRARY statement in it to properly do all the exports necessary to make a COM DLL.

In addition to taking care of all the COM goo for you, ProfilerLib also adds additional methods to CBaseProfilerCallback that will make your life easier. Some of them I've already mentioned in this chapter, but there are others. Whenever I run across anything that I think I might want to reuse, I add it to ProfilerLib, so make sure you check out the project files to see what other time-saving routines are already written for you.

As you'd expect by now from my code, there's a sample program, DoNothing, in the Tests directory under the ProfilerLib directory. It's the simplest profiler you can make and shows you exactly how to use ProfilerLib. It does process all notifications, but it simply beeps when initializing and unloading. That's my patented "Debug-by-Ear" method of development. Additionally, all the other utilities I wrote that utilize the Profiling API use ProfilerLib as their base classes, so you can see more advanced usage. ProfilerLib has saved me a ton of time, and I hope it will save you a great deal of time as well.




Debugging Applications for Microsoft. NET and Microsoft Windows
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2003
Pages: 177
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net