Welcome to Leak Browser

Copyright © 1998-2006 Mark Bartosik

Leak Browser is a debugging tool for tacking down hard to find resource leaks in applications. Please visit www.leakbrowser.com.

Getting Started

It is very important that you read the following lessons:

    • Lesson 1 Understanding what is a leak

    • Lesson 2 Leak testing

    • Lesson 3 Attaching to a program

    • Lesson 4 Hunting for leaks
    • Lesson 8 Getting the best results

    • You may also like to read the other lessons

You are probably hoping that Leak Browser will find all the leaks in your code. Let's hope that it will, however, one must recognize that it is a tool not a silver bullet. That means that it can be used to help you do a job, but it will not do that job for you. This manual is more than just a guide to using Leak Browser, it covers:

  • How to use Leak Browser.

  • A bit about how Leak Browser works.

  • Tips on code development techniques.

  • Please take the time to browse around the help file.


Installation

System requirements:

  • Windows NT 4.0 (sp6a recommended) or Windows 2000, or XP

  • At least 128MB of RAM, 256MB recommended (the more memory the better)

  • 20MB available disk space for install.

  • Microsoft Internet Explorer 6.0 or above (with service packs)

Leak Browser should be installed and used under an administrative account. i.e. You must be a member of the administrators group.

To add a user to the administrators group:

Windows NT 4.0: Use the "User Manager" under "Administrative Tools" in the start menu.
Windows 2000, XP, 2003: Use the "Computer Management Console", "Administrative Tools" in the control panel.


Lesson 1 - Understanding what is a leak

It may seem obvious what a leak is. However, your definition of a leak may be different to Leak Browser's, so please read this section. In short leaks are resources that are repeatedly allocated (but not deallocated) during the running stage of a program.

There are usually three stages in the lifetime of a program:

  1. Startup

  2. Running

  3. Shutdown

Typically only one of stages is going to be important to your customers that is the "Running" of the program. This is the stage that the program was written for, it is the stage that might earn the money. The "Startup" stage is only there to facilitate the "Running" stage. The "Shutdown" stage is only there to avoid dead processes eventually consuming all available resources.

If your code leaks a resource during startup it is of little consequence. Startup only occurs once, and the resources will be tidied up by the operating system during shutdown. If your code leaks a resource during shutdown it is of no consequence since in a few microseconds time the operating system will tidy up the resource anyway. Indeed there is a good argument that the shutdown code should simply perform essential shutdown tasks like flushing buffers and then exiting the process without any further ado. Ask yourself "Why should I spend days coding a beautiful and elegant shutdown, when my customer is only concerned with the running stage of my program?"

Any resource leaks that occur during the running of a program are very dangerous. I have seen a 24 byte leak in code lead to 1 giga byte of memory leaking over a weekend, or a single handle leak bring a trading system to its knees in a few hours. This is the stage of program execution that Leak Browser targets.

Whether or not the program maintains a reference to a resource does not matter. If a program continually allocates widgets and adds them to a collection of widgets, but never removes them this is still a leak. Note that this may be different to other definitions of leaks. In cases where garbage collection is used the resource is not considered to be leaked unless there is no longer a reference to it. Garbage collection can help, but it only solves half the problem (and introduces others). Leak Browser is not concerned whether a resource is still referenced, and thus is able to target leaks that garbage collection cannot.

Which leaks are important - be a little pragmatic

Generally you should only concern yourself with leaks that occur during the running stage of your program (see above). However sometimes you can safely ignore leaks in this area of code. For example:

You are creating an e-commerce server application. The server can be rebooted every weekend. It is a dedicated server with 1GB of memory, on startup 200MB of memory is in use. There are no other known leaks in the system. So you've got 800MB of memory to play with. Let's reduce that to 250MB just for safety incase a reboot does not happen after a busy week. There are 24x7 hours per week, so you can afford to leak 250/(24*7) MB per hour. That's 1.4MB per hour. You expect to average 1000 transactions per hour. So you can afford to leak 1.4KB per transaction.

There are several key assumptions here:

  1. You have a dedicated server.

  2. The server can be rebooted at regular intervals.

  3. There are no other significant leaks in the system.

  4. The leaks are memory only leaks, not scarce resources like operating system handles.

In this case you might consider getting to market quicker, and releasing a fixed version later without the leaks. Before you think that your problems are over:

  • If you are running in a open system (not on a dedicated machine), then the amount that you can afford to leak before upsetting your customers is much less.

  • You can probably leak a little bit on operations that are known to be infrequent.

  • You can never afford to leak scarce resources (like operating system handles).

  • Customers don't always use your applications like you think. Your best customer will use the least tested and most leaky facilities of your application, and more than you ever expect. This is not just cynicism, there is a correlation between good customers and unexpected usage patterns.


