这是线程的跟进:C: Segmentation fault and maybe GDB is lying to me
我有一个用-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提交错误报告的部分吗?
感谢任何花时间阅读此主题的人。我知道这有点长在事情上。
答案 0 :(得分:3)
问题在于fileName
compileShaders()
定义
char fileName[sizeof shaderName + 8]; .
这是不正确的,并没有为fileName
分配足够的字节。
您需要使用strlen(shaderName)+8
进行分配,而不是sizeof(shaderName)
。