C:分段错误,也许GDB对我说谎

时间:2014-04-03 05:30:08

标签: c

以下是段函数的C函数:

void compileShaders(OGL_STATE_T *state) {

    // First testing to see if I can access object properly. Correctly outputs:
    // nsHandle: 6
    state->nsHandle = 6;
    printf("nsHandle: %d\n", state->nsHandle);

    // Next testing if glCreateProgram() returns proper value. Correctly outputs:
    // glCreateProgram: 1
    printf("glCreateProgram: %d\n", glCreateProgram());


    // Then the program segfaults on the following line according to gdb
    state->nsHandle = glCreateProgram();

}

对于记录状态 - > nsHandle的类型为GLuint,glCreateProgram()返回一个GLuint,因此不应该是我的问题。

gdb说我的程序段错误在第303行,这实际上是该行之前的注释行。我不知道这是否真的很重要。

gdb对我说谎吗?我该如何调试呢?

修改

关闭优化(-O3),现在它正在运行。如果有人能解释为什么那会很棒。

编辑2: 出于评论的目的,这里是重要组件的淡化版本:

typedef struct {
    GLuint nsHandle;
} OGL_STATE_T;

int main (int argc, char *argv[]) {
    OGL_STATE_T _state, *state=&_state;
    compileShaders(state);
}

编辑3: 这是我做过的测试:

int main(int argc, char *argv[]) {

    OGL_STATE_T _state, *state=&_state;

    // Assign value and try to print it in other function
    state->nsHandle = 5;

    compileShaders(state);

}

void compileShaders(OGL_STATE_T *state) {

    // Test to see if the first call to state is getting optimized out
    // Correctly outputs:
    // nsHandle (At entry): 5
    printf("nsHandle (At entry): %d\n", state->nsHandle);

}

不确定这是否对任何事情有帮助,或者编译器是否实际上会优化主函数的值。

编辑4: 在main和compileShaders中打印出指针地址,一切都匹配。所以我会假设它在其他地方发生了分裂,而gdb正在向我说谎实际上是哪条线造成的。

4 个答案:

答案 0 :(得分:2)

这将基于你拥有的东西进行猜测,但在这条线上进行了优化:

state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);

可能只针对

进行了优化
printf("nsHandle: 6\n");

因此第一次访问state是segfault的所在。通过优化GDB可以报告问题所在的奇数行号,因为正如您从上面的示例中看到的那样,正在运行的代码可能不再完全映射到源代码行。

正如评论中所提到的,state几乎肯定没有初始化。优化代码中的一些其他差异导致它指向无效的存储区域,而它指向某处的非优化代码有效。

如果你直接用指针做某事阻止优化器“看到”,那么可能会发生这种情况。使用给定的变量。

健全检查有助于检查state != 0,但如果它不为零但无效,则无法提供帮助。

您需要发布呼叫代码,以便任何人告诉您更多信息。但是,您询问了如何调试它 - 我会在输入该函数时打印(或使用GDB查看)state的值,我想它在优化和非优化版本中会有很大差异。然后追溯到函数调用以找出原因。

修改

你发布了调用代码 - 应该没问题。编译时是否收到警告(用-Wall打开所有警告)。无论如何,我在不同情况下打印state值的建议仍然存在。

(删除了关于添加&以及您再次编辑问题的评论)

答案 1 :(得分:1)

优化程序时,源行和渲染代码之间不再有1:1的映射。 通常,编译器会重新排序代码以使您的CPU更有效,或者内联函数调用等......

此代码错误:

*state=_state

应该是:

*state=&_state

嗯,您编辑了帖子,请忽略上述修复。

答案 2 :(得分:0)

在取消引用指针或读取指针之前检查NULL条件。如果传递的值为NULL或者存储的值为NULL,那么您将执行segfault而不执行任何检查。

仅供参考:GDB不能说谎!

答案 3 :(得分:0)

我最终开始了一个包含更多相关信息的新帖子,有人找到了答案。新线程在这里:

GCC: Segmentation fault and debugging program that only crashes when optimized