Lesson 2 - Leak Testing

Before you use Leak Browser, it is best to know what functional areas of your program leak. The easiest way to do this is to run "task manager" or "perfmon" to monitor the amount of memory and handles used by your application. Then repeat various operations of your program, while keeping an eye on the figures for memory and handle usage. If either of these figures CONTINUALLY increases you have a leak.

Tips:

  • Ignore the figures for the first few iterations of each operation. They may include some once-off allocations.

  • Keep the operations simple where possible.

  • Perform the operations enough times to be confident that there really is a leak for each iteration (at least 5 times).

  • Each iteration should aim to leave the program in the same state that it was when the iteration started.

  • Leave the program for a couple of minutes to check whether the resource figures fall back down by them selves (this is sometimes the case where caches are used in the code).

What you are looking for is a repetitive leak. One where there is most likely a linear relationship between the number of operations performed and the resources consumed.

Using Perfmon

The two statistics that you need to measure are:

  • Process private bytes

  • Process handle count

Using Task Manager

The two statistics that you need to measure are:

  • Virtual memory size (this is another name for private bytes)

  • Handle count

These can be selected from Select Columns... under the View menu.


Lesson 3 - Attaching to a program

Once you have discovered that your program leaks and you have installed Leak Browser you will want to start using it to hunt for those leaks. To do this start Leak Browser, and select New Report from the File menu:

You will be presented with a dialog similar to this:

Select a process that you want to generate a report for. A test program LeakTester.exe is provided to help you get started, it has several leaks in it, try running LeakTester.exe and attaching to it. There will be a delay while Leak Browser attaches to the process, loads the debug symbols and generates an initial report. Here is an example initial report:


Lesson 4 - Hunting for leaks

The report that Leak Browser generates will show you the code responsible for the increase in resources illustrated by the pink area of the graph below.

  • First wait for Leak Browser generate the initial report:

  • Next [step 1] perform the operation that causes your program to leak. To ensure that your program has done all one-time initialization perform this operation a few times.

  • Press the record button: [step 2]

  • Pick a small prime number (3, 5, 7, 11, 13), this is the number of iterations of your program that you are about to perform. Set "min cycles" equal to the number of iterations that you are to perform, or increase "min cycles" by one as you perform each iteration.

  • Perform a few iterations of the operation that causes your program to leak.

  • Keep an eye on the leak stats (labelled "Count", "Unique call sites", "Estimated size").

  • Next turn off the leak monitor, but pressing the green pause button: [step 3]

  • Perform several more iterations of your program, ideally at least as many times as when recording. This is VERY important because it is possible that some of the resources tracked when the leak monitor was on will be deallocated now. If this is the case you will see the stats values falling.

  • If the leak "Count" value non-zero press the "Update report" button: [step 4]

Warning: Reports with more than 100 unique call sites can be difficult to read. So you can apply additional filters, see "Tuning out unimportant data".

  • Next read the report!

Things to bear in mind

  • Leak Browser will tell you WHAT is leaking not WHY it is leaking.

  • FALSE POSITIVES
    It is possible that if your code has unusual allocation scheme or uses caches extensively then there will be false positives. In other words Leak Browser may sometimes report a leak where there is no leak. The advice here is to reduce the size of caches, and to increase the number of iterations. Also consider adding diagnostics messages with per class instance to C++ constructors and destructors, or to Visual Basic class initialize and terminate methods. If you manage to prove a false positive then mark the false leak as noise.

  • The reports generated can saved and viewed with LeakBrowser.exe which is redistributable (the other executables are not redistributable).

Choosing a use case

Understanding how to choose a use case is one of the most important aspects to using Leak Browser. If we took as an example a trading system that leaks each time a trade is performed then the use case would be to perform a trade.

[step 1] You would ensure that at least ONE trade had been performed BEFORE pressing record [image].

[step 2] You would perform let's say 7 trades, and then press pause [image]. Each trade being for the same stock.

[step 3] Then enter the value 7 for 'min cycles', and perform at least one more trade, depending on caching algorithms in your code more trades may be required. This allows for elimination of false positives caused by lazy deallocations. A good guide is to continue until the number of 'Unique call sites' stops falling.

[step 4] Update the report

Sometimes your program might not have a GUI. In these cases a good technique is to modify your code to display a message box after each use case iteration, so it is easy to count iterations. Let's say your application was a service that converted .doc files to .pdf, here the use case is processing a single .doc file. To repeat the use case you should use an identical .doc file for each iteration, and display a message box between iterations (using MB_SERVICE_NOTIFICATION as an argument to the message box function).

::MessageBox(NULL, "iteration", "testing for leaks", MB_SERVICE_NOTIFICATION | MB_TASKMODAL | MB_OK );

