Sign in to follow this  

Reasons for instant crashes in Release mode?

This topic is 4200 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently working on a student game project with 5 other team members. In the current build, the game is able to run in debug no problem, but instantly crashes when compiled and ran in release mode. I think I narrowed the problem down to after a certain amount of dynamically allocated memory is allocated it crashes (so it's technically crashing in the initialization stages). I'm pretty sure that is the reason it's crashing, but why? Then again I could be wrong about the reason its crashing all together. The more odd part is that my other team members are able to run the game in release mode, but my computer is always consistant with never working in release mode. We all are using the same exact hardware to build the game on (nx9600 laptops).

Share this post


Link to post
Share on other sites
So the debug buils works fine for everyone, but the release build will not work for you (but the same exe is fine for everyone else). What specs is your computer. Can you show us the allocation code you think may be causing it?

Share this post


Link to post
Share on other sites
Usually problems that pop up using a Release build that are not apparent in Debug builds are related to uninitialized variables... double check them, but it would be weird that it works flawlessly for others but not you...

Cheers

Share this post


Link to post
Share on other sites
The build doesn't work "flawlessly" for other team members, but they are able to run the game for a minute or so until it crashes in some random parts of the program (sometimes in the particles, sometime in the collision tree, etc.)

I think the problem might be in the texture manager when it loads in the textures (specifically in the .tga loading part). I know it's a lot of code, sorry for that.

(We're using OpenGL)



AUX_RGBImageRec * CTextureManager::LoadBMP(char *Filename)
{
FILE *File=NULL;

if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");

if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}

return NULL;
}

// This function returns an integer that is a handle to the texture
GLuint CTextureManager::LoadGLTextures(char * Filename, bool MipMap, char FileType)
{
TextureInfo * newtext = NULL;

AUX_RGBImageRec *TextureImage[1];

for(unsigned int i = 0; i < m_vTextures.size(); i++)
{
if(!strcmp(m_vTextures[i]->file, Filename))
return m_vTextures[i]->Texture;
}

if(FileType == FT_UFINDOUT)
{
unsigned char len = (unsigned char)strlen(Filename);
if(!strncmp(&Filename[len - 3], "tga", 3) || !strncmp(&Filename[len - 3], "TGA", 3))
FileType = FT_TGA;
else
FileType = FT_BMP;
}

switch(FileType)
{
case FT_BMP:
{
if (TextureImage[0]=LoadBMP(Filename))
{
newtext = new TextureInfo;
newtext->file = new char[strlen(Filename)+1];
strncpy(newtext->file, Filename, strlen(Filename)+1);
m_vTextures.push_back(newtext);

glGenTextures(1, &newtext->Texture);

if(MipMap)
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}

if (TextureImage[0])
{
if (TextureImage[0]->data)
{
free(TextureImage[0]->data);
}
free(TextureImage[0]);
}
}
break;
case FT_TGA:
{
FILE *pFile; // File pointer
TGAHEADER tgaHeader; // TGA file header
unsigned long lImageSize; // Size in bytes of image
short sDepth; // Pixel depth;
GLbyte *pBits = NULL; // Pointer to bits

// Default/Failed values
int iWidth = 0;
int iHeight = 0;
int eFormat = GL_BGR_EXT;
int iComponents = GL_RGB8;

// Attempt to open the fil
pFile = fopen(Filename, "rb");
if(pFile == NULL)
return NULL;

// Read in header (binary)
fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile);


// Get width, height, and depth of texture
iWidth = tgaHeader.width;
iHeight = tgaHeader.height;
sDepth = tgaHeader.bits / 8;

// Put some validity checks here. Very simply, I only understand
// or care about 8, 24, or 32 bit targa's.
if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32)
return NULL;

// Calculate size of image buffer
lImageSize = tgaHeader.width * tgaHeader.height * sDepth;

// Allocate memory and check for success
pBits = (GLbyte *)malloc(lImageSize * sizeof(GLbyte));
if(pBits == NULL)
return NULL;

// Read in the bits
// Check for read error. This should catch RLE or other
// weird formats that I don't want to recognize
if(fread(pBits, lImageSize, 1, pFile) != 1)
{
free(pBits);
return NULL;
}

// Set OpenGL format expected
switch(sDepth)
{
case 3: // Most likely case
eFormat = GL_BGR_EXT;
iComponents = GL_RGB8;
break;
case 4:
eFormat = GL_BGRA_EXT;
iComponents = GL_RGBA8;
break;
case 1:
eFormat = GL_LUMINANCE;
iComponents = GL_LUMINANCE8;
break;
};


// Done with File
fclose(pFile);

newtext = new TextureInfo;
newtext->file = new char[strlen(Filename)+1];
strncpy(newtext->file, Filename, strlen(Filename)+1);
m_vTextures.push_back(newtext);

glGenTextures(1, &newtext->Texture);

if(MipMap)
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}
break;
}

if(newtext)
return newtext->Texture;
else
return -1;
}



[Edited by - BalkMan on June 15, 2006 9:21:01 AM]

Share this post


Link to post
Share on other sites
Just a reminder: the code tags are [ source ] and [ source ] (without spaces):

