Reputation: 6778
I have the following code, taken from part of an OpenGL application I'm working on. GDB reports that the code segfaults immediately when calling glfwInit()
. The strange thing is, if I change the value of height
to 256 (or at least, anything so height
< 512), the segfault disappears.
#include <GL/glew.h>
#include <GL/glfw.h>
static const size_t width = 512;
static const size_t height = 512;
int main(int argc, char const *argv[])
{
glfwInit();
glfwOpenWindow(1080, 720, 8, 8, 8, 0, 32, 0, GLFW_WINDOW);
glewInit();
float heightmap[width * height * 3];
for (size_t i = 0, ix = 0; i < width; i++) {
for (size_t j = 0; j < height; j++) {
float noise = 0.0f;
heightmap[ix++] = (float)i;
heightmap[ix++] = noise;
heightmap[ix++] = (float)j;
}
}
const int numIndices = (width - 1) * (height - 1) * 6;timd
GLuint indices[numIndices];
for (size_t i = 0, ix = 0; i < width - 1; i++) {
for (size_t j = 0; j < height - 1; j++) {
indices[ix++] = (i + 0) + (j + 0) * width;
indices[ix++] = (i + 1) + (j + 0) * width;
indices[ix++] = (i + 0) + (j + 1) * width;
indices[ix++] = (i + 0) + (j + 1) * width;
indices[ix++] = (i + 1) + (j + 0) * width;
indices[ix++] = (i + 1) + (j + 1) * width;
}
}
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, width * height * 3 * sizeof(float), heightmap, GL_STATIC_DRAW);
GLuint ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(GLuint), indices, GL_STATIC_DRAW);
do {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, NULL);
glfwSwapBuffers();
} while(glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ebo);
glfwCloseWindow();
glfwTerminate();
return 0;
}
the backtrace from GDB shows
#0 0x00000000004009d7 in main (argc=<error reading variable: Cannot access memory at address 0x7fffff6fe41c>, argv=<error reading variable: Cannot access memory at address 0x7fffff6fe410>) at segfault.c:8
I'm compiling with gcc -g -o segfault segfault.c -lGL -lGLEW -lglfw
.
I'm stumped as to what is causing this error, I don't understand why changing the value of height
affects the segfault.
EDIT: posted more code. segfault still occurs with width/height at 512 but runs fine at 256.
Upvotes: 1
Views: 2304
Reputation: 793
You end up allocating 9437184 bytes of data on the stack. 9.43 MB. This is a lot of memory in one stack frame, and possibly more than your environment allows for the entire stack.
To be honest I'm not sure what the precise issue is, but since you mention a smaller height value fixes everything (cutting height in half gives ~4.7 MB) I think this is the issue. At least, 5MB seems sorta reasonable for stack size though I've read the default for Visual Studio is 1MB. If you want to go deeper into this, discover what the default stack size GCC gives or explicitly set the stack size (assuming you can) until you find a segfault. A quick search says it's around 8MB, though this may not be accurate for you. Assuming this is correct then you managed to exceed it.
Set that data on the heap dynamically. It's normally meant for large amounts of data, while the stack is meant for temporary/local storage.
Upvotes: 3
Reputation: 162317
You didn't initialize heightmap
with data:
float heightmap[width * height * 3];
/* ... */
glBufferDataARB(GL_ARRAY_BUFFER, sizeof(heightmap), heightmap, GL_STATIC_DRAW);
If all what you want to do is initializing the OpenGL Buffer Object, you can simply pass a null pointer.
BTW: All the glBuffer…
have been core ever since OpenGL-1.4, i.e. you should not use the ARB
extensions but can use the core functions safely, even on the oldest implementations you'll find these days (it even works for my old GeForce2 based antique computers).
Upvotes: 2