The use case may encompass as much or as little functionality as you like, however, each iteration should be as similar to the previous as possible, for example processing identical files or trading the same stocks.


Lesson 5 - Understanding reports

When Leak Browser is first attached to a process an empty report is generated. Every report contains a selection of sub-reports. Initially the focus placed on the Realtime sub-report, all the other sub-reports are empty.

Each of these sub-reports is described below. The key sub-reports are marked with a ï.

  • Leaks ï

This provides a hierarchical view of where the leaks are in your code. This is the most sophisticated and often most useful view.

  • Noise

This is a summary of the leaks that have been identified (by the developer) as not in fact being leaks. They are in effect "false positives", the format of the report is the same as for the leak graph.

  • Breakpoints

This is a list of stack traces that the user would like to generate a break point on.

  • Modules ï

This is a list of the modules loaded into the process being monitored. Various information about each module is reported. This also allows leaks from specific modules to be targeted or ignored.

  • Intercepts

This contains a list of functions that are currently hooked.


Lesson 6 - Performance tuning

Because Leak Browser monitors how your program is running it impacts speed at which your program will run. You rarely get something for nothing! When "learning mode" is enabled, Leak Browser is working as efficiently as it can with minimal performance impact. When using "learning mode", the technique to get best results is:

  1. Perform a number of iterations and generate a report with your leaks.

  2. Clear the leaks.

  3. Repeat step 1.

In "learning module" Leak Browser learns from the first report which areas of your code are most likely to leak, and then targets those areas specifically for more detailed (and slower) examination. Without "learning mode" Leak Browser examines all areas of code equally, and this is slower and a little more intrusive.

Although this is very rarely necessary you can reduce the number of categories monitored on the intercepts tab, typically the reason for this is to obtain a smaller and more clear report, reducing the number of intercepts also reduces CPU load.

The generation of leak reports is CPU intensive, so avoid generating reports with more than 100 unique call sites. Typically a report with 100 nodes is hard to understand anyway.

Ensure that you have sufficient memory in your computer. If you start running off the swap file performance will nose dive.

Ensure that you have sufficient CPU power. The display of the reports can also be very CPU intensive. A minimum 1GHz Intel Pentium III or AMD Athlon is recommended, however, good results can be obtained with 266MHz machines, and modern machines with 3GHz processes are .


Lesson 8 - Noise

Lesson 7 - Noise

(Advanced topic)

noise (noiz) noun

Computer Science, Irrelevant or meaningless data.

Let's take as an example an application that receives real time stock market price updates in the background. With such an application there may be a background level of noise generated when resources are allocated to process each new price update.

Excluding Noise

Waiting for deallocations to occur

One way to combat this background noise is to leave the leak monitor off for several minutes before generating a report, however, you may need to wait a very long time before all the background noise resources are deallocated. This is described in lesson 4 - Hunting for leaks. When background noise is present it is hard to tell how long to wait before generating a report.

Recording noise

To avoid a potentially long wait before generating a report, an alternative technique is to record the noise while the target application is otherwise idle.

When you have finished recording the noise press the green pause button. Then swap to the leaks tab and select the check box for "Remove noise".

Manually excluding noise

Upon inspection it may be obvious that some call sites are not in fact leaks but are noise. In this case these sites can be marked as noise manually.


Lesson 9 - Getting the best results

Lesson 8 - Getting the best results

Symbol files

It is most important that Leak Browser is provided with symbol files for as many modules in the process as possible. Typically symbol files are .pdb or .dbg files. When the linker generates the DLL file and the corresponding symbol file it inserts a timestamp (and/or a GUID) into both of them. These timestamps (and/or GUIDs) must match exactly for Leak Browser to load the symbol file.

By default Leak Browser will attempt to download the correct symbol files from http://msdl.microsoft.com/download/symbols. This can be configured from the Tools,Options menu.

Leak Browser uses the symbol files for several things, including

  • Instrumentation of static link C/C++ libraries

  • Generating stack traces for optimized code (using FPO tables)

  • Providing symbolic information (function names) rather than hex codes.

  • Providing file and line number information

Stack trace modes **important topic

Leak Browser uses several techniques to trace the stack as quickly and accurately as possible. The mode can be selected using the [image] button on the leaks and noise tabs.

  • EBP frame mode (fast)

  • FPO frame mode (default)

  • smart mode (experimental)

  • learning mode (two pass)

EBP frame mode is the fastest possible way to trace the stack on an x86 system. However, it does require that the EBP register has been used as a stack frame register, and often the compiler's optimizer will use this register for alternative purposes. For your application code you can simply disable the optimizer or compile with /Oy- option. However, for all the system DLLs already loaded into your process there is nothing that you can do. This mode is best when you suspect that the leaks are purely internal to your code and you are able to use a non-optimized build.

