9

I want to find memory leaks in my application using standard utilities. Previously I used my own memory allocator, but other people (yes, you AlienFluid) suggested to use Microsoft's Application Verifier, but I can't seem to get it to report my leaks. I have the following simple application:

#include <iostream>
#include <conio.h>

class X
   {
   public:
      X::X() : m_value(123) {}
   private:
      int m_value;
   };

void main()
{
X *p1 = 0;
X *p2 = 0;
X *p3 = 0;

p1 = new X();
p2 = new X();
p3 = new X();
delete p1;
delete p3;
}

This test clearly contains a memory leak: p2 is new'd but not deleted.

I build the executable using the following command lines:

cl /c /EHsc /Zi /Od /MDd test.cpp
link /debug test.obj

I downloaded Application Verifier (4.0.0665) and enabled all checks.

If I now run my test application I can see a log of it in Application Verifier, but I don't see the memory leak.

Questions:

  • Why doesn't Application Verifier report a leak?
  • Or isn't Application Verifier really intended to find leaks?
  • If it isn't which other tools are available to clearly report leaks at the end of the application (i.e. not by taking regular snapshots and comparing them since this is not possible in an application taking 1GB or more), including the call stack of the place of allocation (so not the simple leak reporting at the end of the CRT)

If I don't find a decent utility, I still have to rely on my own memory manager (which does it perfectly).

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • This is the problem with such tools - they do everything except what we really need... Is CRT memory leaks detection OK for you, including allocation place in the code, but without call stack? In this case you only need to redefine new operator and turn on memory leaks dump. – Alex F Jun 02 '10 at 08:05
  • 1
    Problem is that I have a perfectly working, self-written, memory allocator that's quite fast, logs all memory allocations including call stacks, report leaks (including call stack) at the end of the application, checks for buffer overflows/underflows, ..., BUT everyone (on StackOverflow) seems to indicate that you MUSTN'T write your own memory manager as the standard one of the CRT/Windows is good enough, and there are enough utilities to find memory leaks, overwrites, ... However, I can't seem to get them working. – Patrick Jun 02 '10 at 08:12
  • 1
    I also think that memory leaks detection is not a reason for writing your own memory allocator. CRT gives everything except stack trace - if you are interesting, I can post you the code. – Alex F Jun 02 '10 at 08:25
  • @Alex, leak detection is not the only reason. It's also buffer overflows/underflows, easier finding memory corruptions, ... I'm trying to find standard alternatives for all the things that I'm currently doing myself and leak detection is only one of them. And of course I'm interested in your code. Can you post it please? – Patrick Jun 02 '10 at 08:48
  • Application Verifier doesn't find heap leaps in an exe. It says so in its documentation. It will find Heap corruptions (ie, double deletes) as well as other issues though so depending on your problems it can be useful. – StarPilot Jun 18 '12 at 16:35
  • It can now. "The latest version of Application Verifier can diagnose heap leaks on Windows 7" http://msdn.microsoft.com/en-us/library/windows/desktop/dd744766%28v=vs.85%29.aspx – Jon Jul 25 '14 at 00:22

7 Answers7

4

CRT memory leaks detection (without stack trace):

// debug_new.h
#pragma once

#include "crtdbg.h"

#ifdef _DEBUG
#ifndef DEBUG_NEW
#define DEBUG_NEW   new( _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

All .cpp files:

#include "debug_new.h"

...

// After all other include lines:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

...

Write this once in the program initialization code:

_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

In MFC, all this is already implemented in MFC headers. You only need to ensure, that every cpp file contains these lines:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Restrictions: this catches only "new" memory leaks, all leaks, caused by another functions, like malloc, are not caught.

Don't make any allocations inside of .h files - they will be printed without source lines, because DEBUG_NEW is defined after all #include lines.

Scott 混合理论
  • 2,263
  • 8
  • 34
  • 59
Alex F
  • 42,307
  • 41
  • 144
  • 212
  • 1
    This trick doesn't work for malloc/free. One of the include files of the CRT does something similar with MALLOC and FREE (#define free DEBUG_FREE or something like this), and this gives problems with classes that have a method called free (e.g. in Qt). Also, this also writes out the memory leaks, but without call stacks, and I really need the call stacks. – Patrick Jun 04 '10 at 09:00
4

Application Verifier only catches leaks in DLLs. Try to read the tooltip in the leak checkbox. That's what it says.

1

Memory Validator from Software Verification will catch memory leaks, and show the complete callstack from the leak's allocation. While it is a commercial product, it has a trial period so programmers can try it and see if it is worth the price to them.

StarPilot
  • 2,246
  • 1
  • 16
  • 18
1

I have a feeling that Application Verifier special cases the exit path and doesn't flag these as leaks - after all, the entire process heap is free on process exit.

Try writing another sample where you initialize the same pointer again - basically lose the reference to the previous allocation. That should certainly be flagged. Let me know the results.

Also, AppVerifier (if you have all the options enabled) should also catch buffer overflows, underflows, writing to stack locations marked RO etc.

Alienfluid
  • 326
  • 1
  • 3
  • 11
  • BTW, also try the "Global Flags" utility that comes with the Debugging Tools for Windows in the Windows SDK. It has a bunch of options for heap tagging etc. and it might be what you need. – Alienfluid Jun 04 '10 at 00:41
  • 1
    I tried setting the pointer to 0. Nothing reported in Application Verifier. Tried using GFLAGS to enable all memory-related flags. Nothing reported. It seems that it is simply impossible to get memory leaks at exit (except for the very minimal leak-reporting in the CRT). Seems I have to stick to my own memory manager. – Patrick Jun 04 '10 at 07:46
0

Application Verifier is not the right tool for this job, but I still recommend you have the Application Verifier checks enabled. The equivalent on Windows is UMDH (User Mode Dump Heap), which is a command line tool.

A former colleague of mine wrote UMDH Gui for at least some usability.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
0

Visual Leak Detector (v2.2) is more useful than the CRT Debug Library because it will show the complete callstack used for memory allocation has led to the leak.

philipvr
  • 5,738
  • 4
  • 32
  • 44
-1

The simplest solution is not to write the leaks or the buffer overflows in the first place - detecting them after the event is really a waste of effort. In my own code, for years I have had zero problems in these areas. Why? Becauase I use the mechanisms that C++ provides to avoid them. For example:

X *p1 = 0;
p1 = new X();

should be:

shared_ptr <X>  p1 = new X();

and you no longer worry about p1 leaking. Better still, don't use dynamic allocation at all:

X x1;

For buffer overflows, always use types like std::string which will grow on input, or if they do not grow will detect the possible overflow and warn you.

I'm not boasting about my prowess in avoiding memory leaks - this stuff really does work, and allows you to get on with the much more difficult task of debugging the business logic of your code.

  • 6
    Many unfortunate souls have to deal with legacy code (untested ugly c stuff) and cannot afford to rewrite everything. – Sascha Jan 15 '15 at 10:40
  • 2
    The question asks for tools to detect memory leaks and the answer begins with "_detecting them after the event is really a waste of effort_". The same could be said of the last statement "get on with the much more difficult task of debugging the business logic of your code" -- Why not write code that does not need debugging of your business logic? Clearly the OP's example was contrived to demonstrate a case of leaking code and was a question reg. how to detect it. Of course it is trivial to correct the code. – Happy Green Kid Naps Dec 08 '15 at 21:56
  • 3
    The answer is completely oblivious to the real world, where memory leaks are present, and need to be weeded out. Like @Sascha said, it is one thing to write new code and it is another thing to maintain existing code. – Happy Green Kid Naps Dec 08 '15 at 21:59