Server Help

Bot Questions - MervBot Memory-Leak Checking

CypherJF - Fri May 27, 2005 6:58 pm
Post subject: MervBot Memory-Leak Checking
Using MervBot b45/b46 - is there any way to come up w/ an effective way of determining that there are no memory leaks occuring within a specific plugin? I'm pretty confident I have deleting allocated memory, but would like to put my mind to ease over it. MMaverick said there used to be a way? Thanks in advance.
Solo Ace - Fri May 27, 2005 7:24 pm
Post subject:
Try using this (this code came straight from MSDN Library), it works fine for me heh.

Code: Show/Hide
// Where your DLL is loaded, call these:
    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

// Then where you want to check for a memory leak, see if there are memory leaks and dump results into the console:
    _CrtDumpMemoryLeaks( );


Taken from MSDN's _CrtDumpMemoryLeaks.

Hope that helps, good luck.
CypherJF - Fri May 27, 2005 7:57 pm
Post subject:
Thanks now to interpret the results:

Quote:
Radon711 Ext: DLL plugin disconnected.
Detected memory leaks!
Dumping objects ->
{38} normal block at 0x00E70050, 12 bytes long.
Data: < > F0 0E E7 00 00 00 00 00 00 00 00 00
{37} normal block at 0x00E70EF0, 88 bytes long.
Data: < > 00 CD CD CD 00 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.


icon_confused.gif
CypherJF - Fri May 27, 2005 9:14 pm
Post subject:
Sorry for the double post, but when I did the MervCore - w/ debug mode - there were a ton of memory leak objects detected. :shrug:
Cyan~Fire - Sat May 28, 2005 4:07 pm
Post subject:
Look for anywhere where you could be allocating those sizes. That's really the only way to do it.
Mr Ekted - Sat May 28, 2005 4:16 pm
Post subject:
Not so. icon_smile.gif
CypherJF - Sat May 28, 2005 7:31 pm
Post subject:
I take it that there is no possible way of figuring it out - without checking everything by hand then eh?
Mr Ekted - Sat May 28, 2005 7:47 pm
Post subject:
There are lots of ways. All the information you need is in your dump.
CypherJF - Sat May 28, 2005 8:37 pm
Post subject:
Way to be cryptic Mr Ekted - care to elaborate on HOW I could go about doing this? icon_smile.gif *continues to read on the Heap State Reporting Functions/Info on MSDN*
Solo Ace - Sat May 28, 2005 8:46 pm
Post subject:
Whenever you allocated a variable you should let it output some information about the allocation.

Use this macro every time after allocation.
Code: Show/Hide
#define DEBUG_NEW(x) printf("allocation: %s %d 0x%p\n", __FILE__, __LINE__, x)


By doing this you can "trace" the leaking variable back by using the address the dump gave you.