FPO frame mode is slowest because it requires to perform a search for FPO information for many frames in the stack trace. However, it works better with optimized code when .PDB files are available.

smart mode attempts to take advantage of the exception frames stored on the stack and used in conjunction with structured exception handling to unwind the stack in the face of an exception. It is able to jump over highly optimized code so even a .PDB file is not available for a critical DLL it is able to trace the stack. Currently smart mode does not use FPO information (although it is under consideration). This is experimental and not fully regression tested, however initial results have been very promising. Once regression tested this will likely become the default mode. This gives very few short stack traces although a few intermediate frames are omitted, it probably results in the most hierarchical and readable reports.

learning mode this is a two pass algorithm. It is intended for use in applications that allocate extremely frequently, which would otherwise cause the CPU load to become excessive when using Leak Browser. The first pass uses EBP frame mode which is very efficient and consumes little CPU time. The second pass uses both FPO frame mode and smart mode and selects the best results. To use learning mode first generate a report as usual, the stack traces will show "first pass" against them. Then clear the results (this is important) by pressing [image] and then [image] to record a second pass of tests. During this second pass any stack traces that are identified has having appeared in an earlier report (the first pass) are traced with both the FPO and smart methods and the most detailed results are selected.

Learning mode is able to give the best results but requires two passes.

Tuning out unimportant data

A report with a large number of nodes can be very hard to understand. Things that you can do to improve the clearity of reports include:

  • Try changing stack trace modes. If the nodes are well grouped hierarchically it is not so much of a problem. Different stack trace modes will result in different results, typically smart mode gives the bests hierarchical reports.

  • Select a larger number of minimum cycles, it is best to choose prime numbers. This will of course require that you exercise the program this number of times while recording the allocations.

  • Select a larger "min size" of allocation to report to tune out the smaller unimportant allocations.

  • Deselect some of the intercept categories. Enabling only "C/C++ runtime" will have the effect of monitoring C/C++ allocations while ignoring the lower level system calls. If the high level C++ leaks are fixed you may also fix the lower level system leaks as a welcome side effect.

  • Ignore leaks from certain system and third party modules. This can be done by selecting those modules on the modules tab, and selecting the menu option <Debug><Module Filters><Exclude leaks by "xxxxxx.dll">

  • Leave the application running longer with the green pause button selected before generating a report. This gives it longer to deallocate resources. Depending on the nature of the application this may or may not be applicable.


Callgraph sub-report

Leaks tab

The leaks tab contains a more sophisticated and hierarchical view of the leaks detected. Often if the leaks near the top of the hierarchy are eliminated then the leaks further down the hierarchy will be automatically eliminated. An example of this is if a C++ object is leaked then any member objects will show up as leaks lower down in the hierarchy. If the leak of the parent object is eliminated then the member object leaks are also eliminated.

This view helps developers target the source of the top level leaks in the code. Various details can be hidden or shown via the check boxes in the floating window.

By default the size of leaks are reported for the node and all its children. This also allows developers to target as a priority the code branches that will reduce the most leaks.

Here the leaks are shown as a hierarchical graph. However, a linear list of leaks can be displayed by unchecking the "show as graph" checkbox.


Breakpoints sub-report

Breakpoints tab

Leak Browser provides the ability to set a breakpoint when it next encounters a particular stack trace. Unlike a general purpose debugger the breakpoint is on a stack trace not on a line of code.

To take advantage of this you will need to attach a debugger to the process being monitored. The breakpoints tab provides the ability to review the list of breakpoints that have been enabled.

Here a breakpoint has been set on a single node by selecting that node on the leak graph, and setting the breakpoint from the Debug menu. Enabled breakpoints are shown by a solid red dot. A list of currently set breakpoints can be viewed in the breakpoints report. Breakpoints can be set on a whole tree of nodes.

When a breakpoint is hit the user is given the option to call DebugBreak (to trigger a general purpose debugger).


Modules sub-report

Modules tab

The purpose of the modules tab is to allow you to see what has been loaded into your process. Also to see which symbol files are in use. Since it is important that the correct symbol files are loaded the main use for this view is identifying the symbol files loaded for each module.

Symbol files have an extension of ".pdb", ".dbg", or ".sym". The symbol search path can be changed from the Tools, Options menu.

The recommended place to put the .PDB or .DBG files is the same directory as the corresponding .DLL files, or to use a "symbol server". For more information about Microsoft's symbol server look up "Debugging Tools for Windows" at www.msdn.microsoft.com. When Leak Browser first attaches to a process it attempts to load the symbols for as many modules as possible. The number of symbol files loaded is displayed in the status bar.

The message "not linked with debug info" is displayed when the module does not contain a debug section. If this is a third party component then there is nothing you can do. If you have the source code then ensure that both the compiler and linker options to "generate debug info" are selected.


