memory leak somewhere

Started by
14 comments, last by blaze02 18 years, 1 month ago
... or possibly that you have under-allocated memory some place and everybody sees the last part of that memory block *magically* changing with time. Most of the time, it's one of those "off-by-one" size calculation errors. Some compilers add debugging info to allocated blocks in _DEBUG mode. One way to be sure is to tweak your "Release" settings to allow for debugging information to be generated and you turn off optimizations. You thus have a debuggable "Release" build. Another method is to add 4K to each malloc() call in turn and run the app to see which one is likely being under-allocated.
Advertisement
So I gave up on the one program because all it did was overload the new/delete/malloc/free functions and operators. My problem is not with a new/delete call (of course not, that would be too simple). In fact, no where in my code do I call new or any other allocator. All my dynamic data is stored in vectors and hash_multimaps.

If you look at the first 2 memory errors that occur, the first is an invalid write to 0x0130000 or whatever. The second is an invalid read from 0x2. Just 2. Which leads me to believe that I using a certain data structure that begins with a 2 byte variable and is followed by another 2 byte variable or is packed to 1 or 2. . But as far as I can see, the &#111;nly way I'm accessing memory at 0x2 is by acquiring a null ptr to a structure with a member starting 2 bytes into the structure.<br><br>I've been asserting that my ptr's are not null and now I'm returning from the function if my ptr's are null (because asserts don't work in release).<br><br>It is possible that the error is not in my code, but I doubt it because the prog locks up right when the clients connect.<br><br>Anyways, more suggestions are always welcome.
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog
So hind-sight is 20/20. I've heard that enough. The solution was to duplicate my Release build (where the prog. broke), then slightly increase typechecks and debug info on that build. This build deemed, "MyDebug" didn't take long to narrow down the exact compiler setting that causes the bug. The problem is I'm not sure how to fixe it.

The compiler setting is "Basic Runtime Checks:" The possible values are, stack frames, unititialized vars, none, or both. When I put this on "Stack Frames", I'm assuming it will check all stack frames and correct on-the-fly.

So I'm guessing my problem is that I'm corrupting the stack somewhere. I do do a bit of recursion, but nothing too hard (at least not for me).

Suggestions?

[Edited by - blaze02 on March 7, 2006 10:00:23 AM]
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog
Well.. here it is. The bane of my existence for the past 12 hours.

void jMsging::NatPunch(const SOCKADDR_IN * sockaddr){	int oldTTL, TTL = 2, size;	getsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&oldTTL, &size);	setsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&TTL, sizeof(TTL));	Send(0, 0, sockaddr);	setsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&oldTTL, sizeof(oldTTL));}


Seems harmless at first glance. And it was only called one time. Thats all it needed to kick the stack pointer in the balls. A cheap shot for the lock up.
So this is how you punch through a NAT with UDP. You lower the ttl, send a zero-byte packet, then up the ttl. Can you see the problem?

getsockopt is used for a variety of options, that is why oldTTL must be typecast to a char*. The problem is that the (size) param is an in/out variable. Much like the recvfrom() network call. People ask why the value has to be a pointer to a size. The answer is that size is not only the size of the value loaded into oldTTL, but also the maximum size that can be loaded in. (size) must be initialized to sizeof(oldTTL) to get rid of the bug.
Final thoughts: why is getsockopt trying to load MORE than 4 bytes into oldTTL just because the size said it could. TTL ranges from 0 -> 255. How was it using more than 4 bytes.
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog
That's a silly assumption anyway. What if size somehow ended up being 0? Then it wouldn't set any bytes and oldTTL would end up containing garbage. You have to set size to something to make sure that doesn't happen, and if you're going to do that, you might as well set it to the correct value.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Quote:Original post by smart_idiot
That's a silly assumption anyway. What if size somehow ended up being 0? Then it wouldn't set any bytes and oldTTL would end up containing garbage. You have to set size to something to make sure that doesn't happen, and if you're going to do that, you might as well set it to the correct value.


That was the problem. I said that I fixed it by initializing size to sizeof(oldTTL).
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog

This topic is closed to new replies.

Advertisement