Segment Fault error - libpng

I seem to be getting a segment fault error from one of my methods that uses libpng. I have ran the gode in gdb and got the following trace:


Thread 1 "clockProject" received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:38
38	../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.
(gdb) bt
#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:38
#1  0x00007ffff2e224de in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#2  0x00007ffff2e228d2 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#3  0x00007ffff2e23342 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#4  0x00007ffff2e860ed in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#5  0x00007ffff2e87d10 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#6  0x00007ffff2e12717 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#7  0x00007ffff2e141a0 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#8  0x0000000000402ceb in loadTexture(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int&, int&) ()
#9  0x0000000000404868 in init() ()
#10 0x0000000000404eed in keyboard(unsigned char, int, int) ()
#11 0x00007ffff7bafd1f in glutMainLoopEvent () from /usr/lib/x86_64-linux-gnu/libglut.so.3
#12 0x00007ffff7bb0145 in glutMainLoop () from /usr/lib/x86_64-linux-gnu/libglut.so.3
#13 0x0000000000404fa3 in main ()

The method in question is loadTexture:


GLuint loadTexture(std::string filename, int &width, int &height) 
 {
 	GLuint TEXTURE_LOAD_ERROR = 0;

   //header for testing if it is a png
   png_byte header[8];
 
   //open file as binary
   FILE *fp = fopen(filename.c_str(), "rb");
   if (!fp) {
     return TEXTURE_LOAD_ERROR;
   }
 
   //read the header
   fread(header, 1, 8, fp);
 
   //test if png
   int is_png = !png_sig_cmp(header, 0, 8);
   if (!is_png) {
     fclose(fp);
     return TEXTURE_LOAD_ERROR;
   }
 
   //create png struct
   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
       NULL, NULL);
   if (!png_ptr) {
     fclose(fp);
     return (TEXTURE_LOAD_ERROR);
   }
 
   //create png info struct
   png_infop info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr) {
     png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
     fclose(fp);
     return (TEXTURE_LOAD_ERROR);
   }
 
   //create png info struct
   png_infop end_info = png_create_info_struct(png_ptr);
   if (!end_info) {
     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
     fclose(fp);
     return (TEXTURE_LOAD_ERROR);
   }
 
   //png error stuff, not sure libpng man suggests this.
   if (setjmp(png_jmpbuf(png_ptr))) {
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     fclose(fp);
     return (TEXTURE_LOAD_ERROR);
   }
 
   //init png reading
   png_init_io(png_ptr, fp);
 
   //let libpng know you already read the first 8 bytes
   png_set_sig_bytes(png_ptr, 8);
 
   // read all the info up to the image data
   png_read_info(png_ptr, info_ptr);
 
   //variables to pass to get info
   int bit_depth, color_type;
   png_uint_32 twidth, theight;
 
   // get info about png
   png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
       NULL, NULL, NULL);
 
   //update width and height based on png info
   width = twidth;
   height = theight;
 
   // Update the png info struct.
   png_read_update_info(png_ptr, info_ptr);
 
   // Row size in bytes.
   int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
   // Allocate the image_data as a big block, to be given to opengl
   png_byte *image_data = new png_byte[rowbytes * height];
   if (!image_data) {
     //clean up memory and close stuff
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     fclose(fp);
     return TEXTURE_LOAD_ERROR;
   }
 
   //row_pointers is for pointing to image_data for reading the png with libpng
   png_bytep *row_pointers = new png_bytep[height];
   if (!row_pointers) {
     //clean up memory and close stuff
     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     delete[] image_data;
     fclose(fp);
     return TEXTURE_LOAD_ERROR;
   }
   // set the individual row_pointers to point at the correct offsets of image_data
   for (int i = 0; i < height; ++i)
     row_pointers[height - 1 - i] = image_data + i * rowbytes;
 
   //read the png into image_data through row_pointers
   png_read_image(png_ptr, row_pointers);
 
   //Now generate the OpenGL texture object
   GLuint texture;
   glGenTextures(1, &texture);
   glBindTexture(GL_TEXTURE_2D, texture);
   glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, width, height, 0,
       GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) image_data);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
   //clean up memory and close stuff
   png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
   delete[] image_data;
   delete[] row_pointers;
   fclose(fp);
 
   return texture;
 }

This method is called from init() , which is re-called every time I press the ‘i’ key, I am using this as an odd way of changing my textures;

init():


void init()
{
	int width, height;

	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity();
	gluOrtho2D(0, 512, 0, 512);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

	if(texture_Increment > 3)
		texture_Increment = 1;

	switch (texture_Increment)
	{
		case 1: an_face_texture = loadTexture("images/planeClockFace.png", width, height);
				hour_hand_texture = loadTexture("images/planeHand.png", width, height); x_hourScale = 100.0f; y_hourScale = 75.0f;
				min_hand_texture = loadTexture("images/planeHand.png", width, height); x_minScale = 100.0f; 
				sec_hand_texture = loadTexture("images/planeHand.png", width, height); x_secScale = 75.0f;
				r_value = 0;
				g_value = 0;
				b_value = 0;
				break;
		case 2:	an_face_texture = loadTexture("images/NuklearClockFace.png", width, height); 
				hour_hand_texture = loadTexture("images/spaceHourHand.png", width, height); x_hourScale = 250.0f; y_hourScale = 75.0f;
				min_hand_texture = loadTexture("images/spaceMinHand.png", width, height); x_minScale = 250.0f;
				sec_hand_texture = loadTexture("images/planeHandSec.png", width, height); x_secScale = 75.0f;
				r_value = 134;
				g_value = 146;
				b_value = 158;
				break;
		case 3: an_face_texture = loadTexture("images/SymbolClockFace.png", width, height); 
				hour_hand_texture = loadTexture("images/SymbolMinHand.png", width, height); x_hourScale = 200.0f; y_hourScale = 60.0f;
				min_hand_texture = loadTexture("images/SymbolMinHand.png", width, height); x_minScale = 200.0f;
				sec_hand_texture = loadTexture("images/planeHandSec.png", width, height); x_secScale = 75.0f;
				r_value = 250;
				g_value = 250;
				b_value = 250;
				break;
	}

	//The office background texture
	background_texture = loadTexture("images/office-wall.png", width, height);

	digital_face = make_digital_face();
	background_wall = make_background_wall();
	stopwatch_button = make_stopwatch_button();
	an_clockface = make_an_clockface();
	hour_hand = make_hour_hand();
	min_hand = make_min_hand();
	sec_hand = make_sec_hand();
	digital_day = make_digitalDay_container();

	glutPostRedisplay();
}

The segement fault happens when I press ‘i’ for the second time, I just can’t figure out why it’s happening.

Comment out the GL calls in loadTexture(). If it still crashes in loadTexture(), your problem doesn’t appear to pertain to OpenGL. If it doesn’t crash, then the GL calls may be related. If so, verify you have an active OpenGL context.

In any case, you can get more info on your problem if you compile -g and then run your app under valgrind (“valgrind YOURAPP”).