Intercepts sub-report

Intercepts tab

The intercepts tab shows the functions that Leak Browser monitors. This tab shows that the Leak API and the C/C++ runtime library was being monitored. It also shows the functions that are tracked for each category. Functions that are imported by ordinal number are denoted by an @ followed by the ordinal number. If an intercept is not installed, it is usually because the relevant DLL is not loaded.


FAQ

  1. Do I need to re-compile my code?

  2. Does Leak Browser work with Visual Basic?

  3. Where should I put the symbol files?

  4. Should I install symbol files for the system files?

  5. Does Leak Browser support Java?

  6. Does Leak Browser support Scripting?

  7. Does Leak Browser support .NET?

  8. Can I avoid leaks by using garbage collection?

  9. Can Leak Browser monitor multiple processes?

  10. Can Leak Browse monitor remote processes?

  11. How much does Leak Browser impact performance?

  12. Can Leak Browser help find COM object leaks?

  13. Does Leak Browser leak?

  14. How do I detach Leak Browser from a process?

  15. Can I use a Debugger and Leak Browser at the same time?

  16. How does Leak Browser work?

  17. Are there any known bugs?

  18. How do I report bugs?

Q> Do I need to re-compile my code?

Maybe. You do need to provide symbol files. It is also advisable (but not a requirement) to use a non-optimized build. You can use a "Debug build" if you like, however, it is often better to create a "Release build" with the optimizer turned off, because this is closer to how your code will run in the field and you won't need to install special debug DLLs. Also you should use the the DLL versions of the C/C++ runtime library. You should do this for ask much code as you can. Obviously you cannot recompile third-party components, the more components that you can recompile with these settings the better results Leak Browser is likely to give you.

In short:

  • Provide symbols

  • Rebuild as much code as you can with the optimizer off

  • Use the Multithreaded DLL version (debug or release) version of the C runtime library.

If you are using Microsoft Visual C++ 5.0 or 6.0 then the following dialogs illustrate how to do this:

If you are using Visual Basic 5.0 or 6.0 then the following dialogs illustrate how to do this:

Q> Does Leak Browser work with Visual Basic?

Yes. Many programs use both Visual Basic and C++. Leak Browser will help find several types of leaks that can occur in Visual Basic, even if your Visual Basic code does not have any leaks Leak Browser can still find the leaks in the C++ parts of your code. Note that Leak Browser does not specifically target Visual Basic (yet) so there are also some leaks in Visual Basic code that it will not detect.

Q> Where should I put the symbol files?

For any code the you compile you should put the symbol files (*.pdb, *.dbg) in the same directory as their corresponding executable files (*.exe, *.dll, *.ocx etc.). For this reason it is not a good idea to have a .exe and a .dll file with the same filename. There is a special environment variable _NT_SYMBOL_PATH that gives the path to system symbol files typically this is %windir%\symbols.

Q> Should I install symbol files for the system files?

Yes, they are not essential but having all the correct symbol files certainly helps. The best place to get the system symbol files is Microsoft's symbol server www.microsoft.com/ddk/debugging/symbols.asp. You might like to search for the MSDN article "Using SymSrv".

Installing the correct symbol files will generally help you when debugging code, not just using Leak Browser.

Q> Does Leak Browser support Java?

Java is not supported. However, if the Java code is compiled to a native .exe or .dll rather than being interpreted, there is no reason why Leak Browser won't work in this environment.

Q> Does Leak Browser support Scripting?

No scripting clients are not supported. Only directly compiled clients are supported. If you use Leak Browser in a scripted environment you will see stack traces into the script interpreter. There is no way to identify which line of script was executing (without support from every script interpreter). As a general recommendation with regard to writing robust code scripting is not recommended for significant amounts of code because it lacks so many safety features that compiled languages offer.

Q> Does Leak Browser support .NET?

No. However, it should still support unmanaged code. This is currently under review.

Q> Can I avoid leaks by using garbage collection?

No. You can reduce the amount of leaks using garbage collection, how much in our experience is very variable. Leak Browser was initially written to identify leaks in a project where one of the world's leading garbage collectors had failed badly (it found less than 1% of the leaks). The key problems with garbage collection are:

  • Most garbage collectors do not track all allocations.

  • An unintended reference to an object will defeat a garbage collector.

  • There are also the issues concerning the cost of garbage collection.

Typically garbage collectors are concerned with calls to new, delete, malloc, free, etc., but we have found that this is not where most leaks occur. What about all those operating system calls like SysAllocString, or CreateEvent? Do you always remember to call SysFreeString or CloseHandle? Do you always use smart objects to encapsulate access to these operating system object? The problems mostly occurs because the Win32 exposes most of its APIs with a "C" interface. This is not very suitable for either C++ or Visual Basic, indeed it is only really suitable for "C", and it is at the "language interface" boundaries that most programmers make mistakes. What is needed is a native language wrapper on top of the "C" interface. This is part of what the .NET framework attempts to do (how well remains to be seen).

