Memory Leak Detector
by Duncan Gray · 01/29/2006 (3:33 pm) · 8 comments
Please read Pat's HowTo for background information.
That method has the drawback of only showing newly allocated memory and since 99% of memory allocations are legitimate, you have to sift through thousands of lines of useless info and figure which one is not legitimate.
I wanted a method where I could flag everything, just before I start a mission, then after the mission was over, check if any memory created after the flagged point, was not deleted.
I wanted it because I found that in my game, as well the standard starter.fps etc, the game's memory footprint grows by several megs after a mission is run, which implies that not all memory allocated during mission creation gets deleted again.
The following is a variation of some of the tools in platformMemory.cc which will create a list of all the memory allocations not deleted.
Copy and paste the following into platformMemory.cc. Read the comments for usage.
.
.
That method has the drawback of only showing newly allocated memory and since 99% of memory allocations are legitimate, you have to sift through thousands of lines of useless info and figure which one is not legitimate.
I wanted a method where I could flag everything, just before I start a mission, then after the mission was over, check if any memory created after the flagged point, was not deleted.
I wanted it because I found that in my game, as well the standard starter.fps etc, the game's memory footprint grows by several megs after a mission is run, which implies that not all memory allocated during mission creation gets deleted again.
The following is a variation of some of the tools in platformMemory.cc which will create a list of all the memory allocations not deleted.
Copy and paste the following into platformMemory.cc. Read the comments for usage.
ConsoleFunction(WriteLeaks, void, 1, 1, "WriteLeaks();")
{
// I used this to try to find things which were created during a mission
// but not deleted when the mission ended.
// Ho to use in the above situation?
// Just before you launch a mission, open the console and type FlagCurrentAllocs();
// You do that to isolate your leak detection to everything which happens after the
// call to FlagCurrentAllocs();
// Next, start your mission, do whats necesary in the mission, exit the mission
// and open the console again and enter WriteLeaks();
// Next go look in your game directoy for a file called memoryLeaks.log
//
argc; argv;
// write out leaks and such
const U32 maxNumLeaks = 1024; // how big a log file do you want?
U32 numLeaks = 0;
PageRecord * walk;
AllocatedHeader* pLeaks[maxNumLeaks];
for (walk = gPageList; walk; walk = walk->prevPage)
for(Header *probe = walk->headerList; probe; probe = probe->next)
{
for(U32 i = 0; i < 4; i++)
{
if(probe->preguard[i] != FreeGuard || probe->postguard[i] != FreeGuard)
if (!(probe->flags & FlaggityFlag))
{
if(numLeaks < maxNumLeaks)
pLeaks[numLeaks++] = (AllocatedHeader *) probe;
}
}
}
if (numLeaks)
{
char buffer[1024];
FileStream logFile;
logFile.open("memoryLeaks.log", FileStream::Write);
for (U32 i = 0; i < numLeaks; i++)
{
dSprintf(buffer, 1023, "Leak in %s: %d %d (%d)\r\n", pLeaks[i]->fileName, pLeaks[i]->line, pLeaks[i]->realSize, pLeaks[i]->allocNum);
logFile.write(dStrlen(buffer), buffer);
}
logFile.close();
}
}.
.
About the author
#2
01/31/2006 (8:04 am)
where do I put this, at build I get errors about a declaration in a header
#3
void flagCurrentAllocs()
But it now says (in the console) that it cant find the function.
01/31/2006 (8:07 am)
Ok i got it to compile I put it just before void flagCurrentAllocs()
But it now says (in the console) that it cant find the function.
#4
// write out leaks and such
const U32 maxNumLeaks = 1024;
U32 numLeaks = 0;
PageRecord * walk;
#ifdef TORQUE_DEBUG_GUARD
AllocatedHeader* pLeaks[maxNumLeaks];
for (walk = gPageList; walk; walk = walk->prevPage)
for(Header *probe = walk->headerList; probe; probe = probe->next)
if ((probe->flags & Allocated) && ((AllocatedHeader *)probe)->fileName != NULL)
pLeaks[numLeaks++] = (AllocatedHeader *) probe;
if (numLeaks && !gNeverLogLeaks) {
if (gAlwaysLogLeaks || Platform::AlertOKCancel("Memory Status", "Memory leaks detected. Write to memoryLeaks.log?") == true) {
char buffer[1024];
FileStream logFile;
logFile.open("memoryLeaks.log", FileStream::Write);
for (U32 i = 0; i < numLeaks; i++) {
dSprintf(buffer, 1023, "Leak in %s: %d (%d)\r\n", pLeaks[i]->fileName, pLeaks[i]->line, pLeaks[i]->allocNum);
logFile.write(dStrlen(buffer), buffer);
}
logFile.close();
}
}
This is a memory leak detector right?
01/31/2006 (8:15 am)
and in tge 1.4 it has:// write out leaks and such
const U32 maxNumLeaks = 1024;
U32 numLeaks = 0;
PageRecord * walk;
#ifdef TORQUE_DEBUG_GUARD
AllocatedHeader* pLeaks[maxNumLeaks];
for (walk = gPageList; walk; walk = walk->prevPage)
for(Header *probe = walk->headerList; probe; probe = probe->next)
if ((probe->flags & Allocated) && ((AllocatedHeader *)probe)->fileName != NULL)
pLeaks[numLeaks++] = (AllocatedHeader *) probe;
if (numLeaks && !gNeverLogLeaks) {
if (gAlwaysLogLeaks || Platform::AlertOKCancel("Memory Status", "Memory leaks detected. Write to memoryLeaks.log?") == true) {
char buffer[1024];
FileStream logFile;
logFile.open("memoryLeaks.log", FileStream::Write);
for (U32 i = 0; i < numLeaks; i++) {
dSprintf(buffer, 1023, "Leak in %s: %d (%d)\r\n", pLeaks[i]->fileName, pLeaks[i]->line, pLeaks[i]->allocNum);
logFile.write(dStrlen(buffer), buffer);
}
logFile.close();
}
}
This is a memory leak detector right?
#5
Yes thats a good place to put it.
If you are refering to the shutdown() function in platformMemory.cc, it does not work.
You need to define TORQUE_DEBUG_GUARD before you can use the memory tools or the console won't know they exist. Perhaps I should have mentioned that but then I would have to repeat most of Pats article.
So for the benefit of those who look at this in the future, depending on your TGE experience, you will need to understand all of Pat's article in order to use this tool effectively.
.
01/31/2006 (12:27 pm)
Quote:
Ok i got it to compile I put it just before void flagCurrentAllocs()
Yes thats a good place to put it.
Quote:
This is a memory leak detector right?
If you are refering to the shutdown() function in platformMemory.cc, it does not work.
Quote:
But it now says (in the console) that it cant find the function.
You need to define TORQUE_DEBUG_GUARD before you can use the memory tools or the console won't know they exist. Perhaps I should have mentioned that but then I would have to repeat most of Pats article.
So for the benefit of those who look at this in the future, depending on your TGE experience, you will need to understand all of Pat's article in order to use this tool effectively.
.
#6
04/27/2006 (11:57 am)
thanks for clearing that up
#7
07/01/2006 (2:27 am)
Holy shit, my memory leak log file is near 1mb!
#8
That second processing loop would need to walk the list once for each item in the list and flag or remove any duplicates. Probably not to hard to do but I have not tried it.
07/12/2006 (10:20 pm)
Most are just repeats. Ideally the code would need to recognise whether it has already written a particular "problem" but that would involve a second processing loop prior to the write loop.That second processing loop would need to walk the list once for each item in the list and flag or remove any duplicates. Probably not to hard to do but I have not tried it.

Torque 3D Owner Eric Roberts
- Eric