##################################################################################

##

##                Overview of the Microsoft NGWS General Code

##                      Profiler Sample (ProfilerGCP)

##

##################################################################################

 

The sample code profiler is collecting information about appdomains, assemblies, modules, classes, functions and function enter-leave events during the execution of a managed program. Specifically,

In more detail:

 

q       Appdomain information: It is a collection of basic information about an appdomain. We are monitoring the appdomainID, the process ID that the current appdomain belongs to, and its name.

q       Assembly information: For each assembly we monitor its id. Additionally, we will maintain the id of the appdomain that loaded the current assembly and the module the assembly is associated with.

q       Module information: The structure for the module will contain the module id, the module name and the module’s base address. Additionally a metadata interface is stored that will allows to get information about the module and the methods and classes that includes.

q       Class information: The information for each class includes the class name and id, and the metadata token for that class. We can use this token with the metadata interface of the module that the class belongs to, in order to retrieve additional metadata information.

q       Thread information: For every thread we monitor its id and the win32 thread that the managed thread is associated with. We also mark it as deleted if it goes away during the program’s execution and we are monitoring whether it is running managed or unmanaged code.

q       Function information: For every function that gets JIT-ed or that is found PREJIT-ed, we are collecting information regarding the module and class it belongs to, the IL code size, its function token and name. Also the sample stores the number of times that the function has been invoked (Enter / Leave / TailCall events). We also collect a function as pitched in light of code pitching events.

 

We are not monitoring context events, garbage collection events, remoting events, runtime suspension events, classic COM wrappers. For the exception events we are only interested in the unwind callbacks since they provide additional information to the enter-leave function events. Specifically, during the unwind phase of an exception, the code profiler will receive exception unwind events instead of function leave events. As far as the context events are concerned, we are only tracking whether an active thread runs managed or unmanaged code. We are not keeping a shadow call stack trace although the tool should be easy to expand in order to include that functionality as well.

 

The information about an appdomain, assembly, module, class, thread or function is available when the loading or JIT-ting has been completed. In other words, we can extract accurate information regarding the above-mentioned items AFTER the loading has been completed and BEFORE the unloading is completed. Every data structure used has a field that indicates whether the specific element is valid or not. We recommend before accessing or using any information in the data structures to assert the specific element is still valid.

   

We strongly recommend to carefully review all the ReadMe items before attempting any changes to the tool since the profiler API has by default very loose error checks in order to improve the performance. This means that the EE can crash at certain occasions if we do not use the information API from the correct callbacks or passing accurate output parameters.

 

Also note that the security callbacks are not implemented yet. For more details please read the corprof.idl file.

 

A final note is that in the end of the program it displays the results in the output. If you wish to change the output format all you need to modify are the various Dump() functions in ProfilerHelper.cpp file. The best way to view the results is to redirect the output in a file and process the file after the managed program has completed its execution. If a failure occurs during the program’s execution, we will shutdown the profiling events and print the error to the standard output. The profiler will not attempt to terminate the execution of the managed program.

 

 

##################################################################################

##

##          Building the Microsoft NGWS General Code

##                Profiler Sample (ProfilerGCP)

##

##################################################################################

 

To build the ProfilerGCP sample you will need to have either MSDev 6.* or a fairly recent version of the Win32 SDK installed on your system. Also you will need to have NGWS Runtime installed. The sample was intended to be built (via nmake) from the version of the MSVC C++ compiler that comes with MSDev 6.*.

Below is the list of files included for the sample.

 

.\Profiler

      Readme.htm

      EnableProfiler.bat

 

BasicHdr.h

Container.hpp

 

ProfilerGCP.mak

ProfilerGCP.def

 

RegUtil.h  

RegUtil.cpp

 

ClassFactory.h

ClassFactory.cpp

 

ProfilerBase.h  

ProfilerBase.cpp

 

ProfilerHelper.h

ProfilerHelper.cpp

 

ProfilerCallback.h

ProfilerCallback.cpp

 

 

Building the sample.

 

q       Ensure that the environment is setup to build using nmake. MSDev, for example, contains a batch file “VCVARS32.bat”, which can be run to do this.

 

q       By default, the makefile assumes that the Win32 headers/libs live under

   

      WIN32_LIB_DIR= d:\progra~1\micros~1\vc98\lib

      WIN32_INC_DIR= d:\progra~1\micros~1\vc98\include

     

If necessary, change these two lines (in the makefile) to reflect where the Win32 headers/libs are on your system.

 

q       By default, the makefile assumes that the NGWS headers/libs live under

   

      NGWS_LIB_DIR= d:\progra~1\NGWSSDK\lib

      NGWS_INC_DIR= d:\progra~1\NGWSSDK\include

 

If necessary, change these two lines (in the makefile) to reflect where the NGWS headers/libs are on your system.

 

q       From the directory containing the makefile, invoke

 

nmake /f profilerGCP.mak

 

to build the sample. The end result should be a debug version of profilerGCP.dll. The makefile can be modified to build a retail version if desired.

 

 

##################################################################################

##

##          Running the Microsoft NGWS General Code

##                Profiler Sample (ProfilerGCP)

##

##################################################################################

 

To enable the sample profiler, run the batch file “EnableProfiler.bat” from the command line of a DOS console. Once the sample profiler is enabled, run any managed program (or program using a managed component) in the same DOS console. The profiler will dump information (to the DOS console) on loaded appdomains, assemblies, modules, classes, as well as information on JITted methods once the program terminates.

 

Note. The batch file does three things. First, it sets an environment variable (COR_ENABLE_PROFILING) which enables the profiler services in the NGWS Runtime. Second, it registers the sample profiler using regsvr32. Lastly, it sets another environment variable (COR_PROFILER) which tells the NGWS Runtime which profiler to send events to. For more information on enabling the NGWS Profiler Services, see “Enable Profiling” in the NGWS SDK Documentation.