If you write code in 100% portable C/C++ and thus don't make operating system calls directly, and if you do not use multiple languages, then a garbage collector may be right for you.

There are a number of times that we have found objects being added to collections but never removed until application shutdown. This results in the collection growing and growing, until the application is eventually shutdown (probably because it is out of memory). To a garbage collector this is not a leak because all objects are still reachable. To your customer it is a leak, because the application eventually slows down and/or crashes.

If you are using a garbage collected language e.g. Java, then your code may not leak, but if the virtual machine implementation leaks, then your customers are no better off. (Most of the leaks in Netscape Communicator come from the Java virtual machine.)

Q> Can Leak Browser monitor multiple processes?

Yes. Just attach to the processes you want to monitor (one at a time), and then use the MDI interface to switch between the windows for each process. You can run multiple copies of Leak Browser, but this will take more memory.

Q> Can Leak Browser monitor remote processes?

Yes. However, you must be an administrator of the remote machine, and an ADMIN$ share must exist on the remote machine. The ADMIN$ share is a standard hidden share that windows uses to expose the windows directory to the network.

Q> How much does Leak Browser impact performance?

How long is a piece of string? If your program does nothing but call new and delete then Leak Browser will have a huge amount of work to do. However, it can be easily configured so that its impact is minimal, as a simple rule the more that you monitor the slower your program will run. See the section about performance tuning.

Q> Can Leak Browser help find COM object leaks?

COM objects are not specifically tracked. Most COM objects use memory, and that memory must be allocated. Since Leak Browser tracks memory allocations it will track COM objects that use any of the memory allocators that are tracked. Most COM leaks are due to either bad reference counting (forgetting to call Release) or cyclic references. Once you have used Leak Browser to find the COM object that is leaked you will usually need to manually work out which client has forgotten to call Release.

Q> Does Leak Browser leak?

Not where it is important not to. The key part of Leak Browser that runs in your process has been carefully written not to leak. It even includes some self monitoring code. The Leak Browser user interface is another matter. It uses a lot of web technology which is known to leak. This is not seen as a problem. Because the user interface is stateless you can close the Leak Browser GUI, and later re-attach to the same process and pick up where you left off.

Q> How do I detach Leak Browser from a process?

You cannot. Once attached Leak Browser will constantly monitor that process until it terminates. Even if you close the Leak Browser GUI the process(es) that have been attached to will continue to gather leak information. The closest that you can come to detaching from a process is to deselect all leak categories, and turn the leak monitor off. This will reduce the performance impact to your process to nearly zero.

Q> Can I use a Debugger and Leak Browser at the same time?

Yes. Indeed this is a specifically supported debugging technique. You can use Leak Browser to set a break point on a particular stack trace, and then use the debugger to better understand why the code that Leak Browser reports a leaky leaks.

Q> How does Leak Browser work?

In very simple terms: Leak Browser injects into your process, instruments your code in memory, and monitors calls to various functions. While the leak monitor recording it tracks allocations and deallocations, when the leak monitor is paused it still tracks deallocations.

Allocations that have not been freed are considered to be leaks. That is why it is important to run through a few cycles of your application with the leak monitor on, and then a few cycles with the leak monitor off. This may all sound simple - but implementing it is not!

Q> Are there any known bugs?

  1. Occasionally a "switch / retry" message box appears on the Leak Browser application. This usually means that the "Leak Browser Service" is no longer responding. Solution: on the target machine run the command:

C:\> net stop "Leak Browser Service"

Then launch Leak Browser again and re-attach to the process that you were debugging.

Q> How do I report bugs?

Logon to www.leakbrowser.com and use the forums and/or contact page to bug a bug.


Source code view

A syntax highlighting dockable source code view is available to navigate the code. To navigate to the source code simply single click on the source code link in the report.

Sometimes the line number reported is the line immediately after the leak. This is normal for debuggers.

The source view can be docked, hidden or left floating.

The source code search path can be configured from the tools menu:

In the example above assuming that the source file identified in the leak report is "d:\leakbrowser\leaktester\call_graph_tester.cpp". Then LeakBrowser will attempt to load "call_graph_tester.cpp" from the following paths:

    1. d:\leakbrowser\leaktester\call_graph_tester.cpp <path in symbol file>

    2. c:\program files\leak browser\data\call_graph_tester.cpp <path of report file>

    3. c:\program files\leak browser\data\leakbrowser\leaktester\call_graph_tester.cpp <path of report file>

    4. k:\program files\microsoft devstudio\vc98\mfc\src\call_graph_tester.cpp

    5. k:\program files\microsoft devstudio\vc98\mfc\src\leakbrowser\leaktester\call_graph_tester.cpp

    6. d:\my source\call_graph_tester.cpp

    7. d:\my source\leakbrowser\leaktester\call_graph_tester.cpp

