the application crashes but runs fine with GDB

Hi forum,

I am having a segmentation fault with the tiny application i developed. To track down the problem i ran the app with the gdb and then it runs fine with gdb.

Where should i look into the track down this issue ?

Is there any opengl related debugger ?

Thanks

This is probably an uninitialized variable.

I’m not aware of how gdb handles this, but in general a debug build will initialize local variables whereas a release build will just leave them with whatever was last on the stack, which in most cases is going to be garbage.

Hi

I could not track down the problem. Here goes the code snippet . Probably someone within the forum will be able to track what is wrong with the code:


int main( void )
{
   // Initialise GLFW before using any of its function
   if( !glfwInit() )
   {
      std::cerr << "Failed to initialize GLFW." << std::endl;
      exit(EXIT_FAILURE);
   }
   
   glfwWindowHint(GLFW_SAMPLES, 4);
   //we want the opengl 4
   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
   //we do not want the old opengl
   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
   
   // Open a window and create its OpenGL context
   window = glfwCreateWindow( winWidth, winHeight, "Terrain Tesselation with Displacement Mapping", NULL, NULL);

   if( window == NULL )
   {
      fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 4.3 compatible. Try the 2.1 version of the tutorials.
" );

      //we could not initialize the glfw window
      //so we terminate the glfw
      glfwTerminate();
      exit(EXIT_FAILURE);
   }

   glfwSetErrorCallback(error_callback);
   glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
   glfwSetKeyCallback(window, key_callback);

   //glfwSetMouseButtonCallback(window, mouse_button_callback);
   //glfwSetCursorPosCallback(window, cursor_position_callback);   
   //glfwSetScrollCallback(window, scroll_callback);


   //make the current window context current
   glfwMakeContextCurrent(window);
   glfwSwapInterval(1);

   glfwGetFramebufferSize(window,&winWidth,&winHeight);
   framebuffer_size_callback(window,winWidth,winHeight);
   
   // Initialize GLEW
   glewExperimental = true; // Needed for core profile
   
   if (glewInit() != GLEW_OK)
   {
      fprintf(stderr, "Failed to initialize GLEW
");
      exit(EXIT_FAILURE);
   }

   if(!glewIsSupported("GL_VERSION_4_4"))
   {
      std::cerr << "OpenGL version 4.4 is yet to be supported. " << std::endl;
      exit(1);
   }

   while(glGetError() != GL_NO_ERROR) {}

   //print out information aout the graphics driver
   std::cout << std::endl;
   std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
   std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
   std::cout << "GLEW Verion: " << glewGetString(GLEW_VERSION) << std::endl;
   std::cout << "OpenGL Vendor: " << glGetString(GL_VENDOR) << std::endl;
   std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

   //do the initialization once and only 
   startup();
      
   do{
     render(static_cast<float>(glfwGetTime()));
     // Swap buffers
     glfwSwapBuffers(window);
     glfwPollEvents();
     
   } // Check if the ESC key was pressed or the window was closed
   while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
	  glfwWindowShouldClose(window) == 0 );
   

   //once the following function is called
   //no more events will be dilivered for that
   //window and its handle becomes invalid
   glfwDestroyWindow(window);
   
   // Close OpenGL window and terminate GLFW
   glfwTerminate();

   shutdown();
   
   exit(EXIT_SUCCESS);
}


void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
   float ratio = 1.0f;

   if(height > 0)
      ratio = (float)width / (float)height;

   //setup the viewport
   glViewport(0,0,width,height);

}

void render(float currentTime)
{
  //set the window background clearing color
  static const GLfloat black[] = {0.85f,0.95f,1.0f,1.0f};
  static const GLfloat one = 1.0f;
  static float lastTime = 0.0;
  static float totalTime = 0.0;

  if(!paused)
    totalTime += (currentTime - lastTime);
  lastTime = currentTime;

  float t = (float)totalTime * 0.03f;
  float r = sinf(t * 5.37f) * 15.0f + 16.0f;
  float h = cosf(t * 4.79f) * 2.0f + 3.2f;


  //get the current width and height
  glfwGetFramebufferSize(window,&winWidth,&winHeight);

  //create the viewport with the updated 
  //window width and height
  glViewport(0,0,winWidth,winHeight);

  glClearBufferfv(GL_COLOR,0,black);
  glClearBufferfv(GL_DEPTH,0,&one);

  //define the model-view matrix
  ModelviewMatrix = glm::lookAt(glm::vec3(sinf(t) * r,h,cosf(t) * r),
				glm::vec3(0.0f),
				glm::vec3(0.0f,1.0f,0.0f));
  
  //define the projection matrix
  ProjectionMatrix = glm::perspective(60.0f,
				      (float)winWidth/(float)winHeight,
				      0.1f,
				      1000.0f);
  //calculate the model-view-projection matrix
  ModelviewProjectionMatrix = ProjectionMatrix * ModelviewMatrix;

  //bind the shader 
  shader->Use();
  //set the shader uniforms - to be sent to the shaders

  glUniformMatrix4fv((*shader)("ModelviewMatrix"),1,GL_FALSE,glm::value_ptr(ModelviewMatrix));
  glUniformMatrix4fv((*shader)("ProjectionMatrix"),1,GL_FALSE,glm::value_ptr(ProjectionMatrix));
  glUniformMatrix4fv((*shader)("ModelviewProjectionMatrix"),1,GL_FALSE,glm::value_ptr(ModelviewProjectionMatrix));
  glUniform1f((*shader)("dmapDepth"),enableDisplacement ? dmapDepth : 0.0f);
  glUniform1i((*shader)("enableFog"),enableFog ? 1 : 0);

  glUniform1i((*shader)("texDisplacement"),0);
  glUniform1i((*shader)("texColor"),1);


  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  if(wireframe)
    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  else
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);


  glDrawArraysInstanced(GL_PATCHES,0,4,64 * 64);
  
  //unbind the shader
  shader->UnUse();
         
}

