#169721 - vuurrobin - Fri Jul 31, 2009 3:55 pm
hello everybody
I have a program that somehow freezes and I can't figure out why. the program displays some explosions on the screen by creating some ExposionSprite objects and calling its update function. if I put the objects on the stack (either sepparate or in an array), it works. if I use new or malloc+placement new, it works. if I use my AllocRawMem (which just calls malloc) and manually call placement new, it works.
if I use my AllocMem (which calls AllocRawMem and placement new), it freezes. if I use my LiteVector or std::vector, it freezes.
it always freezes during the update function, but the problem can't be in there or else it would freeze all the time. I also doubt it is my memory functions or LiteVector, seeing as std::vector doesn't uses those functions, and I asume std::vector doesn't have bugs.
I tried the program on no$gba and on my original ds, and they both freezes. sometimes it freezes after about 30 iterations/vblanks and sometimes after 2 or 3 vblanks. but it always freezes within a second.
I've kinda run out of options to try, so I hope that someone has any idea what could go wrong, or is willing to run the program in his debugger to see what the program is doing.
here is the program:
http://www.megaupload.com/?d=VWZNM110
edit: if anybody wants to see the code, just say so and I'll post what you need.
can somebody please help me?
vuurrobin
#169722 - sgeos - Fri Jul 31, 2009 5:50 pm
A memory leak, perhaps?
#169725 - vuurrobin - Fri Jul 31, 2009 7:00 pm
I'm not allocating or releasing anything in the loop, and using the functions I found here:
http://forum.gbadev.org/viewtopic.php?t=14438&highlight=getmemfree
I can see that the free memory (the number returned by getMemFree()) stays consistent (at 3824072). so I don't think that its a memory leak.
could this have something to do with static/global data? or the cache messing something up? I assume that there isn't anything wrong with the standard c rand() function, right?
#169726 - sgeos - Fri Jul 31, 2009 7:15 pm
Clearly something isn't being done right, and it could be anything. rand() shouldn't be a problem, but you might be doing something silly with the result.
My advice is sleep on it and go through your code tommorow, slowly and carefully. Look for off by one errors. The bug is probably in some code you assume is solid and are not focusing on.
EDIT: You have all compiler warnings enabled, right? The gcc option for that is -Wall
#169743 - Cearn - Sat Aug 01, 2009 8:58 am
no$gba seems to get stuck at the loop at 0200:3188, which I think is part of the function starting(?) at 0200:3144. It calls 0200:30CC a lot, so that one may have something to do with it as well.
If you could provide the functions at those locations and the structs they use, that might be helpful. The template makefiles should produce a mapfile where you can find the names of the functions at those addresses.
#169744 - vuurrobin - Sat Aug 01, 2009 1:47 pm
I looked at the map file, and searching for those adresses didn't gave me any results. after looking for it myself, I could find the following block:
Code: |
.text 0x02002db0 0x47c c:/programs/devkitPro/libnds/lib\libnds9.a(sprite.o)
0x02002db0 oamDisable
0x02002e44 oamClear
0x0200305c oamRotateScale
0x02002e10 oamGetGfxPtr
0x02002de0 oamEnable
0x02002e6c oamGfxPtrToOffset
0x020030bc oamUpdate
0x02003120 oamInit
0x02002e9c oamSet
.text 0x0200322c 0x45c c:/programs/devkitPro/libnds/lib\libnds9.a(sprite_alloc.o)
0x02003258 oamCountFragments
0x02003444 oamAllocReset
0x020032a4 oamFreeGfx
0x02003478 oamAllocateGfx
.text 0x02003688 0xdc c:/programs/devkitPro/libnds/lib\libnds9.a(system.o)
0x02003720 systemMsgHandler
0x020036c8 powerOn
0x02003710 powerValueHandler
0x02003688 ledBlink
0x020036f8 systemSleep
0x0200369c powerOff |
but those are all from libnds. however, I did change the project a few times, so the adresses probably shifted a bit.
I do know the function of where it freezes:
Code: |
void ExplosionSprite::update()
{
cout << "in update" << endl;
if(explosionVBlankPassed == vblankPerExplosion)
{
cout << "displaying" << endl;
//the sprite is displaying an explosion
frameVBlanksPassed++;
if(frameVBlanksPassed == vblankPerFrame)
{
//time for the next frame, or wait if the explosion is over
register uint newFrame = (getCurrentFrame() + 1);
if(newFrame == MAX_FRAMES)
{
//the explosion is over, so we make the sprite invisible,
//and wait a number of vblanks
setVisible(false);
explosionVBlankPassed = 0;
}
else
{
//set the next frame
setFrame(newFrame);
}
frameVBlanksPassed = 0;
}
}
else
{
cout << "waiting" << endl;
//the sprite is waiting between explosions
explosionVBlankPassed++;
if(explosionVBlankPassed == vblankPerExplosion)
{
//waiting is over, so we set the first frame, set the sprite visible
//and randomly set the position, frame time(number of vblanks to wait per frame)
//and wait time(number of vblanks to wait after the explosion finished)
using libOOP::randInt;
setFrame(0).setVisible(true);
setPosition(randInt(0, (SCREEN_WIDTH - getWidth())), randInt(0, (SCREEN_HEIGHT - getHeight())));
vblankPerFrame = randInt(5,10);
vblankPerExplosion = randInt(10, 60);
explosionVBlankPassed = vblankPerExplosion;
}
}
cout << "Sprite::update" << endl;
Sprite::update();
cout << "end Sprite::update" << endl;
} |
everytime it freezes, it displayed 'waiting' or 'displaying' as last (mostly waiting), but it never reaches 'Sprite::update'.
the problem is that the function itself if fine. it works when I put the ExplosionSprite on the stack, and on the heap works on some occasions. if I change the way the object is created, the update function freezes within a second.
@sgeos, yes I have all warnings turned on.
#169749 - LOst? - Sat Aug 01, 2009 10:13 pm
vuurrobin, are explosionVBlankPassed, vblankPerExplosion, frameVBlanksPassed, vblankPerFrame declared volatile? If they are not, and they are updated inside an interrupt, undefined (random) results will follow.
Also, using cout might be a bad idea? printf() is probably better. I just don't know how much cout takes as an ostream object and how buffered the output will be. printf() might buffer too, so I don't know.
_________________
Exceptions are fun
#169755 - elhobbs - Sun Aug 02, 2009 12:57 am
are you usuing defaultExceptionHandler to catch exceptions like stack overflows and invalid memory accesses?
#169756 - vuurrobin - Sun Aug 02, 2009 1:32 am
I've found and fixed the problem :D .
the problem was that I didn't handled passing the ownership of the vram correctly in the copy constructor. because of this, it tried to release the vram every vblank (I'm using libnds vram allocating functions). this led to either using or releasing vram that was already released, or to oam getting a NULL pointer to the graphics. fixing the copy constructor also fixed the bug.
@LOst?, they aren't declared volatile, but they also aren't updated inside an interupt.
and yes, cout is bloated but otherwise fine. and I find it easier to use than printf(). and seeing that it was just temporarily I chose to use it. and I'll probably create my own text routines sooner or later.
@elhobbs, yes I use defaultExceptionHandler() to catch those things. it catches hardware exceptions, right?
Thank you everybody for your help!!! :D
#169766 - elhobbs - Sun Aug 02, 2009 10:19 pm
yes, hardware exceptions.
libnds has a function to allocate teture memory but it does not have a function to free it - am I mistaken?
#169767 - TwentySeven - Sun Aug 02, 2009 11:06 pm
void glResetTextures(void);
#169768 - vuurrobin - Sun Aug 02, 2009 11:54 pm
I don't know anything about textures, but I'm using oamAllocateGfx and oamFreeGfx to allocate vram for my sprites.