If it cannot be found in any of these places the user is prompted to locate the file.


Tips

  1. Target leaks in the order easiest first. Typically the easiest categories of leaks to find are C/C++ and Win32 handles, followed by Win32 Allocs and COM strings.

  2. Immediately you find a leak fix it, have a quick look for similar or related leaks in the code. Then retest. Fixing leaks immediately they are found improves the signal to noise ratio when testing.

  3. If you can, use non-optimized builds (see FAQ - re-compiling)

  4. Ensure that you have as may symbol files available as possible (including those for the operating system).

  5. Use Microsoft's symbol server (and provide a local download cache), and include the symbol server on your symbol path (under Tools, Options).

  6. First look for leaks without Leak Browser attached (using task manager and/or perfmon).

  7. Configure the source code search path to match where your libraries are installed.


Trouble shooting

Internet Explorer configuration

Leak Browser's reports are web pages. You need to ensure that your web browser allows the pages on the "Local intranet" to download and run unsigned ActiveX controls, also scripting must be enabled.

Be careful not to accidentally enable these settings for the "Internet" zone.

Also some versions of Internet Explorer have problems with XSL processing. Please use Internet Explorer 6 with service packs.

Startup problems

Depending on the speed of your machine and various other factors you may encounter the following dialog. Usually pressing "Retry" will work, although you may need to wait up to 30 seconds before pressing "Retry" for it to work.

If after waiting 30 seconds the problem persists, then stop the Leak Browser service.

C:\> net stop "leak browser service"

Use task manager to close or terminate Leak Browser, and then launch Leak Browser again.

If this fails, reboot.

Attaching problems

If Leak Browser fails to attach to your process, try again.


Revision History

Version 3.0 | Major ease of use improvements. Removed various experimental incomplete and little used functionality.
Version 2.1 | Integrated a source code viewer. Added ability to save a .zip archive of the reports generated. Uses compressed HTML help. Added MDI interface. Various usability improvements.
Version 2.0 | Massive rework. The instrumentation no longer requires the .exe file to be modified. The interface is web based. Enhanced function interception. Remote debugging supported. Non-intrusive handle monitoring. Support for noise filtering. Several sub-reports added.
Version 1.x | This was a dialog based application. It required that the .exe file was instrumented prior to running. The output was simple text, containing similar output to the stacks sub-report of version 2.x.


Developing Leak Browser

This section is "for interest only". If you are using Leak Browser you are probably a software developer, so we thought that you might like to know what some of the ingredients that are in Leak Browser. The following libraries were used to develop Leak Browser:

  1. Boost boost.org

  2. CodeMax 2.0 by Barry Allyn winmain.com

  3. Code Jockey v6.0 codejock.com

  4. WFC - Win32 Foundation Classes release 50 by samblackburn.com

  5. Various code from CodeProject

  6. Various code from CodeGuru

  7. Various code from MSDN Magazine (formerly MSJ)

  8. Header files from "Undocumented Windows NT" ISBN 0-7645-4569-8 CD IDG Books

  9. Microsoft ATL

  10. Microsoft MFC

  11. Microsoft WTL

  12. Microsoft Platform SDK

  13. Microsoft Internet Explorer Control

  14. Microsoft XML library

  15. Microsoft NT DDK

Leak Browser was mostly written in C++, there is also some assembler, XSL, Visual Basic, DHTML, and Java Script.


Writing better C++

A quick quiz

Q> You need to allocate a temporary buffer of 'n' bytes. How would you do this?

Possible answers (click here):

If you or your colleagues gave any answer other than the last, then you will probably have many leaks in your source code.

Typically in a development life cycle, the code is written and then it is debugged. There are always bugs, and they are always require more skill to remove than to insert. If your answer to the quiz was not the last answer then you may struggle to find the bugs in sophisticated code. Leak Browser will help, but in the end it is your level of skill that counts.

Pointers

"Poi nters are the goto's of data"

You probably don't use goto's and labels in your source code. There is never a good use for this type of spaghetti code. However, you do probably use pointers. Raw pointers are dangerous, because they do not imply ownership rules, they allow mathematical operations to be performed on memory addresses (leading to off-by-one errors and buffer-over-runs), and they can be null.

Between smart pointers and references you almost never need to directly use raw pointers.

Here are some (incomplete) guidelines for when and when not to use pointers.

  • If a reference (or const reference) can be used instead of a pointer then prefer to use a reference. This is often the case when a pointer would otherwise be used to pass an object [in] to a function.

  • Prefer std::string to char *.

  • Prefer std::vector for dynamic buffers (over new[] and delete[] ).

