Re: Detecting memory leaks (VC8)
Quote:
Originally Posted by
Lindley
Personally I find it rather difficult to determine exactly which gtk+ objects need explicit deletion and which don't, since gtk+ uses some kind of reference counting which isn't documented all that well.
I have to admit, that is a definite weakness with gtk+. I tend to use gtkmm for new projects.
I haven't had much time to look into this yet so I'm still struggling to figure out how I'll crack the fact that _CrtDumpMemoryLeaks() will be giving me false readings for global objects if I'm not using MFC (it does work fantastically well for an MFC app but not so well in the example I gave).
Is there a way to set a "start point" for leak detection? In other words, to say "ignore any memory allocated before this point because that'll just be the global objects"?
Re: Detecting memory leaks (VC8)
I also had some issues when experimenting with _CrtDumpMemoryLeaks() but the method I posted before works alright (VS2010 untested). My guess is that _CrtDumpMemoryLeaks() is called by the debug libs later in the exit (after the globals are destroyed).
If you have dll's in your project you can do the same trick as in main in DllMain DLL_PROCESS_ATTACH but there will be a lot of duplicated reports, most of them without proper file names since the memory holding the information is discarded before the printout.
Re: Detecting memory leaks (VC8)
Quote:
Originally Posted by
John E
I have to admit, that is a definite weakness with gtk+. I tend to use gtkmm for new projects.
I haven't had much time to look into this yet so I'm still struggling to figure out how I'll crack the fact that _CrtDumpMemoryLeaks() will be giving me false readings for global objects if I'm not using MFC (it does work fantastically well for an MFC app but not so well in the example I gave).
Is there a way to set a "start point" for leak detection? In other words, to say "ignore any memory allocated before this point because that'll just be the global objects"?
Using the page I linked to earlier, you should be able to set a "memory checkpoint" and then just dump everything that's different between two checkpoints.
Re: Detecting memory leaks (VC8)
Thanks guys. Still busy with a different project at the moment but I'll get aorund to trying these asap. :thumb:
Re: Detecting memory leaks (VC8)
I tried some further experiments this morning. Here's my app's main loop:-
Code:
int main (int argc, char *argv[])
{
Gtk::Main app(&argc, &argv);
MainWindow mainWnd;
mainWnd.set_title ("Hello World !");
app.run (mainWnd); // <-- This runs my code
_CrtDumpMemoryLeaks();
return 0;
}
As you can see, this app uses libgkt+ (strictly speaking, gtkmm). Note the red line. The red line essentially calls gtk_init() which initialises libgtk+.
If I commented out everything between that red line and my return statement, the resulting code would flag up several hundred memory leaks. I've been in touch with the gtk developers but their attitude is that a 'true' leak is one that gets worse with usage. One-off leaks caused by program initialisations not getting cleaned up are somehow not 'true' leaks. That seems to be the official gtk line. :(
Of course, what I want to find are the leaks in my own code - in other words, anything that leaks during the call to app.run (mainWnd); So I need some way of doing something like this:-
Code:
int main (int argc, char *argv[])
{
Gtk::Main app(&argc, &argv);
MainWindow mainWnd;
mainWnd.set_title ("Hello World !");
_Ignore_Any_Memory_Allocated_So_Far_And_Begin_Leak_Detection_Here();
app.run (mainWnd); // <-- This runs my code
_CrtDumpMemoryLeaks();
return 0;
}
A couple of other web sites suggested a technique similar to S_M_A's (i.e. using _CrtSetDebugFlag) but I can't seem to make it work. No matter where I put my calls to _CrtSetDebugFlag() I always end up with all the memory leaks getting reported. Is there a way to do what I want?
Re: Detecting memory leaks (VC8)
Quote:
Originally Posted by
itsmeandnobodyelse
The memory leaks were reported when you use the macro DEBUG_NEW in your sources which actually provides a different operator new and operator delete where all allocations and deallocations were watched.
Noooooo. DEBUG_NEW replaces the normal new and in this case in debug mode the leak report will contain some additional information helping to detect where the leak occurs.
even a regular new will show up on the leak report. DEBUG_NEW does not "make" this happen.
Re: Detecting memory leaks (VC8)
I've just been reading about a product called Valgrind. It has a facility for selectively suppressing leak reports from 3rd party modules (e.g. DLLs). i.e. so you can keep track of leaks in your own code whilst ignoring leaks in someone else's code that you can't do anything about. Sadly Valgrind isn't available for Windows. :( Something similar though would be a neat feature for Visual Studio IMHO.
Re: Detecting memory leaks (VC8)
John if you follow my suggestion in post #12 and drop the call to _CrtDumpMemoryLeaks() I'm pretty sure you get what you seek. The call is not needed (see post #17).
Re: Detecting memory leaks (VC8)
I think I've done it correctly but I still seem to be seeing all the memory leaks. For example if I have no header files and just one source file looking like this:-
Code:
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
int main (int argc, char *argv[])
{
char *p = new char[9];
#if defined(_DEBUG)
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF; // Check heap alloc and dump mem leaks at exit
_CrtSetDbgFlag( tmpFlag );
//_crtBreakAlloc = 58652; // in case something very bad happens
assert( !errno );
#endif
return 0;
}
I still see the 9 bytes that got allocated before the _CrtSetDbgFlag() stuff. What am I not uncderstanding?
Re: Detecting memory leaks (VC8)
Setting the DbgFlags informs the CRT to do a leak check "as late as possible"
it doesn't matter WHEN you've set the LEAK_CHECK flag. At the very start of your program or at the very end makes no difference.
Basically what the crt does for you is (it does a LOT more, but this gives yo a rough idea of what's going on behind the scenes).
Code:
void TheRealMainEntryPoint()
{
initialise_CRT();
call_constructors_of_global_objects();
int ret = main( getargc(), getargv() ); // Call the user provided main()
call_destructors_of_global_objects();
if (debugflag & _CRT_LEAK_CHECK_DF) // Leak report flag set ?
_CrtDumpMemoryLeaks(); // then report leaks.
cleanup_CRT();
ExitProcess(ret);
}
Re: Detecting memory leaks (VC8)
Okay, so going back to post #20 (my second code sample) is it possible to achieve what I've been trying to do? I've read a couple of articles suggesting that it should be possible but I haven't been able to make it work so far. :cry:
Re: Detecting memory leaks (VC8)
Quote:
Originally Posted by
John E
What's interesting is that no leak got detected from strTest1 (which was a std::string).
This most likely isn't reporting a leak due to the small string optimization that is done with std::string.
Basically, for strings with 15 characters or less, the data for the string is held directly in the string object (and not allocated separately). So there is no memory leak because no memory was allocated.
If you try this with a longer string, you will probably see a leak for the global std::string when calling _CrtDumpMemoryLeaks() at the bottom of main.
Re: Detecting memory leaks (VC8)
Quote:
Originally Posted by
John E
I've just been reading about a product called Valgrind. It has a facility for selectively suppressing leak reports from 3rd party modules (e.g. DLLs). i.e. so you can keep track of leaks in your own code whilst ignoring leaks in someone else's code that you can't do anything about. Sadly Valgrind isn't available for Windows. :( Something similar though would be a neat feature for Visual Studio IMHO.
Valgrind is terrific----not just for memory leaks, but for heap corruption errors, and even multithreading errors to a limited degree.
Re: Detecting memory leaks (VC8)
John can you post a (minimal) project where you have a problem detecting memory leaks? I just have to try it since, at least in 2005, what I posted worked like a charm.
Re: Detecting memory leaks (VC8)
Thanks S_M_A. I've probably confused the issue because my requirement has changed since my original post. At first, I was just trying to enable leak detection. But after I got it working, I hit a different problem....
Just to recap, my app uses libgtk+ whose initialization routines seem to leak memory all over the place - but when I reported it to the gtk+ devs, their attitude was that if a block of memory needs to persist for the full lifetime of the program, failing to release it is somehow not a 'true' memory leak.
The problem is that there are hundreds of such leaks - so finding my own leaks amongst the huge amount of output is extremely difficult. What I want to do is to be able to set up a 'start' point (after I've initialized libgtk+) such that only the leaks after that point will get listed.
To save you from needing to install libgtk+ I've given a similar example in post #24. If you assume that the statement char *p = new char[9]; was in reality my call to gtk_init(), what I'm trying to do is to detect only the leaks which occur after that point.
So if you take this pseudo code as an example:-
Code:
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
int main (int argc, char *argv[])
{
char *p1 = new char[9]; // In reality, Gtk::Main() which calls gtk_init() (which introduces all the leaks)
_start_detecting_leaks_here();
char *p2 = new char[15];
return 0;
}
I'd like to have some method of not listing the memory leaked at p1 whilst still listing the memory that got leaked at p2.
It might be worth adding that the gtk code is all external to my app (i.e. all implemented in DLLs). I don't know if that could offer a solution somehow? Let me know if that didn't make sense. :)