Stack overflow in release but not debug

Started by
8 comments, last by Mephs 18 years, 11 months ago
Hey guys. Wrote a 3ds model loader (yes, i know there are libraries that can do it but i wanted to do it myself for various reasons). Anyways, it works fine in debug. I can load models no prob. But when I do a release compile, i get a stack overflow error. I dunno why it wouldnt show up in the debug compile (I admit that I dont know much of the difference between both save for optimisation in release and lack of debug code). Anyone can help me? Its with my main recursive function: ProcessChunk. It has a while in it that will run until i've read the entire chunk. This is where the stack overflow occurs, testing the while condition.


void C3DSModel::ProcessChunk(stChunk* pChunk)
{
	while (pChunk->bytesRead < pChunk->length)
	{
		stChunk tempChunk = {0};
		ReadChunk(&tempChunk);
		
		switch(tempChunk.ID)
		{
		//ETNRY POINT
		case EDIT3DS:			// 0x3D3D
			ProcessChunk(&tempChunk);
			break;

		//OBJECT(MESHES)
		case OBJECT:			// 0x4000
			{
			stMesh mesh;
			pMeshs.push_back(mesh);
			numMeshs++;
			tempChunk.bytesRead += GetString(pMeshs[numMeshs-1].szMeshName);
			ProcessChunk(&tempChunk);
			}
			break;
		case OBJ_MESH:			// 0x4100
			ProcessChunk(&tempChunk);
			break;
		case MESH_VERTICES:		// 0x4110
			ReadMeshVertices(&tempChunk);
			break;
		case MESH_FACES:		// 0x4120
			ReadMeshFaces(&tempChunk);
			break;
		case MESH_MATERIAL:		// 0x4130
			ReadMeshMaterials(&tempChunk);
			break;
		case MESH_UV:			// 0x4140
			ReadMeshUVCoords(&tempChunk);
			break;

		//MATERIALS
		case MATERIAL:			// 0xAFFF
			{
				stMaterialInfo mat = {0};
			pMaterials.push_back(mat);
			numMaterials++;
			ProcessChunk(&tempChunk);
			}
			break;
		case MAT_NAME:			// 0xA000
			tempChunk.bytesRead += GetString(pMaterials[numMaterials-1].szTextureName);
			break;
		case MAT_DIFFUSE:		// 0xA020
			ReadDiffuseColor(&tempChunk);
			break;
		case MAT_TEXMAP:		// 0xA200
			ProcessChunk(&tempChunk);
			break;
		case MAT_TEXFLNM:		// 0xA300
			tempChunk.bytesRead += GetString(pMaterials[numMaterials-1].szTexFileName);
			break;

		//Every other unprocessed ID value will just skip to the end of the chunk
		default:
			SkipChunk(&tempChunk);
		}
		pChunk->bytesRead += tempChunk.length;
	}
}


thx for your time.
Advertisement
Is pChunk->bytesRead initialized to zero before entering the function? If not, this could explain the difference. In debug mode, memory is initialized to a default value, but in release mode it is not.
well,after hours of debugging, I found the line that was causing me the error. I commented it out, and it all seems to work fine. Dunno if I will need that line later on, but thats something I can leave til then. Although I am curious as to why the problem didnt show up in the debug build, if anyways knows, lemme know.
Dave Hunt,

Yes bytesread was initialised to 0. But thx for that info, i will have to keep that in mind.

My problem was here:

