views:

898

answers:

5

I've got a Win32 C++ app with a suite of unit tests. After the unit tests have finished running, I'd like a human-readable report on any unfreed memory to be automatically generated. Ideally, the report will have a stack with files & line number info for each unfreed allocation. It would be nice to have them generated in a consistent order to make it easy to diff it from one run to the next. (Basically, I would like the results of valgrind --leak-check=full, but on windows).

I've had success with UMDH getting this kind of info from running processes, but that tool only seems to work if you attach to an existing process. I want this to happen automatically every time I run my unit tests.

Is there a tool that can do this? If so, how do I use it?

Thanks!

+1  A: 

If you're using MSVC, Microsoft's Debug heap functions can be used to generate the report you want, but it may not be as automatic as you'd like (you may need to write some custom code):

_CrtSetReportMode
_CrtSetReportFile
_CrtMemState    
_CrtMemCheckpoint
_CrtMemDumpStatistics
_CrtSetReportFile
_CrtSetDbgFlag
Michael Burr
You turn on too many of these in a larger project and things slow down to a crawl
Harald Scheirich
+4  A: 

To obtain this sort of information, we override new/delete and malloc/free, providing our own heap implementations that store stacktraces on allocation and produce a report when the heap is destroyed (as well as adding sentinels to detect buffer overruns).

This is a fair bit of work the first time you do it. This guy has written a freeware tool that handles all the hard bits - I have not tried it out myself, but his explanation of how he wrote it is useful when rolling your own.

moonshadow
A: 

You can define DEBUG_NEW and that turns on some leak detection, you need to define it before including any system include files. It only checks for leaks using the new operator and of course you must recompile your code so you can't attach it like valgrind.

See more info here:

http://msdn.microsoft.com/en-us/library/tz7sxz99(VS.80).aspx

KPexEA
doesn't DEBUG_NEW only work for MFC?
Clay
A: 

I did this once, but it wasn't quite as automatic. I don't have access to that code now, but here's the idea:

I used the debug functions that Mike B has mentioned (btw, they only work in Debug).

The tests runner ran all tests twice, because during the first run memory is allocated for globals. The second time, the total number of allocated blocks was checked before and after each test (I think you can do it in setUp() and tearDown()). If the number was different, it meant a memory leak, and the test failed with an appropriate message. Of course, if the test itself fails, you should preserve its error message. Now to find the leak, I had to read the block allocation number of the last allocation using pBlockHeader, then set a breakpoint on it using _CrtSetBreakAlloc and run again.

More on this here: http://levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/

Lev
A: 

I played around with the CRT Debug Heap functions Mike B pointed out, but ultimately I wasn't satisfied just getting the address of the leaked memory. Getting the stacks like UMDH provides makes debugging so much faster. So, in my main() function now I launch UMDH using CreateProcess before and after I run the tests to take heap snapshots. I also wrote a trivial batch file that runs my test harness and then diffs the heap snapshots. So, I launch the batch file and get my test results and a text file with the full stacks of any unfreed allocations all in one shot.

UMDH picks up a lot of false positives, so perhaps some hybrid of the CrtDebug stuff and what I'm doing now would be a better solution. But for right now I'm happy with what I've got.

Now if I just had a way to detect if I was not closing any handles...

twk