SDL memory leaks and Visual Leak Detector

1.2k Views Asked by At

Alright, so I think my program might have a memory leak. It's an SDL application, and it seems to have grown too large for me to manually pinpoint the leak. I searched around for a windows equivalent of Valgrind (I'm running Windows 7 x64 and using Visual Studio 2010), and eventually came across Visual Leak Detector. Unfortunately, it doesn't seem to want to generate ay output.

I set up another project, an empty console application, and set up VLD the same way as in my SDL app. Upon running the program, VLD worked perfectly and caught every memory leak that I threw at it. But in the SDL app, it just outputs "Visual Leak Detector Version 2.2 installed." at the beginning of the debug session and nothing else, even when I intentionally created a memory leak right in the main function.

The closest I can tell, it might have to do with SDL screwing with the program entry point. But that's just a guess. Is there any way to get VLD to work with SDL?

2

There are 2 best solutions below

0
On BEST ANSWER

You could try to deleaker. It is a powerful tool for debugging memory leaks.

0
On

I had a similar problem using SDL library as well. In my case though, I was trying to use the default Memory Leak detection of Visual Studio 2010 because I didn't wanted to use a third party library/application.

Fixing the issue

If after all the required includes, define and function call you still don't see any memory leaks printed out, it might be that your Runtime Library is not set properly.

Double check if you have the debug version of the Runtime Library instead of the non-debug one (/MT and /MD).

Multi-threaded Debug (/MTd)

Multi-threaded Debug DLL (/MDd)

The compiler defines _DEBUG when you specify the /MTd or /Mdd option. These options specify debug versions of the C run-time library. See _DEBUG reference MSDN

Thus, the _DEBUG symbol must be defined in order to enable CRT code.

[...] When _DEBUG is not defined, calls to _CrtSetDbgFlag are removed during preprocessing [...]. See MSDN reference

So building a debug build is not enough to ensure _DEBUG will be defined.

This is something that you usually don't change in a normal project, but following a tutorial for SDL could lead you were I was.

Hopefully, it is going to help someone else, or even you.

More Details below

I was following the MSDN page to enable Memory leak detection out of the box with VS 2010.

After declaring those

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

I enabled them into my code and I inserted a deliberate memory leak

int main( int argc, char* args[] )
{
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );

    int *pArray = (int*)malloc(sizeof(int) * 24); // Memory not freed

    return 0;
}

Nothing was printed out.

So, I looked at the assembly and it was definitively not generating the CRT code at all as you can see:

int main( int argc, char* args[] )
{
012932F0  push        ebp  
012932F1  mov         ebp,esp  
012932F3  sub         esp,0CCh  
012932F9  push        ebx  
012932FA  push        esi  
012932FB  push        edi  
012932FC  lea         edi,[ebp-0CCh]  
01293302  mov         ecx,33h  
01293307  mov         eax,0CCCCCCCCh  
0129330C  rep stos    dword ptr es:[edi]  
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); // Nothing in both case!

    int *pArray = (int*)malloc(sizeof(int) * 24);
0129330E  mov         esi,esp  
01293310  push        60h  
01293312  call        dword ptr [__imp__malloc (129E4CCh)]  
01293318  add         esp,4  
0129331B  cmp         esi,esp  
0129331D  call        @ILT+580(__RTC_CheckEsp) (1291249h)  
01293322  mov         dword ptr [pArray],eax  

Then, I realized that the _DEBUG symbol was probably not getting defined.