void C3DSModel::ReadMeshFaces(stChunk* pChunk){	unsigned int numFaces = 0;	pChunk->bytesRead += fread(&numFaces, 1,2, pFile);	stMesh* mesh = &(pMeshs[numMeshs-1]);	mesh->pFaces = new stFace[numFaces];	mesh->numFaces = numFaces;	struct st3DSFace{ unsigned short pt1,pt2,pt3, visibility;};	st3DSFace *pFaces = new st3DSFace[numFaces];	pChunk->bytesRead += fread(pFaces, 1, numFaces * sizeof(st3DSFace),pFile);	for (int i=0; i<numFaces; i++)	{		mesh->pFaces.vertIndex[0] = pFaces.pt1;		mesh->pFaces.vertIndex[1] = pFaces.pt2;		mesh->pFaces.vertIndex[2] = pFaces.pt3;	}	delete [] pFaces;	//NOTE: This line causes a stack overflow error in a release build.	//This line processes face material, which is a subchunk	//ProcessChunk(pChunk);}


the ProcessChunk causes the error. Some tutorials i've seen online use it, others dont. So for now, i wont use it. Like i said, doesnt seem to matter thus yet.
Well,

after further testing, and a day's worth of looking over my code, I found the problem. Optimisation. My release build was set for speed optimisation. However, these optimisations caused my code to give a stack overflow error. Once I disabled optimisation, my code worked fine. Weird!

Just thought I'd post this, if just to help another n00b like myself so he/she might not waste as much time as i did on a similar error.
Quote:Original post by Chrysaor
Well,

after further testing, and a day's worth of looking over my code, I found the problem. Optimisation. My release build was set for speed optimisation. However, these optimisations caused my code to give a stack overflow error. Once I disabled optimisation, my code worked fine. Weird!

Just thought I'd post this, if just to help another n00b like myself so he/she might not waste as much time as i did on a similar error.


That sounds like you might be recursing too deeply, or that you have a problem that is getting covered over by "slop" in the compiler output. I'm not sure I'd call it solved without knowing for sure which one it is. Just my $0.02USD.
How big is tempChunk? It seems like it will be allocated on the stack for every recursive call. Try allocating it dynamically and verify that you're not processing data redundantly. I think that in a lot of cases you're reading chunks and then just skipping them...
I'd say the most likely problem is you went too deep recursively and overran your stack. Try increasing the stack size and running it again. Actually, i guess it might not be the most likely problem, but certainly the easiest to diagnose.
I think your problem, IIRC is related to the way you are using fread. You specify that you are reading (numFaces * sizeof(st3DSFace)) items of size 1, this is not the case, you should be reading numFaces items of size sizeof(st3DSFace), so I think you need to fix your fread statement. I'm not 100% sure this was what caused my problem, but I'm pretty sure that was the cause.

I do remember however that when debugging, the bytesread variable ended up as some garbage for whatever reason, so if it wasn't what I think it was then it may have been a variable initialisation problem as previously stated, and that is what caused the stack overflow because it ended up trying to read a stupidly high number of bytes (e.g. 3243536574 or something like that).

IIRC the bytesread variable is used in some calculation that is used to skip unknown or unneccessary chunks, and the problem occurs when the bytesread variable is wrong it causes the skipchunk function to mess things up.

Anyhoo, hope that helps!

Steve
Cheers,SteveLiquidigital Online
Ahhh.. no now I remember! The skipchunk function is failing due to one of the reasons I mentioned above, it is basically reading from the middle of a chunk and so when querying for the size of a given chunk, it ends up as a stupid value because it is not reading from the chunk header as it should be. It then tries to read in the chunk using the incorrect chunksize which is what causes the stack overflow! I'm 99% sure that will be the cause of your problem!

*EDIT* Actually thinking about it, as you said it happens in realease and not debug, I may be incorrect in what I was saying. I cannot remember if my own problem was only occuring in release mode, it may have been but I'm not sure, and I would be at a loss to explain why it was happening in one mode and not the other, but my first suspiscion would be either an uninitialized variable, or a locally defined variable going out of scope that should be initialised as a pointer with new. Debug mode will keep the variable alive when it goes out of scope, but release mode deallocates it, so debug mode will continue to work while release mode falls over!

[Edited by - Mephs on May 19, 2005 7:47:19 AM]
Cheers,SteveLiquidigital Online

This topic is closed to new replies.

Advertisement