导航时在iPhone OpenGL应用程序上随机崩溃

jv4*_*v42 10 iphone crash opengl-es objective-c

我正在开发一个混合OpenGL ES和常规iPhone UI的iPhone应用程序.这意味着有一个EAGLView问候用户,然后一些常规UIViews被推过它(有一个UINavigationController作为根控制器).

从子视图导航回来时,我有一个随机(但非常频繁)的崩溃.这是一个(...删除...)堆栈跟踪,来自Release版本,但它在Debug中崩溃了.

#0  0x006863d0 in GetFBOBuffers ()
#1  0x00660120 in TerminateScene ()
#2  0x00660314 in FlushScene ()
#3  0x00660cd4 in FlushHW ()
#4  0x0066a6a0 in GLESPresentView ()
#5  0x323533a4 in -[EAGLContext presentRenderbuffer:] ()
#6  0x000026c0 in -[EAGLView presentFramebuffer] (self=0x11ce60, _cmd=<value temporarily unavailable, due to optimizations>) at (...)/Classes/EAGLView.m:157
#7  0x00004fdc in -[(...)ViewController drawFrame] (self=<value temporarily unavailable, due to optimizations>, _cmd=<value temporarily unavailable, due to optimizations>) at (...)    ViewController.m:380
#8  0x336ebd9a in __NSFireTimer ()
#9  0x323f54c2 in CFRunLoopRunSpecific ()
#10 0x323f4c1e in CFRunLoopRunInMode ()
#11 0x335051c8 in GSEventRunModal ()
#12 0x324a6c30 in -[UIApplication _run] ()
#13 0x324a5230 in UIApplicationMain ()
#14 0x0000214c in main (argc=1, argv=0x2ffff568) at (...)/main.m:14
Run Code Online (Sandbox Code Playgroud)

以下列出了我所知道的事项:

  • 我的应用程序没有得到内存警告.
  • 我的应用程序在仪器下没有发现泄漏.
  • 在模拟器上没有崩溃,但有时会出现非常明显的延迟.
  • 在崩溃之前,Instruments/OpenGL/ResourceBytes中有大量已发布的数据.
  • 我正在使用VBO和vertex/texcoord/normals数组.

所以我知道它必须是某种被释放或销毁的数据,但我不知道如何找到它.任何提示和技巧将不胜感激;-)

更新:

在设置了一些断点后,沿着堆栈移动,查看各种变量,我找到了崩溃的原因,但还没有找到源.

在EAGLView中,在presentFramebuffer崩溃发生的方法和时间,如果我可以相信gdb,colorRenderBuffer ivar为0,即使尝试断点时它似乎不起作用.

似乎deleteFrameBuffer来自的呼叫layoutSubviews不匹配createFramebuffer.

更新2:

后来有很多断点......我发现了一个错误的情况:在一个中间[EAGLView layoutSubviews]被调用!因此缓冲区在使用时被删除... BAM!drawFrame

现在我如何解决这个问题

jv4*_*v42 3

我还没有找到“正确”的修复方法,但我添加了一个解决方法。

在 中presentFramebuffer,我在渲染周围设置了一个布尔值:

if (context)
{
    isRendering_PATCH_VARIABLE = YES;

    [EAGLContext setCurrentContext:context];

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

    success = [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);

    isRendering_PATCH_VARIABLE = NO;
}
Run Code Online (Sandbox Code Playgroud)

在 中deleteFramebuffer,我检查这个布尔值:

if (isRendering_PATCH_VARIABLE)
{
    NSLog(@"GOTCHA - CRASH AVOIDED");   
}

if (context && !isRendering_PATCH_VARIABLE)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

它似乎没有副作用(比如显示器损坏等),所以我暂时就这样吧。