GCC:分段故障和调试程序,仅在优化时崩溃

这是线程的后续跟进: C:分段错误,也许GDB对我说谎

我有一个用-O0编译好的程序,但用-O1,-O2,-O3和Ofast编译段错误。 似乎堆栈在某种程度上会被破坏,但我无法弄清楚为什么或在哪里。

首先,这是我正在使用的结构的一部分。 它位于头文件中:

typedef struct { GLuint nsHandle; } OGL_STATE_T; 

这是主文件中相关的淡化部分:

 void init(OGL_STATE_T *state) { printf("init: %p\n", state); // Print pointer address make sure it's the same. compileShaders(state); } int main(argc, char *argv[]) { static OGL_STATE_T _state, *state=&_state; printf("main: %p\n", state); // Print pointer address init(state); return 0; } 

然后这是compileShaders函数。 这是指针地址损坏发生的地方:

 void compileShaders(OGL_STATE_T *state) { printf("compileShaders entry: %p\n", state); // Print pointer address make sure it's good GLuint nsVertex = compileShader("nsVertex", GL_VERTEX_SHADER, state); GLuint nsFragment = compileShader("nsFragment", GL_FRAGMENT_SHADER, state); printf("compileShaders return: %p\n", state); // Print pointer when returning. state->nsHandle = glCreateProgram(); // Segmentation fault here. /* ... */ } 

正如稍后将在输出中说明的那样,第二个printf语句返回错误的地址。

最后,compileShader函数(注意这里名称末尾缺少’s’)。 最初该函数没有采用状态指针,但我添加了它,因此我可以跟踪执行中腐败发生的位置。

 GLuint compileShader{char * shaderName, GLenum shaderType, OGL_STATE_T *state} { printf("compileShader 1: %p\n", state); // Print state address at function entry FILE *shaderFile; char fileName[sizeof shaderName + 8]; long lSize; char *buffer; strcpy(fileName, "./"); strcpy(fileName, shaderName); strcpy(fileName, ".glsl"); shaderFile = fopen(fileName, "rb"); fseek(shaderFile, 0L, SEEK_END); lSize = ftell(shaderFile); rewind(shaderFile); buffer = calloc(1, lSize + 1); GLuint shaderHandle = glCreateShader(shaderType); printf("compileShader 2: %p\n", state); // Print state address at function middle const GLchar *shaderString = buffer; glShaderSource(shaderHandle, 1, &shaderString, 0); glCompileShader(shaderHandle); GLint compileSuccess; glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess); fclose(shaderFile); shaderString = NULL; free(buffer); printf("compileShader 3: %p\n\n", state); // Print state address before returning return shaderHandle; } 

现在为踢球者输出:

 main: 0x1387c init: 0x1387c compileShaders entry: 0x1387c compileShader 1: 0x1387c compileShader 2: 0x1387c compileShader 3: 0x1387c compileShader 1: 0x1387c compileShader 2: 0x1387c compileShader 3: 0x1387c compileShaders return: 0x1006c Segmentation fault. (Core dumped) 

所以这告诉我,当compileShader()函数退出时,地址仍然很好,并且在它返回到compileShaders()之后(请不要混淆,一个有’s’而另一个没有),地址得到损坏?

在这一点上,我有点大吃一惊。 这很难调试,因为如果我不优化代码,我不会得到任何错误。 但是,如果我确实优化了代码(无论是O1,O2,O3还是Ofast),我都会遇到分段错误。

printf语句是我现在唯一的朋友,他们此时并没有告诉我任何事情。 这是我向GCC提交错误报告的部分吗?

感谢任何花时间阅读此主题的人。 我知道这有点长在事情上。

问题在于compileShaders()fileName定义

 char fileName[sizeof shaderName + 8]; . 

这是不正确的,并没有为fileName分配足够的字节。

您需要使用strlen(shaderName)+8 ,而不是sizeof(shaderName)进行分配。