void startup()
{
  //initialize some of the global variables
  enableDisplacement = true;
  wireframe = false;
  enableFog = true;
  paused = false;

  //load the shaders
  loadShaders();
  
  //load the geometry of the triangle
  loadGeometry();
  
  //load the texture  - normal map
  textureDisplacementID = loadTexture(normalmapfilename);
      
  //now load the color texture
  textureColorID = loadTexture(colortexturefilename);

  glActiveTexture(GL_TEXTURE1);
}



GLuint loadTexture(const string &filename)
{
  GLuint textureID;
 
  //load the image using SOIL image library
  int texture_width = 0, texture_height = 0, channels = 0;
  
  GLubyte* pData = SOIL_load_image(filename.c_str(),
				   &texture_width,
				   &texture_height,
				   &channels,
				   SOIL_LOAD_AUTO);
  
  if(pData == NULL)
    {
      cerr<<"Cannot load image: "<<filename.c_str()<<endl;
      exit(EXIT_FAILURE);
    }

  
  //vertically flip the image on Y axis since it is inverted
  int i,j;
  for( j = 0; j*2 < texture_height; ++j )
    {
      int index1 = j * texture_width * channels;
      int index2 = (texture_height - 1 - j) * texture_width * channels;
      for( i = texture_width * channels; i > 0; --i )
	{
	  GLubyte temp = pData[index1];
	  pData[index1] = pData[index2];
	  pData[index2] = temp;
	  ++index1;
	  ++index2;
	}
    }
  
  
  //setup opengl texture
  
  //generate a name for the texture
  glGenTextures(1, &textureID);

      
  //now bind the name to the context using the GL_TEXTURE_2D binding point
  glBindTexture(GL_TEXTURE_2D,textureID);
  
  GL_CHECK_ERRORS;
  
  //set texture parameters
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
  
  
  //allocate texture memory
  glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB8,texture_width,texture_height);
  
  GL_CHECK_ERRORS;
  
  //specify some data for the texture
  glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);
  //free SOIL image data
  SOIL_free_image_data(pData);
  

  GL_CHECK_ERRORS;
  
  return textureID;
}


void loadGeometry()
{

   GL_CHECK_ERRORS;
   //setup the quad vao
   glGenVertexArrays(1,&vaoID);
   glBindVertexArray(vaoID);
   
   //opengl needs to be told how many vertices from the vertex array
   //to use to make one patch - here 4 vertices make one patch
   glPatchParameteri(GL_PATCH_VERTICES,4);
   
   glEnable(GL_CULL_FACE);

   GL_CHECK_ERRORS;      
}

void loadShaders()
{
   GL_CHECK_ERRORS;
   
   shader = new GLSLShader();


   //load the shader
   shader->LoadFromFile(GL_VERTEX_SHADER, "shaders/dispmap.vert");
   shader->LoadFromFile(GL_TESS_CONTROL_SHADER, "shaders/dispmap.tcs");
   shader->LoadFromFile(GL_TESS_EVALUATION_SHADER, "shaders/dispmap.tes");
   shader->LoadFromFile(GL_FRAGMENT_SHADER, "shaders/dispmap.frag");

   //compile and link shader
   shader->CreateAndLinkProgram();
   shader->Use();

   shader->AddUniform("ModelviewMatrix");
   shader->AddUniform("ModelviewProjectionMatrix");
   shader->AddUniform("ProjectionMatrix");
   shader->AddUniform("dmapDepth");
   shader->AddUniform("enableFog");

   shader->AddUniform("texDisplacement");
   shader->AddUniform("texColor");

   dmapDepth = 6.0f;

   shader->UnUse();
   
   GL_CHECK_ERRORS;

}

Please let me know if there is anything missing

