MemCheck tutorial: find memory leaks

Hunting memory leaks is the main use and the initial motivation for MemCheck: in 1994, our project was on a reasonable size (about 1000 classes in 150 000 lines of code); yet we discovered that it consumed more and more memory as it was being used, due to memory leaks (this was on Turbo Pascal).
Thinking about it, we decided that it was not difficult and could be funny to write our own memory manager which would log each memory allocation and deallocation, to find out how much was lost. That was the basic idea. The very first version just reported something like "hey, there were 56 allocations which have not been freed, leading to 996 bytes lost" (ok, I won't say here how much it really reported the first time we ran it on OptIt - just that today we know for sure there are no memory leaks in the parts of the code we actually use).
Ok, let's go for a short demo of what MemCheck can do now...

  1. Launch Delphi
  2. In tools/Debugger options, ensure "stop on Delphi exceptions" is checked
  3. File/New application
  4. Close Unit1 without saving (this will be a formless app)
  5. Add the memcheck unit to the project
  6. In the project dpr file, just above the begin end, insert:
        procedure Leak;
            begin
                TObject.Create;
            end;
  7. In the project's dpr file, make the body (begin...end part) contain
        begin
            MemChk;
            Leak;
        end.
  8. Go to Project/Options/Compiler. Set everything for debugging (no optimization, stack frames, all debugging)
  9. Go to Project/Options/Linker. Include TD32 debug info.
  10. Build all
  11. If you run in the debugger, the program will execute and on termination, Delphi will show you where the leak is by raising an exception on the buggy line (this is the user interface of MemCheck: we just use Delphi itself !). The text file is less useful in this case.
  12. If you run outside the debugger, you'll use the text file to understand the leak (see below - in fact, today even with the debugger I prefer to use the text file).
  13. OK, let's improve a little... Add another procedure
       procedure CallLeak;
            begin
                Leak;
            end;
  14. In the project's dpr file, make the body (begin...end part) contain
       var
    i: integer;
       begin
            MemChk;
    for i:= 1 to 5 do
                CallLeak;
        end.

Reading the text file

In the example above, the text file tells you...

Get the call stack information in the debugger

Again, this was written before the debug info was available in the text file. So today this is less useful.

  1. Run the example above
  2. The debugger tells you there is a leak in the routine Leak
  3. Press Ctr-F7 and evaluate the global boolean variable ShowCallStack (it is defined in MemCheck). Change it to True.
  4. Press F9. The debugger shows you the calling line. You can go on seeing the stack...

 




Last update: March 2001