Microsoft Windows NT Call Profiler README File March 06, 1992 September 22, 1992 February 22, 1993 April 27, 1994 1. Description: ---------------- Windows NT (32-bit) Call/Attributive Profiler (CAP) for x86, Mips, Alpha, and PowerPC platforms. CAP is a general purpose profiling tool that can be used to measure the function call performance of .EXE's and .DLL's, (AKA modules), in a variety of ways. The following measurement methods are supported: a) Measuring calls from within an .EXE. b) Measuring calls from within a .DLL. c) Measuring calls from an .EXE to all of it's DLLs. d) Measuring calls from one .DLL to all of its DLLs. e) Measuring all the calls to specified .DLL's, from any .EXE or .DLL. f) Any arbitrary combination of a) through e). CAP creates a call tree of all the functions called in the EXE(s)/ DLL(s) being profiled. Profiling Data can be collected only for functions in C programs by using the attributed profiling hook provided by the Microsoft C compiler (compiling with the "-Gh" option). Data is *NOT* collected for functions in assembler language programs. 2. Profiling Files: -------------------- o cap.ini -- Call Profiler initialization file. o cap.dll -- Call Profiler DLL. o cap.lib -- Profiler library file containing profiling entry points. o capdump.exe -- Dump utility for dumping/clearing profiling data, and stopping profiling at any time. o capsetup.exe -- Allows attaching/detaching cap.dll to/from all Windows applications. o penter.lib -- An empty library containing a dummy CAP entry point. This can be used instead of CAP.lib to link with an already CAP ready executable object modules (recompiled with the -Gh option) so the application can run without recompiling and without any of the CAP overheads. o sol.end -- A sample CAP data file generated by a sample profile run of sol.exe. o readme -- Call Profiler README document (this file). 3. Using the Call Profiler: ---------------------------- o Place a copy of CAP.INI in one of the following area where it suits your need: - the CURRENT directory - the Windows directory (ie: c:\windows\cap.ini) - the root of the current drive (\cap.ini) - the root dir of C: drive (c:\cap.ini) list all the DLL/EXE images to be profiled as follows: (Note: CAP.INI and all its three section headers must exist but the sections could be left blank) [EXES] Name of applications to be profiled. Each name should be on a new line. [PATCH IMPORTS] List of DLLs/EXEs to be profiled for all of their imported entries. Each name should be on a new line. [PATCH CALLERS] List of DLLs to be profiled for their exported entries if called from the applications (listed in the [EXE] section) or any of their DLLs. Each name should be on a new line. [NAME LENGTH] This is an optional section allowing to specify the maximum number of characters to be printed for the routine name in the output data files. If the value is not specified or 0, default length of 40 is used. Length can be any value between 20 and 2048. [CHRONO FUNCS] List of modules and corresponding functions that start the dump of the chronological listing. For example, if "test=SomeFunc" is listed under this section then all functions that are called inside of test!SomeFunc... will be listed until the call depth is less than or equal to the depth of the listed function. [EXCLUDE FUNCS] List of modules and corresponding functions that will be excluded from the profiling process. The [call _penter] at the beginning of the function will be NOPed. But if these functions call some other functions and if these children functions are not listed under this section, they will still be included in the profiling process. To correctly take a function out of the profiling process, him and his children must all be included under this section. If not, the timing of the Excluded function will be included with its parent routine while the timing of its children routine will still be computed separately. [OUTPUT FILE] filename=xxxxx This option allows the user to specify a different drive for the output listing. This file can be over the net somewhere or just a different name than xxxx.END or xxxx.CAP. For example: filename=c:\results\explorer\explorer.cap or filename=\\Results\CAP\explorer\explorer.pro [CAP FLAGS] - profile "on" or "off". Turn on or off profiling initially without altering the code. - dumpbinary "on" or "off". This is to allow the dumping of the data in binary form, not in the regular text form. This feature is there to allow faster dumping and require less space. A program called CAPRPT will go in and produce the listing from this data. CAPRPT is still under development. - capthread "on" or "off". If on, this switch will start the 3 threads that will interact with CAPDUMP to Clear, Start and Stop the collection of data. This is made into an option so if the user does not need CAPDUMP, he/she does not have to start 3 additional threads everytime CAP is initialized. This is quite expensive when profiling a number of processes at the same time. - loadlibrary "on" or "off". If on, CAP will intercept all LoadLibrary calls from the profiled binary and correctly initializes its symbol table. - setjump "on" or "off". If on, CAP will also intercept longjmp instructions and handled it accordingly. - undecoratename "on" or "off". Turn on or off the undecoration of function names. - excelaware "on" or "off". Turn on or off the addition of delimiters so the output listing can be imported into Excel. - regular dump "on" or "off". Turn on or off the regular data that CAP dumps out. This is to shorten the output listing if you are only interested in the chronological listings. - chronocollect "on" or "off". Turn on or off the collection of the chronological listing of the functions. This could be very lengthy. - chronodump "on" or "off". Turn on or off the output for the chrono listing. This switch is independent of [chronocollect] since sometimes you just want to turn off the dumping but leaving the collection alone. - slowsymbols "on" or "off". Turn on or off exhaustive lookup of symbols. If off, addresses for which symbols cannot be quickly found (e.g. static symbols) are printed as absolute addresses versus a symbol plus offset in the on case. o Attach CAP.DLL to the application process. This can be done in two ways: 1) Recompile your EXE/DLL using the "-Gh" and "-Zd" compiler options. (NOTE - on Mips platform, use "-Od" to disable compiler optimization.) Link it with CAP.LIB using the "-debugtype:coff" and "-debug:mapped,partial" linker options. This method will cause all the C functions in the recompiled sources to be profiled. NOTE:- If symbols have been removed from your exe or dll, Cap will try to locate the symbols files (DBG files) using the path as specified in the environment variable "_nt_symbol_path". E.G. if the DBG file of your exe is in c:\symbols\exe, set _nt_symbol_path to c:\symbols. 2) Run CapSetup.exe to attach CAP.DLL to all Windows applications. Note that only those EXEs listed in the [EXES] section of CAP.INI will be profiled. Overhead for the non-profiled applications is minimal. See section 8, "Using CapSetup", for CapSetup.exe usage. You need to have Administrative privileges in order to run CapSetup. *** Please be extremely careful with this option since turning *** it on could resulted in the system being totally thrashed *** if CAP.DLL could not run correctly. Thus causing the *** profiled binary to fail to load also. And if the binary *** is as important as WINLOGON, then the only thing to do *** is to reload NT or use a dummy cap.dll or remove the *** CAP.INI file. o Place CAP.DLL in your SYSTEM directory (i.e. ..\nt\system32). o Run your applications. o All the applications specified in the [EXES] section of the CAP.INI will be profiled. o Exit the application to dump the profiling data, or run CapDump.exe to dump the data. See section 6 "Profiling Data" for details. 4. Examples for Supported Measurement Methods: ---------------------------------------------- Suppose we have Windows .EXE's called ZOOMAN and HUNTED, and .DLLs called ELEPHANT, MONKEY, SNAKE, WATER, and FOOD. Let's assume the following intercall dependencies exist: zooman.exe - water.dll - food.dll hunted.exe - elephant.dll -- water.dll -- food.dll - monkey.dll -- water.dll -- food.dll - snake.dll a) Measuring calls from within ZOOMAN.EXE: o Recompile ZOOMAN and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] zooman.exe [PATCH IMPORTS] [PATCH CALLERS] [NAME LENGTH] 60 o All the C functions in ZOOMAN.EXE will be profiled by CAP. b) Measuring calls from within WATER.DLL: o Recompile WATER and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] zooman.exe hunted.exe [PATCH IMPORTS] [PATCH CALLERS] [NAME LENGTH] o Both ZOOMAN.EXE and HUNTED.EXE will be profiled for all the C functions within WATER.DLL. c) Measuring calls from HUNTED.EXE to it's DLLs: o Run CapSetup.exe to attach cap.dll to all Windows Applications, and reboot the system. o Setup CAP.INI as follows: [EXES] hunted.exe [PATCH IMPORTS] hunted.exe [PATCH CALLERS] [NAME LENGTH] o All the calls from HUNTED.EXE to ELEPHANT.DLL, MONKEY.DLL, and SNAKE.DLL will be profiled. These are all the C functions exported by ELEPHANT, MONKEY, and SNAKE DLLs which are used by HUNTED.exe. d) Measuring calls from ELEPHANT.DLL and MONKEY.DLL to their DLLs: o Run CapSetup.exe to attach cap.dll to all Windows Applications, and reboot the system. o Setup CAP.INI as follows: [EXES] hunted.exe [PATCH IMPORTS] elephant.dll monkey.dll [PATCH CALLERS] [NAME LENGTH] o All calls from ELEPHANT.DLL and MONKEY.DLL to WATER.DLL and FOOD.DLL will be measured. These are all the C functions exported by WATER and FOOD DLLs which are used by either ELEPHANT.DLL or MONKEY.DLL. e) Measuring all the calls to FOOD.DLL: o Run CapSetup.exe to attach cap.dll to all Windows Applications, and reboot the system. o Setup CAP.INI as follows: [EXES] zooman.exe hunted.exe [PATCH IMPORTS] [PATCH CALLERS] food.dll [NAME LENGTH] o Both ZOOMAN.EXE and HUNTED.EXE will be profiled separately for all the calls to FOOD.DLL. For ZOOMAN.EXE, these are all the C functions exported by FOOD.DLL which are used by ZOOMAN.EXE. And for HUNTED.EXE these are all the C functions exported by FODD.DLL which are used by either ELEPAHNT.DLL or MONKEY.DLL. f) Any arbitrary combination of a) through e): a+c) Measuring calls from within ZOOMAN.EXE and calls to it's DLLs: o Recompile ZOOMAN and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] zooman.exe [PATCH IMPORTS] zooman.exe [PATCH CALLERS] [NAME LENGTH] c+d) Measuring calls from HUNTED.EXE to it's DLLs and calls from ELEPHANT and MONKEY DLLs to their DLLs: o Run CapSetup.exe to attach cap.dll to all Windows Applications, and reboot the system. o Setup CAP.INI as follows: [EXES] hunted.exe [PATCH IMPORTS] hunted.exe elephant.dll monkey.dll [PATCH CALLERS] [NAME LENGTH] a+c+d) Measuring calls from within HUNTED.EXE and calls to its DLLs plus calls from ELEPHANT and MONKEY DLLs to their DLLs: o Recompile HUNTED and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] hunted.exe [PATCH IMPORTS] hunted.exe elephant.dll monkey.dll [PATCH CALLERS] [NAME LENGTH] b+d) Measuring calls from within ELEPHANT.DLL and calls to its DLLs: o Recompile ELEPHANT and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] hunted.exe [PATCH IMPORTS] elephant.dll [PATCH CALLERS] [NAME LENGTH] * * * * * * * * * * * * * * * * R E S T R I C T I O N * * * * * * * * * * * * * * * * Do NOT measure calls within a DLL if the DLL's exported functions are being measured from another EXE/DLL. The following example shows this incorrect combination which should be avoided: x) Measuring calls from ZOOMAN.EXE to its DLLs and calls within WATER.DLL: o Recompile WATER and link it with CAP.LIB as described in section 3. o Setup CAP.INI as follows: [EXES] zooman.exe [PATCH IMPORTS] zooman.exe [PATCH CALLERS] [NAME LENGTH] o Note that in addition to measuring all C functions (including the exported routines) within WATER.DLL, all the C functions exported by WATER.DLL which are used by ZOOMAN.EXE are measured. This means that the same function within WATER.DLL will be measured twice. These types of scenarios are not supported and will result in unexpected behavior. 5. Exported Routines: ---------------------- The exported entry points listed below can be used to control profiling certain sections of code. They can be combined with any of the supported measurement methods mentioned above. o StartCAP() : Clears profiling data & starts profiling o StopCAP() : Stops profiling o DumpCAP() : Dumps data for the current CAP.DLL instance A typical example (foo.exe): StartCAP(); // Clear existing profiling data and restart // profiling. .. .. // application's code .. StopCAP(); // Stop profiling without dumping data. DumpCAP(); // Dump profiling data to FOO.CAP file. Prototypes for these routines are: extern void _stdcall StartCAP(void); extern void _stdcall StopCAP(void); extern void _stdcall DumpCAP(void); 6. Profiling Data: ------------------- o Profiling data can be captured in three ways: 1) Upon termination of the application profiling data is dumped into a text file using the application name with .END extension. 2) Using the dump utility, CapDump.exe, profiling data can be dumped at any time. Application name with .CAP extension will be the data file name. See section 7 "Using CapDump" for more details. 3) Using exported routine DumpCAP(). Application name with .CAP extension will be the data file name. o Data files are created in the same directory as the application that is being profiled. o Data is appended to data files with each data dump. o A separate call tree is generated for each thread in the process context. Different sections in the data file indicates data for different threads in the process. o The following data is dumped: - Call depth in the tree - Function name - Number of calls - Total time for the function+callees - Time per call for the function+callees - Total time of the function only - Time per call of the function only - First time (function+callees) - Minimum time (function+callees) - Maximum time (function+callees) o See SOL.END as a sample output file. 7. Using CapDump: ------------------ o CapDump.exe can be used to stop profiling and clear/dump profiling data for all the applications being profiled, at any time. o The following options are available via CapDump.exe: - Stop : Stops profiling (applications continue to run). - Clear and Restart : Clears any existing profiling data and restarts profiling. - Dump and Stop : Dumps any existing profiling data and stops profiling (applications continue to run). o Data is dumped to a text file using the profiling applications name with .CAP extension. All fields are tab separated. Data is appended to data files with each dump. o If calls are being profiled when data clearing is requested, the time of clearing is used as the starting time for those calls. o A log file, capdump.log, is generated when capdump.exe is run. It will contain any errors that might occur during capdump.exe operation and for normal error free operation, capdump.log will be empty. 8. Using CapSetup: ------------------- Usage: CapSetup -A | -D -A Attaches CAP.dll to all Windows applications -D Detaches CAP.dll from all Windows applications Notes: 1) Administrative privileges are required in order to run CapSetup. 2) System needs to be rebooted in order for the change to take effect. *** Please be extremely careful with this option since turning *** it on could resulted in the system being totally thrashed *** if CAP.DLL could not run correctly. Thus causing the *** profiled binary to fail to load also. And if the binary *** is as important as WINLOGON, then the only thing to do *** is to reload NT or use a dummy cap.dll, or remove *** the CAP.INI file. 9. Caveats: ------------ o Cap - if a routine being profiled is within try-except block and it crashes, the stack will NOT unwind. This is because there is no prolog code in the Cap penter to support this. o For Mips only - Mips Cap cannot profile static functions. o If symbols are not available in an EXE/DLL that is being profiled, ??? is displayed as the function name. o Non-local GOTOs (i.e. setjmp/longjmp calls) are not currently supported. Profiling an application containing any non-local GOTOs will result in unexpected results. o Profiling data in *NOT* collected for functions in assembler language programs. o Paging file size will increase while profiling. o For Alpha only - setjump, loadlibrary, and Exclude Funcs are not implemented in this release. o It may take a long time when cap is dumping data to the cap file. In some cases, it may take up to 30 minutes, depending on how many symbols and the level of nesting calls. o If you are using GDI calls, you may want to add GdiSetBatchLimit(1) for each thread before you re-compile with cap.lib. This is to disable batching so each GDI call will be performed and profiled correctly. ** END OF README **