I wouldn't know any other or better ways, so, Ekted, giving some more help would be appreciated. sa_tongue.gif
CypherJF - Sat May 28, 2005 8:53 pm
Post subject:
Just some cliff-notes:
{#} - this allocation request number is enclosed in curly brackets (for example, “{36}”).

And -- New objects are filled with 0xCD when they are allocated.

msdn

msdn2
Mr Ekted - Sat May 28, 2005 8:57 pm
Post subject:
1. You have the length and content of the leaked memory. So you are looking for allocations of 12 and 88 bytes. Find all your allocations and look at how big they are.

2. You have the contents. What structures that you allocate could contain the data "F0 0E E7 00" or "00 CD CD CD"?

3. You have the addresses. If you run the EXE under exactly the same circumstance with no random elements, all of the allocations will be the same addresses.
CypherJF - Sat May 28, 2005 9:12 pm
Post subject:
Well, I did tested that macro that Solo gave - and the memory addresses provided do not match any of the allocations that I perform. I'm going to start assuming it has to do w/ a leak in the core?

the only structures that I 'new' up are
Code: Show/Hide
struct PlayerTag
{
   Player *p;
   char name[20];
   int index;
   int data;
};

struct OffenseTag
{
   Player *killer;
   Player *killed;
   int time;
   int id;
};


OffenseTag would be 12 byte's - right?

Quote:
Radon711 Got synchronization packet [1778400][1804605582]
Radon711 P:CypherJF> .load ctkwatch
allocation: C:\Projects\B45\cTKWatch\SPAWN.CPP 483 0x00C70EF0 bot = new botInfo(event.handle);
Radon711 Ext: DLL plugin connected.
allocation: C:\Projects\B45\cTKWatch\SPAWN.CPP 279 0x00C70E70 OffenseTag *ot = new OffenseTag();
Radon711 P:CypherJF> .tk 1
allocation: C:\Projects\B45\cTKWatch\SPAWN.CPP 534 0x00C70D40 Player *tag = new PlayerTag;
Radon711 A:Player warned
Radon711 P:CypherJF> .unload 0
Radon711 Ext: DLL plugin disconnected.
Detected memory leaks!
Dumping objects ->
{40} normal block at 0x00C70EB0, 12 bytes long.
Data: < > F0 0E C7 00 00 00 00 00 00 00 00 00
{37} normal block at 0x00C70EF0, 88 bytes long.
Data: < > 00 CD CD CD 00 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.


Well found the 0x00C70EF0.

Thanks for the help.
Mr Ekted - Sat May 28, 2005 9:52 pm
Post subject:
PlayerTag is 32. OffenseTag is 16.

I assumed you had run the core without your DLL first. If it's the core, you will get that same dump.
CypherJF - Sat May 28, 2005 10:08 pm
Post subject:
Ya, I didn't post that run of a clean core run w/o plugin. I was looking at the src code more closely the one offset is the

botInfo *bot;
...
bot = new botInfo(event.handle);
botlist.append(bot);


Anyways, the botlist is never cleared out or delete the dynamically allocated memory - Catid told me he had that intentionally in there because it was a fix to something, if he recalled correctly (I can see Ekted 'cringe' at that icon_smile.gif).

So that's technically 1 allocation that isn't cleared which I could find - to find a fix - ... is another question. But thanks everyone for the help.
Mr Ekted - Sat May 28, 2005 11:12 pm
Post subject:
If it's always just the 2 blocks no matter how long you run, then you are fine. The process isn't leaking memory over time.
CypherJF - Sun May 29, 2005 2:10 am
Post subject:
But it is my understanding though that the dynamically non-released memory will never be allowed to be claimed by the heap manager until a system reboot - is that correct?

Like Catid said, it's fine if it leaks - but it's only bad if you're always unloading and reloading plugins...

But really, there should be no memory leaks in an application - if at all possible.
Bak - Sun May 29, 2005 4:39 am
Post subject:
I believe it's freed when the process terminates, because each process has it's own virtual memory that's 4 gigs big
CypherJF - Sun May 29, 2005 4:46 am
Post subject:
I've read that before, but I wonder how that comes into play when my professors were teaching the class what I had mentioned in my other post. Was this the case for the older programs/OS'?
Cyan~Fire - Sun May 29, 2005 10:38 am
Post subject:
Windows is supposed to clean up every program's heap, but it doesn't always do the best job of it, which is why I always manually free everything.
Mr Ekted - Sun May 29, 2005 11:50 am
Post subject:
Everything specifically allocated on any heap is freed when the process is terminated. This is also true of window handles, resource handles (pens, brushes, fonts, etc), open files/pipes/mutexes/etc. The only thing I can see being an OS-level leak would be handles into driver objects with a bad driver (not cleaning up correctly), but the user-level has no control over this.
Cyan~Fire - Sun May 29, 2005 9:23 pm
Post subject:
Well, it's only one more line of code in your app, so I'd say it's a case when "better safe than sorry" is actually true.
Mr Ekted - Sun May 29, 2005 10:19 pm
Post subject:
I'm not saying "don't worry about freeing stuff." By all means write clean code. But if the leak is in the core, and you don't feel like debugging someone else's problem, AND it's not a recurrring leak, then it's not as a big a deal.
CypherJF - Mon May 30, 2005 12:10 am
Post subject:
Got'cha, thanks everyone. icon_smile.gif
Cyan~Fire - Mon May 30, 2005 1:03 pm
Post subject:
Ok. There are no leaks in the core. (Or at least none that the CRT detected.)
Solo Ace - Mon May 30, 2005 1:25 pm
Post subject:
Cypher used v45 there, heh, maybe that's a difference between v45 and v46? I don't know, v38 was my latest. sa_tongue.gif
CypherJF - Mon May 30, 2005 1:35 pm
Post subject:
Cyan~Fire wrote:
Ok. There are no leaks in the core. (Or at least none that the CRT detected.)


client.cpp
Code: Show/Hide

int _cdecl main(int argc, char *argv[])
{
   /*
      argv[0] Commandline to exe
      argv[1] First argument
   */
      _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
      _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
      _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
      _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
      _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
      _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

//...


   _CrtDumpMemoryLeaks( );

   system("PAUSE");
   return 0;
}


Output:
http://cypherjf.sscentral.com/uploads/output2.txt
Solo Ace - Tue May 31, 2005 6:05 am
Post subject:
Which version is this, Cypher?

Does the newest version show any difference?
CypherJF - Tue May 31, 2005 1:12 pm
Post subject:
It's build 46- the actual plugin src code I use is b45 - however, there is no major differences between these two builds.
Solo Ace - Wed Jun 01, 2005 4:41 am
Post subject:
It seems like many "console" messages are leaking, the messages it puts in the console.
Maybe there's something wrong with that?
Solo Ace - Fri Jun 03, 2005 8:10 am
Post subject:
Let's get our common sense (yes!) to work and find out why it's reporting memory leaks in the core.

In the main function we can find
Code: Show/Hide
   // Create bot database
   BOT_DATABASE botDatabase;


Which will construct botDatabase, now, where does it deconstruct it? sa_tongue.gif

If you'd rename the main function and make an alternative main function which you call the original main function from you will see _CrtDumpMemoryLeaks() doesn't dump anything and return FALSE.

I think this must be a false positive, as MSDN called it.
Mr Ekted - Fri Jun 03, 2005 3:08 pm
Post subject:
public/static objects are constructed when the app starts and destructed when the app stops. Whether or not the CRT debug functions correctly see this I don't know.
Solo Ace - Fri Jun 03, 2005 5:07 pm
Post subject:
I was just saying there is no memory leak detected in MERVBot's core by _CrtDumpMemoryLeaks(). But you have to make sure you call the _CrtDumpMemoryleaks(); after botDatabase was deconstructed, otherwise botDatabase will be seen as a memory leak by it, which it isn't because it will get deconstructed as soon as the main function returns.
CypherJF - Fri Jun 03, 2005 6:54 pm
Post subject:
Yeah, I guess that really makes sense. Ugg. Again I feel dumb. lol. icon_smile.gif
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group