Hi forum,

I found at which point the application crashes, but did not find the reason behind it. Here i need your help ,folks. I am loading two texture image one after another as follows:


void startup()
{
  //initialize some of the global variables
  enableDisplacement = true;
  wireframe = false;
  enableFog = true;
  paused = false;

  //load the shaders
  loadShaders();
  
  //load the geometry of the triangle
  loadGeometry();
  
  //load the texture  - normal map
  textureDisplacementID = loadTexture(normalmapfilename);

  glActiveTexture(GL_TEXTURE1);
      
  //now load the color texture
  textureColorID = loadTexture(colortexturefilename);
  
}


The application executes fine with the first texture loading. But it crashes with the second texture loading :


textureColorID = loadTexture(colortexturefilename);

Now lets get inside the texture loading function:


GLuint loadTexture(const string &filename)
{
  GLuint textureID;
 
  //load the image using SOIL image library
  int texture_width = 0, texture_height = 0, channels = 0;
  
  GLubyte* pData = SOIL_load_image(filename.c_str(),
				   &texture_width,
				   &texture_height,
				   &channels,
				   SOIL_LOAD_AUTO);
  
  if(pData == NULL)
    {
      cerr<<"Cannot load image: "<<filename.c_str()<<endl;
      exit(EXIT_FAILURE);
    }

  std::cout << "Texture width: " << texture_width
	    << "Texture height: " << texture_height
	    << "channels: " << channels
	    << std::endl;

  
  //vertically flip the image on Y axis since it is inverted
  int i,j;
  for( j = 0; j*2 < texture_height; ++j )
    {
      int index1 = j * texture_width * channels;
      int index2 = (texture_height - 1 - j) * texture_width * channels;

      for( i = texture_width * channels; i > 0; --i )
	{
	  GLubyte temp = pData[index1];
	  pData[index1] = pData[index2];
	  pData[index2] = temp;

	  ++index1;
	  ++index2;
	}
    }
  
  
  //setup opengl texture
  
  //generate a name for the texture
  glGenTextures(1, &textureID);

      
  //now bind the name to the context using the GL_TEXTURE_2D binding point
  glBindTexture(GL_TEXTURE_2D,textureID);
  
  GL_CHECK_ERRORS;
  
  //set texture parameters
  
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
  
  
  //allocate texture memory
  glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB8,texture_width,texture_height);
  
  GL_CHECK_ERRORS;
  
  //specify some data for the texture
  glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);
  //free SOIL image data
  SOIL_free_image_data(pData);
  

  GL_CHECK_ERRORS;
  
  return textureID;
}


Any idea what is wrong with the above function ?

Thanks

At this stage I’d be single-stepping the offending function and inspecting variable values to determine what’s going wrong.

Thanks for the hint!

I stepped through each line and i found the i am having the crash with following call for the second time:


 //specify some data for the texture
  glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texture_width,texture_height,GL_RGB,GL_UNSIGNED_BYTE,pData);

I am creating two texture objects. Each texture object load one image . The first one went fine and i am having the crash with the second one.

The image that I am loading is a .png image , i have the checked the width, height and number of channels within the image. The channels value is 3 .

Lets go through all the parameters within the above function:

target - GL_TEXTURE_2D
level - 0, since it is the base image level.
xoffset - 0
yoffset - 0
width - accessed through the image loading library
height - accessed through the image loading library
format - GL_RGB
type - GL_UNSIGNED_BYTE - i am not so sure about it
pixels - data that is loaded with the image loading library

What else do i need to check that causes the crash with the above function ?

Any more hints ?

Thanks

This shouldn’t cause a crash, but is (width * numchannels) a multiple of 4? Since you’re loading as GL_RGB it’s quite possible that it isn’t, in which case you need to set glPixelStorei appropriately.

I’d run valgrind on your app. It’ll catch many memory abuses, and provide you a stack trace of exactly where the offending code is (and where the code it’s operating on was allocated if heap memory).

Thanks mhagain,

The hint helped. It worked fine after the inclusion of


glPixelStorei(GL_UNPACK_ALIGNMENT,1);

I went through the documentation, and it is confusing. Some explanation within this context would be helpful.

Anyone?

Thanks

The best explanation is the one available here: http://www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads

In simpler terms, it crashed because glTexImage2D was trying to read from your source data in blocks of 4 bytes at a time (the default behaviour) but because your row width (in bytes) wasn’t a multiple of 4, for each row it would read a little bit beyond the end, until eventually you get a buffer overflow.

Typically you never see mention of this in older documentation or tutorials, and you never see older source code taking account of it, because older hardware was restricted to power-of-two sized textures, which would generally satisfy the requirement. Taking this older material and trying to use arbitrary-sized textures with it is a recipe for disaster.

I recommend bookmarking that “Common Mistakes” page, by the way: it’s a goldmine.