std::vector<char> v(10); // allocate a vector of ten characters

function_requires_char_pointer(&v[0]); // use address of zero'th element

  • Try to use smart pointers instead of raw points. Smart pointers make the ownership and lifetime of an object clear.

  • Understand the following two classes, the difference between them, and when to use them:

std::auto_ptr<T>
boost::shared_ptr<T>

  • If an object is being passed [out] of a function then a reference should be preferred, or possibly return by value (if the object is not large). This requires that the object has a cheap default constructor, and in the case of return by value a cheap copy constructor also. Also, the name of the function should make it clear that it will modify one of its arguments.

  • Use a pointer when it is reasonable that the object may not actually exist, in which case NULL can be used. If the object always exists use a reference.

  • If object can be assigned or copied, then a reference cannot be used as a member variable.

  • If you are using Microsoft's COM, learn to use the smart pointers in atlbase.h and comdef.h:

ATL::CComPtr, CComQIPtr, CComBSTR
_com_ptr_t, _bstr_t
and #import

Also learn and understand the deficiences in these classes. Most problems occur at the boundaries, between components, between types (e.g. BSTR to _bstr_t), or the boundaries between COM and C++. Try to be consistent in usage of these classes.

Most of the problems comes down to poor language bindings. For example there is no good language binding between a SafeArray and std::vector. This is not a lacking of C++, it is down to the vender of COM (i.e. Microsoft) to provide a good language binding. This is being addressed (some what) with .NET.

  • Avoid inserting raw pointers into STL collections. This is a common source of problems. A common alternative to using pointer in collections is shown below:

std::collection<T*> my_collection;

is this:

std::collection< boost::shared_ptr<T> > my_collection;

Many Microsoft smart objects cannot be direct ly inserted into STL collections. This is because they overload the '& operator'. This is problematic. It can be solved by either creating your own smart pointer, wrapping Microsoft's pointer in the boost::shared_ptr, or using an adapter to redefine the 'operator &' correctly (it should return a pointer with the same type as this).

Recommended reading

The best way to improve you C++ is to read some of the book from the recommended reading section. If you do this you will find that it is possible to write high quality code with very few (if any) leaks.


Writing Better Visual Basic

Leak Browser does not specifically target Visual Basic (yet) so there are also some leaks in Visual Basic code that it will not detect. Leak Browser will detect when Visual Basic code leaks an operating system resource or a C++ resource.

What Visual Basic is best at is GUI related code, it also integrates with COM reasonably well. Trying to use Visual Basic for infrastructure type code can lead to messy code, primarily because it lacks expressiveness often required for this type of code.

There are three types of leak that primarily occur with Visual Basic.

1. Cyclic references

In GUI code, it is common for a form to contain a control or other COM object. The form maintains a reference to the object (by way of a member variable) and the object maintains a reference to the form (via 'with events'). This leads to cyclic reference counting, the cycle must be broken, or both the form and all its members will be leaked. In the case of controls (objects with a GUI) the act of unloading the form automatically disconnects the event interface. However, for COM objects without a GUI that fire events, when the form is unloaded the developer must remember to the member to 'nothing'.

Private WithEvents m_objIxm As clsInstrument

Public Sub SomeStartupRoutine(TheIxm As clsInstrument)
  Set m_objIxm = TheIxm
End Sub

Private Sub m_objIxm_OnUpdate()
  ' do something
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Set m_objIxm = Nothing ' <--- Do not forget this, or things will leak!
End Sub

2. External resources

The Win32 APIs are mostly written in 'C', and do not provide good language bindings to Visual Basic (C++ also suffers when it interfaces to C interfaces). When a Visual Basic developer needs to call a C function like CreateEvent the developer is often distracted by the issues with interfacing to C functions.

The developer may forget to call CloseHandle in all the right places for example within an "on error goto" error handler. Also concepts like smart pointers or "auto handles" are not available in Visual Basic (this is one reason why it is not suitable for infrasture programming). Thus Visual Basic developers need to be especially careful when using Win32 APIs that allocate resources.

3. Programmed leaks

It is possible to continuously add objects into an array or collection, and never remove them. This is also a leak.


Quiz answers

unsigned char buffer[n]; | Sorry, you really need some training. This is not (currently) legal C++ (although it is legal C99).
unsigned char * buffer = malloc(n); | Sorry, you need to learn C++. You are currently a C programmer, C++ is a very different language, although it does support much of C. You really ought to program using C++ concepts where possible.
unsigned char * buffer = new unsigned char[n]; | Okay, this is C++, but you really need to learn and use modern C++ (this is pre 1995 style). Learn to use STL.
std::vector<unsigned char> buffer(n); | Great, you are a C++ programmer.