ACE LogoThe Windows development environment provided by VisualStudio has some neat tools for detecting memory leaks in code. You simply #define _CRTDBG_MAP_ALLOC before including your headers, and #include <crtdbg.h> as the last header:

#define _CRTDBG_MAP_ALLOC
// Include other header files here
#include <crtdbg.h>

Then, you call _CrtDumpMemoryLeaks() before your application exits. If your program exits at many points, you can alternatively call _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ) at the beginning of you application, which will cause the leaks to also be printed when it exits. The results are printed to the Debug Window and look like the following:

Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : 
{18} normal block at 0x00780E80, 64 bytes long.
Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.


Cool, Huh?! However, some libraries don’t play nice with this, as I explain below.

Memory Leak Detection and ACE:

I’ve mentioned ACE before in a previous post evaluating portable runtime environments. It’s a pretty cool set of libraries that provides a portable OS abstraction layer and communication environment. If you write your application using ACE, it will compile and run on a whole host of system types… but I digress.

One problem with ACE is that it conflicts with the Windows leak check code. If you define _CRTDBG_MAP_ALLOC before the ACE headers, you will get build errors like the following:

1>..\include\ace\os_ns_unistd.h(154) : error C2059: syntax error : 'constant'

What’s happening is that the ACE headers try to enable the leak detection code themselves, which causes the overridden memory functions to conflict with the original versions. In essence, ACE is trying to define malloc (for example) after crtdbg.h has already overridden it.

So, how do you get your application to build with leak detection and ACE? Define _CRTDBG_MAP_ALLOC after the ACE headers (Remember: the ACE headers must always be included before other headers… another complaint I have).

#include "ace/ACE.h"
#define _CRTDBG_MAP_ALLOC
// Include other headers here
#include <crtdbg.h>

Okay, your application should compile now. Run it and look at the output window. For a simple application that does nothing but return, this is what I see:

Detected memory leaks!
Dumping objects ->
{178} normal block at 0x00CDBD78, 50 bytes long.
Data: <---TEST---      > 2D 2D 2D 48 45 4C 4C 4F 2D 2D 2D 00 CD CD CD CD
{173} normal block at 0x002EAAC8, 8 bytes long.
Data: <  .     > C0 A1 2E 00 CD CD CD CD
{172} normal block at 0x002EAA78, 20 bytes long.
Data: <4  Z       Z    > 34 90 F3 5A 0A 01 00 00 F3 17 DA 5A 03 00 00 00
{171} normal block at 0x002EAA18, 32 bytes long.
Data: <   Z  ]         > C4 91 F3 5A C0 FB 5D 00 FF FF FF FF 00 00 00 00
{170} normal block at 0x002EA9B8, 32 bytes long.
Data: <   Z  ]         > C4 91 F3 5A 88 FB 5D 00 FF FF FF FF 00 00 00 00
{169} normal block at 0x002EA958, 32 bytes long.
Data: <   ZP ]         > B4 91 F3 5A 50 FB 5D 00 FF FF FF FF 00 00 00 00
{168} normal block at 0x002EA910, 8 bytes long.
Data: <   Z    > D4 91 F3 5A 00 00 00 00

... Truncated for sanity (30 more leaks follow) ...

Object dump complete.
The program '[14288] simple.exe: Native' has exited with code 0 (0x0).


These are very likely false-positives, but they are annoying. There are other problems too:

  1. There are no file/line numbers printed, so we can’t track down the code to verify if the errors are real or not.
  2. File and line numbers don’t show up for errors outside of ACE (the first leak is mine).
  3. All this output adds noise that can hide other memory leaks (I wish Microsoft would add a way to suppress errors we don’t care about… props to Valgrind for doing this).

Anyways, all of this is quite frustrating. I was hunting around on the ACE newsgroup for solutions and could only find this thread:

“In general, we track memory issues on Windows using Purify, so you might try going that route.”
Douglas Schmidt

“Correct. This memory tracking scheme and the ACE restrictions onheader file placement are at odds here. You have two choices:

1. Use a different memory tracking scheme such as Purify, which Doug
suggested.

2. Develop, or sponsor, necessary changes to remove ACE’s restrictions
on header file placement.”
Steve Huston

So there you have it: ACE and Window memory leak detection don’t play nice together. I hate encountering a problem without a viable solution… it bugs me (no pun intended). I even tried modifying the ACE headers with marginal results (it came close to compiling). Oh well…

Tagged with:  

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>