COM Memory Leak Detection

 

Home Purchase Preface Contents Examples Resources Errata Site Guide

 COM and CORBAŽ Side by Side

Detecting COM Memory Leaks

The conventional C/C++ run-time functions cannot be used to determine COM-related memory leaks. This page explains how to use IMallocSpy to detect COM memory leaks in a C++ program.

bulletoleaut32.dll (checked version)
bulletmovefile.exe
bulletIMallocSpy
bulletExample Program
bulletDownloading the Example

 

oleaut32.dll (checked version)

OLE Automation caches allocations of BSTRs. This caching creates confusion when attempting to locate COM related memory leaks. For more information on this issue, see:

http://support.microsoft.com/support/kb/articles/q139/0/71.asp

To disable BSTR caching, you will need to do the following:

  1. In your environment, set OANOCACHE=1
  2. Install the checked (debug) version of oleaut32.dll

The checked version of oleaut32.dll can be obtained by downloading a checked version of the appropriate service pack for Windows NT (I have never used Windows 95 or Windows 98 to check for memory leaks in my COM applications).

The checked version of Service Pack 5 can be downloaded from:

http://www.microsoft.com/ntserver/nts/downloads/recommended/sp5/sp5build/default.asp

Previous service packs can be downloaded from:

ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/nt40

I have used the IMallocSpy example described in this document with Service Packs 3, 4, and 5.

Once you have obtained the checked version of oleaut32.dll, you'll need to replace your existing oleaut32.dll in c:\winnt\system32 (or wherever) with the checked version.

Be very careful when doing this since many different applications rely on oleaut32.dll. In fact, you won't be able to overwrite c:\winnt\system32\oleaut32.dll because it will already be in use.

To replace oleaut32.dll, you'll need to either install another version of NT that you can boot into, or you can use the movefile application described in the next section.

movefile.exe

Movefile.exe is a very simple program that allows a file to be "moved" the next time that Windows is booted.

Click here to see the source code for the movefile application. It relies on the MoveFileEx() win32 function.

The movefile application (including a compiled exe) can be downloaded along with the rest of the example at the bottom of this page.

Once you have placed "movefile.exe" in your path, you can use it as shown below.

C:\WINNT\system32> movefile
Usage : MoveFile  'existing filename'  'new filename'

C:\WINNT\system32> movefile oleaut32_checked.dll oleaut32.dll
oleaut32.dll will be replaced with oleaut32_checked.dll on next reboot.
You will then reboot your machine and the release version of oleaut32.dll will be replaced with the checked version of oleaut32.dll.

Now that you've turned off BSTR caching, you're ready to use IMallocSpy.

IMallocSpy

The IMallocSpy interface is used when creating a "spy" object that can monitor COM memory allocations at run-time. An instance of the spy is created and is registered using the following call:

CoRegisterMallocSpy

To keep things simple, my example uses a spy inside a simple console application. For COM objects you will need to install the spy in each COM application (DLL or EXE).

Example Program

My application consists of the following three source files:

bulletCmallspy.h
bulletCmallspy.cpp
bulletleaker.cpp

The Cmallspy.{h,cpp} files are the header and implementation files for the CMallocSpy COM class that implements the IMallocSpy interface. You should not need to change the source for these files unless you need to do more than search for memory leaks. I haven't changed these files in quite some time. The main limitation is that I allocate 100,000 buckets to keep track of the allocations. If your COM application is doing an extremely high number of allocations, you'll crash the program when you exceed the 100,000 limit.

I wrote CMallocSpy so that it would work in a similar manner to the Crt functions, which are used to find C/C++ run-time memory leaks. The first step is to identify the allocation number of the leak. Next, a breakalloc() is set to occur at the appropriate allocation. The COM application can then be run in the debugger and the stack can be checked to see what allocation caused the leak at the appropriate breakpoint.

In the leaker.cpp example, I identify both CRT and COM memory leaks. You should be able to build the leaker  project, run it in the debugger, and view the following in the "Output" window.

Loaded 'C:\WINNT4\system32\oleaut32.dll', no matching symbolic information found.
CMallocSpy dump ->
 IMalloc memory leak at [4]
 IMalloc memory leak at [5]
CMallocSpy dump complete.
Dumping objects ->
{48} normal block at 0x00BF0070, 75 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
The thread 0x145 has exited with code 0 (0x0).
The program 'C:\comleaks\leaker\Debug\leaker.exe' has exited with code 0 (0x0).

Downloading the Example

All of the source code discussed in this document can be downloaded from the following location:

comleaks.zip  (22 KB)

 

Home ] Up ] Purchase ] Preface ] Contents ] Examples ] Errata ] Site Guide ]

Send mail to jpritchard@pobox.com with questions or comments about this web site.
Last modified: August 12, 2003