INFO: Troubleshooting CAP/WST Utilities Under Windows NT

Last reviewed: March 4, 1998
Article ID: Q169275
The information in this article applies to:
  • Microsoft Win32 Software Development Kit (SDK)

SUMMARY

This article provides a collection of tips, tricks, and traps to you can use to avoid and solve common problems that you may encounter while using the Call Attribute Profiler (CAP) and Working Set Tuner (WST) utilities for Windows NT. Note that these utilities are included with the Win32 Software Development Kit. You can use these powerful utilities to make your application run faster and use less RAM.

This article assumes that you have read the preliminary information on the use of these tools that is available in the Win32 SDK Tools documentation. The information in this article applies to the versions of CAP/WST utilities that are shipped on the January 97 Win32 SDK or later.

MORE INFORMATION

Preparing Your Application

We recommend that you build applications that you want to tune with CAP or WST with slightly different switches than the documentation suggests. For the compiler, use /Zi or /Z7 (don't forget /Gh). For the linker, use /debug /debugtype:both and /pdb:<name>.pdb or /pdb:none. We recommend using the C7- style symbols: /Z7 with the compiler and /pdb:none with the linker for best results.

One benefit of using these switches is that you can do full symbolic debugging under the Visual C++ or Windbg debugger in case either the CAP or WST utility manages to flush out a problem in your code. This is more common than you may think, for example /Gh causes the compiler to insert a call to a function called _penter() in front of each and every function in your code. This global increase in code size causes your functions to load into slightly different offsets in memory, which may cause a pointer bug or array-overrun bug in your code to now show itself. By using these switches, you can debug your application normally when it is compiled for CAP/WST.

TIP: We recommend that you do not use capsetup.exe to prepare your applications for tuning. Instead, building your applications with the proper switches works more reliably.

TRAP: Running "capsetup -a" and then building your application for tuning causes the CAP utility to not work. Just avoid Capsetup.exe if you can.

Tuning/Profiling DLLs and OCXs

Tuning DLLs and OCXs is fairly straightforward for both CAP and WST, once you know the details, though the procedure is slightly different for each.

WST:

When an executable compiled for WST is initialized, WST gets control and looks at all the DLLs loaded in that process's memory space. Only DLLs that are present and built for WST are tuned, which means that the DLLs must be statically linked. Dynamically-loaded DLLs (and OCXs) are not tuned even though they may be compiled for tuning.

TRICK: However, you can tune all DLLs/OCXs. The trick is to build only the DLL/OCX that you want to tune for tuning. Do not build the executable for tuning. Then do the following:

  1. Remove the name of the .EXE from the [exes] section in WST.INI file to cut down on extraneous output files in the output directory.

  2. Put the name of the DLL/OCX into the [exes] section in WST.INI.

  3. The symbols for the DLL/OCX (whether it is the DLL/OCX itself, or a .dbg or .pdb file) must be on the symbol search path (which includes %SystemRoot%, %_NT_SYMBOL_PATH%, %_NT_ALT_SYMBOL_PATH%, the working directory, and all subdirectories of these four). Otherwise, you will get empty output files in the WST directory. This is especially important for an OCX, which is usually residing (and also usually registered) in another directory.

TIP: We have had best luck by simply putting and registering the DLL/OCX in the same directory as the executable, or by making sure the application and DLL/OCX are in subdirectories of the current directory when you run the executable.

CAP:

Fortunately, CAP supports dynamically loaded libraries without any special caveats. You just need to make sure that loadlibrary=on in the CAP.INI file. However, if you're not getting symbolic information for your DLLs, you can try something similar to the procedure for WST--except you must put the name of the .EXE in the [exes] section, unlike for WST.

Known Problems, Limitations

The following is a list of known problems and limitations with the CAP and WST utilities. It's best to contact Microsoft Technical Support for help with any problems encountered with these utilities. A support engineer may be able to provide a workaround or help with critical problems.

  1. If you are tuning with CAP/WST under Windows NT version 3.51 and run into problems, it is highly recommended that you switch to Windows NT version 4.0 and use the latest version of CAP/WST utilities. It is possible that the problem you are encountering with these utilities ,may have already been fixed in the latest Windows NT 4.0 SDK. You should also make sure you have the latest version of the Win32 SDK installed on your Windows NT machine or simply copy the latest version of CAP.DLL file from the Win32 SDK into your executable's directory.

    Trap: Note that you can use CAP.DLL for Windows NT 4.0 on a Windows NT Version 3.51. However, you must copy IMAGEHLP.DLL from Windows NT 4.0 into your application's directory that you are tuning because the latest version of CAP/WST utilities need the new IMAGEHLP.DLL to do symbol lookups. Be careful not to replace the IMAGEHLP.DLL in the Window NT 3.51 %systemroot%\system32 directory.

  2. On rare occasions, when using CAP, a fault occurs in the C-runtime library's strcpy() function call from CAP.DLL. This causes the target DLL, that is being tuned by CAP, to not load its symbols. This results in missing symbols in the .END file after a profile run for such a DLL. Unfortunately, this could be the DLL or OCX that you are trying to tune, as opposed to a child or system DLL. You can identify this problem if you have linked with the debug C-runtime (CRT) library and you see strcpy() at the top of the call stack in the debugger after stopping at the second-chance exception.

    We are researching this known problem with the CAP utility and will post new information here in the Microsoft Knowledge Base as it becomes available.

  3. The system IMAGEHLP.DLL for Windows NT versions 4.0 with Service Pack 2 (and previous versions of NT) returns corrupted symbolic name strings when CAP is doing symbol lookups and when the setting "undecorate=off" is set in CAP.INI. In this situation, your .END file will contain a few "garbage" characters embedded, usually a control-Z. In addition, this problem could also crash Capview.exe utility. This problem can typically be fixed by stripping out any non-printable characters from your .END file.

    We are researching this known problem with the CAP utility and will post new information here in the Microsoft Knowledge Base as it becomes available.

  4. Trap: The CAP tool has certain problems with Visual C++ style exception- handling. If a Visual C++ exception occurs, CAP does not correctly clean up the stack, causing strange crashes and application lockups. In order to avoid this problem, you have to modify your application so that no Visual C++ exceptions occur during a profile run. Note that this problem may also occur with the WST utility, since both these utilities share common code.

    We are researching this known problem with CAP, WST utilities and will post new information here in the Microsoft Knowledge Base as it becomes available.

  5. WST utility cannot tune static functions. This is due to a limitation of the Visual C++ linker. When WST encounters static functions, it will tune them like other functions and they will be listed in the .PRF output file. But, the Visual C++ linker cannot reorder static functions, and, consequently, will generate a few harmless warnings that it is unable to reorder them.

    Note that for Visual C++ applications you may see some mysterious static functions in the .PRF file with a name in the format of _$Ennn, where

       'nnn' is some numeric value. These are static helper functions generated
       by the compiler. WST puts these function names in the .PRF output, but
       the resulting linker warnings can be safely ignored. Unfortunately these
       static functions (and any that you defined in your application) will not
       be reordered and, consequently, will not be tuned either.
    
    

CAP Memory Usage Information

CAP memory usage can be a factor in the performance of your application. If CAP's memory usage becomes too great (usually due to a lot of chronological data), this will result in a lot of swapping, which in turn can affect the performance of your application.

CAP's memory usage can be divided into the following three groups (ordered from smallest to largest):

  1. Symbol information.

  2. Calling tree structure.

  3. Chronological calling data.

The symbol data is loaded when the app starts, and also when a DLL is dynamically loaded (if 'loadlibrary=on' in CAP.INI). The symbol information is a kind of dictionary, mapping function names to raw hex addresses. This allows CAP to log the profile information by name rather than hex addresses. The size of the symbol information depends on how many DLL's are loaded, and how many symbols are in each DLL.

The calling tree structure is continuously built as the profiled application executes. Each node in this tree represents one caller-callee pair. For example, the first time function A calls function B, a new node is created. Each additional call from function A to function B changes the profiling values in node A-B, but does not increase the storage space. So the size of the calling tree is dependent on the number of caller-callee relations that are actually exercised by the application. Each node requires 80 bytes of memory.

The calling tree information is dumped to the log file and provides the input for Capview.exe. It contains information such as the number of times function A called function B, the shortest/longest/average time function B executed when called by function A, and how much of function B's time was due to calls that it made itself.

Chronological calling data is by far the largest user of CAP memory. Unlike the calling tree data, the chronological data contains a data cell for every function call that occurs. If function A calls function B 100 times, 100 cells are created. This allows for a very detailed log that shows the exact order that calls were made and how much time each call took. The size of the chronological data, then, depends on how many function calls are made by the application. Each data cell requires 40 bytes.

Preparing to Contact Technical Support

When CAP or WST fails, the most common symptoms are failure to produce any output or an exception while your application executes (usually during initialization). To determine if the failure is due to a problem in CAP.DLL or WST.DLL, you will have to debug your application. When you hit a 2nd- chance exception in the debugger (ignore all 1st-chance exceptions - they are normal and are handled by an exception handler in CAP/WST), look at the top of the call stack to see if the exception occurred in CAP or WST. To do this, use LINK -dump -headers on CAP.DLL or WST.DLL (or you can do a "quick view" in Windows Explorer on the DLL) and note the image base address and the "size of image" value. If the address where the exception occurred is within image base + size of image, then you have most likely encountered a bug in CAP.DLL or WST.DLL.

Before contacting Microsoft Technical Support for help in diagnosing the problem, please debug your application and do the following (these instructions are for an x86 machine):

  1. Dump the stack as follows:

    Windbg: In the command window, enter "dd esp" and leave the output there.

    Visual C debugger: On the Debug menu, click Memory, enter "esp", and then copy downward 20 lines or so (right-click, then click Copy). Paste it into a new document in Notepad or any other editor.

  2. Get the contents of the registers as follows:

    Windbg: In the command window, type "r".

    Visual C debugger: Get the contents of the registers from the Debug menu, Registers window.

  3. Get the call stack as follows:

    Windbg: In the command window, type "kbsv". Visual C debugger: On the Debug menu, Call Stack. Copy everything.

  4. Get a disassembly listing of the code around the exception as follows:

    Windbg: Click the assembly toolbar button (with the 1's and 0's in it) and get a screenful of code both above and below the address of the 2nd- chance exception.

    Visual C debugger: On the Debug menu, click Disassembly. Copy a few pages above and below the address of the exception.

  5. Assemble information as follows:

    Windbg: The output from all the commands that you typed into the command window should still be in the command window. Scroll back in the command window, copy all the debug output from CAP/WST, and include the stack dump, register dump, and call stack you created.

    Visual C debugger: Copy the output from CAP/WST from the Output window into your document.

TIP: To skip past all the 1st-chance exceptions that you may hit when debugging CAP-compiled applications (which are normal) do the following:

Windbg: On the Options menu, click Exceptions, set "Access Violation" (0xc0000005) to "Notify", and then click Change.

Visual C debugger: On the Debug menu, click Exceptions and make sure that "access violation" is set to "stop if not handled".

REFERENCES

Win32 SDK Tools documentation


Additional query words: debug tls base
Keywords : BseMisc kbtool kbtshoot
Platform : NT WINDOWS
Issue type : kbhowto


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: March 4, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.