PDA

View Full Version : the application crashes but runs fine with GDB



sajis997
09-16-2014, 10:43 AM
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

mhagain
09-16-2014, 10:48 AM
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.

sajis997
09-16-2014, 11:15 AM
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.\n" );

//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,winHeigh t);

// Initialize GLEW
glewExperimental = true; // Needed for core profile

if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
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(ModelviewProjectionMat rix));
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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,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_wid th,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

sajis997
09-17-2014, 02:11 AM
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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,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_wid th,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

mhagain
09-17-2014, 04:34 AM
At this stage I'd be single-stepping the offending function and inspecting variable values to determine what's going wrong.

sajis997
09-17-2014, 10:24 AM
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

mhagain
09-17-2014, 02:02 PM
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.

Dark Photon
09-19-2014, 05:07 PM
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).

sajis997
09-20-2014, 01:47 AM
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

mhagain
09-20-2014, 03:54 AM
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.