memory leak detecting in C++ with/without Visual Leak Detector
Asked Answered
P

7

8

I want to detect memory leaks of my C++ program in Windows. I read the documentation also on MSDN about mermoy leak detection and I also started using Visual Leak Detector.

I have a doubt about the reporting of the leaks. I am expecting a file name with a line number, but I am always reported the text below. It has all the component of a leak description ( block type, memory address, data, etc..) except for the file name and the line number.

If it is a real leak? If yes do you know why the file/line are not reported? In the meantime I am having a look also at this url

Thanks

Detected memory leaks!
Dumping objects ->
{4723} normal block at 0x04AFB5B8, 8 bytes long.
 Data:  2C 3F 00 00 28 3F 00 00 
{1476} normal block at 0x04AC3B58, 12 bytes long.
 Data:  00 CD CD CD EB 01 75 4C CA 3D 0B 00 
Object dump complete.
Punctuality answered 25/8, 2010 at 9:45 Comment(3)
flipcode.com/archives/How_To_Find_Memory_Leaks.shtmlNitid
This is off-topic but I was advised before to use smart pointers to avoid manual memory management and memory leaksPrearrange
You should use deleaker. it must help you.Illconditioned
S
7

I investigated quite some different ways of tracking memory leaks. They all have their advantages but also their disadvantages.

To understand their advantages and disadvantages, we have to understand the different mechanisms and requirements:

  1. How are new, delete, malloc and free intercepted? Some tools use #define to redefine new, delete, malloc and free, but this relies on the correct order of the include files, and may give problems if a class contains e.g. a method called free (as is the case in Qt). The preprocessor will also redefine this method, which may lead to compilation errors or unresolved externals.

    Another way is to overrule the global new and delete operators. This is a much cleaner solution, but fails is you have a 3rd party library that puts a new in the library, but the delete in the header (or vice versa).

  2. How is the source of the call determined. If new,delete,... are intercepted using #define's, often the preprocessor symbols __FILE__ and __LINE__ are uses to get the source of the leak. However, if you have 'generic' functions in your code like e.g. CreateString(), then most of the leaks will be reported in these generic functions, which does not really help you.

    An alternative is to get the call stack at run time. It can be quite easily done using the Windows StackWalk function, but in my experience, this is very very slow. A much faster alternative is to get the base-pointer directly, and to rely on the stack-frame-pointers (you must compile with /Oy- to get the stack-frame-pointers). You can get the frame (base) pointer like this: _asm mov DWORD PTR [FramePtr], ebp. Then simply loop and in the loop get the instruction pointer from ((ADDR *)FramePtr)[1]; and the next frame-pointer fromFramePtr = ((ADDR *)FramePtr)[0];

  3. How to report the leaks at the exact moment. In my case, I want the leaks to be reported at the end of the application, but to be able to do this, you need a leak-reporting mechanism at the end of your application. This means that if you want to report your leaks yourself, you need to rely on global variables being destructed at the end of your application (and report the leaks in ths destructor of the global variable). For server-type applications, you are probably more interested in getting the difference in memory usage between two points in time.

And now the different leak-systems:

  1. C RunTime: reports leaks at the end, but has no decent way of reporting call stacks. Its method of intercepting calls to new,delete,... may cause problems in combinations with 3rd party libraries (like Qt, Boost, ...)

  2. External Microsoft utilities (like GFlags, UMDH,, ...): they seem to be able to only log differences between two points in time. However, the call stack seems to be much better, although the GFlags utility may set flags in the OS that may cause a serious slowdown of your application.

  3. Visual Leak Detector. Seems to correctly find all leaks, but in my case it doesn't work since I have a 3rd party DLL that simply aborts the process at its DllUnload (seems to be a Windows 7 specific problem).

  4. My personal favorite (and people will not agree with me, I'm sure), is to write your own memory manager. Intercepting can be easily done using global new and delete operators (with the possible problems mentioned above), and you can get the call stack as described above. This alternative also relies on being able to have code that is executed at the very last moment in your application.

When choosing an alternative, I found the following aspects very imporant for my situation:

  • I want it to work seemlessly in my application, so that every developer is notified immediately if there is a leak. If you delay leak-checking to a later moment where you use external utilities like Purify, leak-finding will be much harder.
  • I want leaks to be reported at the end of the application, automatically.
  • I want as much as possible information from the leak (the data, the call stack, ...)

Hope this helps.

Shirker answered 25/8, 2010 at 11:26 Comment(0)
W
5

This is the output from Visual Studio's own debug CRT, not the output from Visual Leak Detector. Firstly ensure that you're using the current version at Codeplex and that you have #included vld.h in your project. You will get a much more informative output.

Worms answered 25/8, 2010 at 10:34 Comment(2)
Hi mandrill! Unfortunately is the output of Visual Leak Detector. I am using an old version taken from CodeProject web site not the one from CODEPLEX ..so I presume thatI should update + I will check the setup. IMPORTANT: can you gently confirm that what I wrote is a real leak?Punctuality
That isn't the output of Visual Leak Detector -- you will get lots of output with the call sites of where the objects were allocated. You are seeing the output of the Visual Studio leak detector: msdn.microsoft.com/en-us/library/e5ewb1h3%28VS.80%29.aspxWorms
P
2

I got it after debugging a lot of header files.

Here is what has to be done to enable file/line number in the output

#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC_NEW
Porkpie answered 25/8, 2010 at 13:24 Comment(2)
for some reason those two defines just tell me: c:\program files (x86)\microsoft visual studio 10.0\vc\include\crtdbg.h(1116) : {640} normal block at 0x000A5E28, 12 bytes long. in addition to the leak ... it doesnt really helpZambrano
settings this up triggers this warning: c:\program files\microsoft visual studio 9.0\vc\include\crtdbg.h(1203) : warning C4985: 'operator new': attributes not present on previous declarationNag
R
1

Did you compile with debugging information enabled and ensure that the pdb file is available by the leak detector? Without this information it wouldn't be able to provide line numbers.

Rennes answered 25/8, 2010 at 13:31 Comment(0)
U
0

You should use Valgrind, it's very powerfull and explains properly where are the leaks located in your program. Your program may need to be compiled with gcc, though...

Uranie answered 25/8, 2010 at 9:57 Comment(3)
I know this tool but I am afraid I have to stick to VC++! :)Punctuality
Nothing to stop you building it in gcc though, leaks are the same whatever the compilerShirker
assuming his application +libraries he uses are compatible with both linux/gcc and windows/vc++Contractile
A
0

Rational Purify is available as a for-money plugin for VC++, and is a very good leak (and other trouble) detector. I used to use it a lot on Solaris, and it was very easy to use and clear. I've also heard good things from other people about the version for use with Visual Studio, but I've never actually tried that.

FWIW, I suspect that Purify was the inspiration for Valgrind, which has already been mentioned.

Auria answered 25/8, 2010 at 10:44 Comment(0)
B
0

If the allocation numbers (the ones in the curled braces) are always the same, this could help. Basically, it described how to make VC++ generate a breakpoint when the allocation with the specified number is attempted.

Brach answered 25/8, 2010 at 10:58 Comment(2)
Hi SpaceComboy, Thank you! I noticed that; I see that in some project it stays the same and in other changes.Punctuality
@user311906: The allocation numbers are just counting all heap-allocations made. If your application makes the allocations in the same order every time, the numbers of the leaking allocations will not change, and you can use that to track down the origin of the problem. This is even more useful than just the file and line-number, because it will also give you the current state of the application.Dipteran

© 2022 - 2024 — McMap. All rights reserved.