AUX_RGBImageRec * CTextureManager::LoadBMP(char *Filename)
{
FILE *File=NULL;

if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");

if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}

return NULL;
}

// This function returns an integer that is a handle to the texture
GLuint CTextureManager::LoadGLTextures(char * Filename, bool MipMap, char FileType)
{
TextureInfo * newtext = NULL;

AUX_RGBImageRec *TextureImage[1];

for(unsigned int i = 0; i < m_vTextures.size(); i++)
{
if(!strcmp(m_vTextures[i]->file, Filename))
return m_vTextures[i]->Texture;
}

if(FileType == FT_UFINDOUT)
{
unsigned char len = (unsigned char)strlen(Filename);
if(!strncmp(&Filename[len - 3], "tga", 3) || !strncmp(&Filename[len - 3], "TGA", 3))
FileType = FT_TGA;
else
FileType = FT_BMP;
}

switch(FileType)
{
case FT_BMP:
{
if (TextureImage[0]=LoadBMP(Filename))
{
newtext = new TextureInfo;
newtext->file = new char[strlen(Filename)+1];
strncpy(newtext->file, Filename, strlen(Filename)+1);
m_vTextures.push_back(newtext);

glGenTextures(1, &newtext->Texture);

if(MipMap)
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}

if (TextureImage[0])
{
if (TextureImage[0]->data)
{
free(TextureImage[0]->data);
}
free(TextureImage[0]);
}
}
break;
case FT_TGA:
{
FILE *pFile; // File pointer
TGAHEADER tgaHeader; // TGA file header
unsigned long lImageSize; // Size in bytes of image
short sDepth; // Pixel depth;
GLbyte *pBits = NULL; // Pointer to bits

// Default/Failed values
int iWidth = 0;
int iHeight = 0;
int eFormat = GL_BGR_EXT;
int iComponents = GL_RGB8;

// Attempt to open the fil
pFile = fopen(Filename, "rb");
if(pFile == NULL)
return NULL;

// Read in header (binary)
fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile);


// Get width, height, and depth of texture
iWidth = tgaHeader.width;
iHeight = tgaHeader.height;
sDepth = tgaHeader.bits / 8;

// Put some validity checks here. Very simply, I only understand
// or care about 8, 24, or 32 bit targa's.
if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32)
return NULL;

// Calculate size of image buffer
lImageSize = tgaHeader.width * tgaHeader.height * sDepth;

// Allocate memory and check for success
pBits = (GLbyte *)malloc(lImageSize * sizeof(GLbyte));
if(pBits == NULL)
return NULL;

// Read in the bits
// Check for read error. This should catch RLE or other
// weird formats that I don't want to recognize
if(fread(pBits, lImageSize, 1, pFile) != 1)
{
free(pBits);
return NULL;
}

// Set OpenGL format expected
switch(sDepth)
{
case 3: // Most likely case
eFormat = GL_BGR_EXT;
iComponents = GL_RGB8;
break;
case 4:
eFormat = GL_BGRA_EXT;
iComponents = GL_RGBA8;
break;
case 1:
eFormat = GL_LUMINANCE;
iComponents = GL_LUMINANCE8;
break;
};


// Done with File
fclose(pFile);

newtext = new TextureInfo;
newtext->file = new char[strlen(Filename)+1];
strncpy(newtext->file, Filename, strlen(Filename)+1);
m_vTextures.push_back(newtext);

glGenTextures(1, &newtext->Texture);

if(MipMap)
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}
break;
}

if(newtext)
return newtext->Texture;
else
return -1;
}

Share this post


Link to post
Share on other sites
I didn't read it all, but seriously check out your constructors to see if you initializing all your member variables. Uninitialized pointers can point to anywhere in the memory and uninitialized floats can result in "Not a Number" (NaN) values...

As for lines like :

if(!strncmp(&Filename[len - 3], "tga", 3) || !strncmp(&Filename[len - 3], "TGA", 3))

you should use strnicmp, as it will simply ignore the case

Hope this helps

Share this post


Link to post
Share on other sites
I found it!

in this part of the texture loader...


if(MipMap)
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, newtext->Texture);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
free(pBits);



I forgot the free(pBits); !!!

man those were really unhelpful crashes i got... but at least we found the cause. Thanks for everyone's help so far.

Share this post


Link to post
Share on other sites
If you're writing member functions, you're writing C++, at least nominally: and if you're writing C++ nominally, you may as well do it for real. The language, and standard library, provide many tools that have been carefully designed by a large number of smart people (and the implementations refined continually since the interfaces were standardized in 1998) specifically to help avoid memory management problems of the sort that led to your crash. In particular, working with char*'s to hold textual data is a veritable mine field - save yourself headaches and disasters-waiting-to-happen, and use std::string.

Oh, and by the way, reordering 3 case statements to put the "most likely" one first is unlikely to make a difference, and extremely unlikely to make a *significant* difference. Realistically, any time spent performing one or two extra branches there is going to be several orders of magnitude less time than what is spent processing all those OpenGL calls and the file I/O. If it was for code readability reasons, ask yourself why the reader should *care* which case is most common :\

Share this post


Link to post
Share on other sites

This topic is 4200 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this