Very strange bug...

Hi everybody!

I have a function which loads up an Image, and makes it a gl texture. It then returns the GLuint value.

The calling code stores this value, and then later uses it to draw textured objects on screen. The whole thing is in 2d space, and every aspect of this works.

I then wrote some more functions to my library, tested two, and got them working. But now something seems to be wrong with my image loading code.

Basically, unless I printf the returned values of the function( the one that loads the image ) - after storing them into variables (the printf output is correct by the looks of it - I load 2 textures, with returned GLuints of 1 & 2 respectivly), my program kicks a Segmentation error, and doesnt run at all!!

      --- I have even tried adding a printf as the first line of my main(), to just print some basic text before doing anything. But if I dont printf the two returned values, even this doesnt work!! Arrrrrrrrrr

Any help people?

Thank you.

:’(

Care to post some code?

Sure, heres the image loader:


GLuint	globLoadImage( char* globsFileName, unsigned int globuiWidth, unsigned int globuiHeight, int globiTrans )
{
	/*Some nice var */
	FILE	*imageFile;
	GLubyte	*data, *dataRGBA;			/* Holds data, as we load it. &One for transparency	*/
	unsigned long size, i, j, k, l;		/* For da claculizzle								*/
    unsigned short int planes;          /* number of planes in image (must be 1)			*/
    unsigned short int bpp;             /* number of bits per pixel (must be 24)			*/
	unsigned int	chkDimension;		/* Var to check dimensions & make sure standard		*/
    char temp;                          /* temporary color storage for bgr-rgb conversion.	*/
	GLuint	texture;					/* holds the texture ID that we send back.			*/

	/* does file exist? */
	if(( imageFile = fopen( globsFileName, "rb" )) == NULL )
	{
		globLog( "[globLoadImage@globEng]: File Not Found! %s 
\
							Does it exist?
", globsFileName );
		return FALSE; //Cant go any further tbh
	}
	
	/* get width height from header, seek to. */
	fseek( imageFile, 18, SEEK_CUR );
	
	if(( i = fread( &chkDimension, 4, 1, imageFile )) != TRUE )
	{
		globLog( "[globLoadImage@globEng]: Error reading width of: %s 
\
							File could be corrupt.
", globsFileName );
		return FALSE;
	}
	if( chkDimension != globuiWidth )
	{
		globLog( "[globLoadImage@globEng]: Wrong image width: is %d, should be %u; from %s
", 
			chkDimension, globuiWidth, globsFileName );
		
		return FALSE;
	}
	
	if(( i = fread( &chkDimension, 4, 1, imageFile )) != TRUE )
	{
		globLog( "[globLoadImage@globEng]: Error reading height of: %s 
\
							File could be corrupt.
", globsFileName );
		return FALSE;
	}
	if( chkDimension != globuiHeight )
	{
		globLog( "[globLoadImage@globEng]: Wrong image height: is %d, should be %u; from %s
", 
			chkDimension, globuiHeight, globsFileName );
		
		return FALSE;
	}
	printf( "Dimensions: %ux%u
", globuiWidth, globuiHeight );
	
	/* Get the # planes from file */
	if(( i = fread( &planes, 2, 1, imageFile )) != TRUE)
	{
		globLog( "[globLoadImage@globEng]: Unable to read #planes from: %s 
\
							File could be corrupt.
", globsFileName );
		return FALSE;
	}
	if( planes != 1 )		/* check for errors */
	{
		globLog( "[globLoadImage@globEng]: Planes not 1 in: %s", globsFileName );
		return FALSE;
	}
	
	/* And now bbp data */
	if(( i = fread( &bpp, 2, 1, imageFile )) != TRUE )
	{
		globLog( "[globLoadImage@globEng]: Could not read bpp from %s
\
							File could be corrupt.", globsFileName );
		return FALSE;
	}
	if( bpp != 24 )
	{
		globLog( "[globLoadImage@globEng]: Invalid bpp (!24) in: %s
\
							File could be corrupt.", globsFileName );
		return FALSE;
	}

	/* Get to the data, allocate memory and load :) */
	fseek( imageFile, 24, SEEK_CUR );

	/* Calculate image size, */
	size = globuiWidth * globuiHeight * (bpp/8);
	data = ( GLubyte* ) malloc( size );
	i = globuiWidth * globuiHeight * (32/8);
	dataRGBA = ( GLubyte* ) malloc( i );
	
	printf( "bpp: %d bits or %d bytes, size: %d 
", bpp, bpp/8, size );
	if(( data == NULL )||( dataRGBA == NULL ))		//Has it worked?
	{
		globLog( "[globLoadImage@globEng]: Could not allocate memory for image.
" );
		return FALSE;
	}

    if (( i = fread( data, size, 1, imageFile )) != 1 ) 
	{
		globLog( "[globLoadImage@globEng]: Error reading image data from %s.
", globsFileName );
		return FALSE;
    }

	/* reverse colours */
	for ( i=0; i< size; i+=3 )
	{
		temp = data[i];
		data[i] = data[i+2];
		data[i+2] = temp;
	}
	
	if( globiTrans ) /* If transparency conversion, white = transparent */
	{
		for( i=0, l=0, k=0; i<globuiHeight; i++ )
		{
			for( j=0; j<globuiWidth; j++ )
			{
				if(( data[l] == 255 )&&( data[l+1] == 255 )&&( data[l+2] == 255 ))
				{
					dataRGBA[k++] = data[l++];	//R
					dataRGBA[k++] = data[l++];	//G
					dataRGBA[k++] = data[l++];	//B
					dataRGBA[k++] = 0;			//A
					//printf( "k=%d, l=%d, a=%d
", k, l, dataRGBA[k-1] );
				} else {
					dataRGBA[k++] = data[l++];
					dataRGBA[k++] = data[l++];
					dataRGBA[k++] = data[l++];
					dataRGBA[k++] = 255;
					//printf( "k=%d, l=%d, a=%d
", k, l, dataRGBA[k-1] );
				}
			}
		}
	} else { /* Otherwise, build RGBA image anyway, but full alpha ;P */
		for( i=0, l=0, k=0; i<globuiHeight; i++ )
		{
			for( j=0; j<globuiWidth; j++ )
			{
				dataRGBA[k++] = data[l++];
				dataRGBA[k++] = data[l++];
				dataRGBA[k++] = data[l++];
				dataRGBA[k++] = 255;
			}
		}
	}

    /*
	 * And now convert to GL texture, straight away
	 */
	glGenTextures( 1, &texture );
	glBindTexture( GL_TEXTURE_2D, texture );
	
	/* Set up environement var, tweak these, want white == transparent I say :D */
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

	/* And now, finally build it */
	gluBuild2DMipmaps( GL_TEXTURE_2D, 4, globuiWidth, globuiHeight, GL_RGBA, GL_UNSIGNED_BYTE, dataRGBA );
	
	free( data );
	free( dataRGBA );
	
	return texture;
}

And heres an extract that calls it…


GLuint txA, txB, txF;

//...

//Function to draws stuff on screen
void gogogo()
{
	globDrawImage( txB, -1, -1, 1, 1 );
	
	xpos= -1.0;
	for( xpos = -1.0; xpos <= 1.0; xpos+= 0.1 )
	{
		globDrawImage( txA, xpos, ypos, (xpos+0.1), (ypos+0.1) );
	}
	if( xpos>1.0) xpos = -1.0;
	
	glColor3f(1.0f, 0.0f, 1.0f );

	globPrint( txF, -0.07, 0.0, "Yhea!!!" );

	glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
	
	globRefresh();
}

int main(int argc, char **argv) 
{  	

// (... - glut make window/ init gl, and all that)

txA = globLoadImage( "Data/Img/floor2.bmp", 64, 64, 1 );
	txB = globLoadImage( "Data/Img/testBackground1.bmp", 800, 600, 0 );	
	txF = globMakeFont( "-*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1", "variable" );

//(... glut function bind etc)

	glutMainLoop();
  return 0;
}

Thanks :slight_smile:

Hmmm… well, a bit of gdb seems to reveal:

117 glutMainLoop();
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0xb7d5a0b9 in malloc_consolidate () from /lib/libc.so.6
(gdb) bt
#0 0xb7d5a0b9 in malloc_consolidate () from /lib/libc.so.6
#1 0xb7d5c0cd in _int_malloc () from /lib/libc.so.6
#2 0xb7d5e18c in malloc () from /lib/libc.so.6
#3 0xb7bc18b0 in _xcb_in_read () from /usr/lib/libxcb.so.1
#4 0xb7bc029a in _xcb_conn_wait () from /usr/lib/libxcb.so.1
#5 0xb7bc2155 in xcb_wait_for_reply () from /usr/lib/libxcb.so.1
#6 0xb7c43b11 in _XReply () from /usr/lib/libX11.so.6
#7 0xb7c8f9de in _XkbHandleGetMapReply () from /usr/lib/libX11.so.6
#8 0xb7c903f8 in XkbGetUpdatedMap () from /usr/lib/libX11.so.6
#9 0xb7c904ee in XkbGetMap () from /usr/lib/libX11.so.6
#10 0xb7c8bea9 in _XkbLoadDpy () from /usr/lib/libX11.so.6
#11 0xb7c8c737 in XkbLookupKeySym () from /usr/lib/libX11.so.6
#12 0xb7c8c7f4 in XLookupString () from /usr/lib/libX11.so.6
#13 0xb7f4a39c in glutMainLoopEvent () from /usr/lib/libglut.so.3
#14 0xb7f4a8cc in glutMainLoop () from /usr/lib/libglut.so.3
#15 0x0804b6e9 in main (argc=1, argv=0x1) at tester.c:117

Not sure if this help… will carry on with gdb I think. Also, no magic printf in that there^.

Also, I have tried allocating memory to the texture variables, before calling image load - just incase, using GLuint data type ofc, and even unsigned int, but still no luck :frowning:

this doesnt sound like OpenGL issue. crashes are the easiest things to handle imho. the debugger should show you the callstack where you can step back to globLoadImage() and see which line produces the exception. obsereving it and steping through the load function should fix this pretty quick.

Yesm yes you were right. It was 2 actually, which seem to have managed to run to my drawing part of the code!

Well, thats working now, of course now there are different bugs to sort, but none seem to be with my gl sections :slight_smile:

Thanks anyhow.