代码之家  ›  专栏  ›  技术社区  ›  jv42

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

  •  10
  • jv42  · 技术社区  · 15 年前

    我正在开发一个iPhone应用程序,它是OpenGL ES和普通iPhone UI的混合。这意味着 EAGLView 向用户打招呼,然后是一些普通的 UIView 被推到上面的 UINavigationController 作为根控制器)。

    从子视图导航回来时,我遇到了一个随机(但非常频繁)崩溃。这是一个(…审查的…)堆栈跟踪,来自一个发布版本,但是在调试中它会崩溃。

    #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
    

    以下是我知道的事情:

    • 我的应用程序没有发现仪器下的泄漏。
    • 模拟器上没有崩溃,但有时会出现非常明显的延迟。
    • 我同时使用VBOs和vertex/texcoord/normals数组。

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

    更新:

    在设置了一些断点、沿着堆栈移动、插入了各种变量之后,我找到了崩溃的原因,但还没有找到源代码。

    presentFramebuffer 在崩溃发生的位置和时间,如果我相信gdb,colorRenderBuffer ivar是0,即使当它是0时尝试断点似乎不起作用。

    deleteFrameBuffer 来电 layoutSubviews createFramebuffer .

    更新2:

    以后会有很多断点。。。我发现了一个错误的情况: [EAGLView layoutSubviews] 被调用 在一个 drawFrame ! 所以缓冲区在使用时被删除。。。砰!

    现在我该怎么解决 那个

    4 回复  |  直到 14 年前
        1
  •  3
  •   jv42    15 年前

    我还没有找到一个“合适”的解决方案,但我已经添加了一个解决方案。

    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;
    }
    

    deleteFramebuffer ,我检查此布尔值:

    if (isRendering_PATCH_VARIABLE)
    {
        NSLog(@"GOTCHA - CRASH AVOIDED");   
    }
    
    if (context && !isRendering_PATCH_VARIABLE)
    {
        // ...
    }
    

        2
  •  3
  •   No one in particular    15 年前

    这是我最近做的一些疯狂的猜测。

    我的第一步类似于Xcode提供的OpenGL ES示例,我在ES上调用了init?渲染器。但在那之后,我暂停了进程,以便加载其他资源。

    [EAGLView layoutSubviews] 在我初始化之后就再也没有被调用过。我没有撞车,但在这之后没发生什么事。

    我要做的是,在初始化OpenGL的上下文并加载所有数据之后,我必须手动调用 [鹰视图布局子视图]

    也许你需要试试类似的东西。初始化OpenGL上下文和数据后,调用 [鹰视图布局子视图] 在你开始画画之前。也许这将阻止此调用在渲染步骤中再次出现并崩溃。

        3
  •  1
  •   zoul    15 年前

    暗中一刺:你的设备内存不足,应用程序收到内存警告,负责GL视图的控制器释放视图,这是你没有计算在内的?当您取消默认设置时,问题是否会消失 didReceiveMemoryWarning ?

    - (void) didReceiveMemoryWarning { /* nothing we can do, sorry */ }
    

        4
  •  1
  •   jdtec    14 年前

    我遇到了这个问题,利用了你的工作一段时间。不过,我最近注意到的是,坠机只是发生在方向改变时。

    这解决了这个问题,我不需要黑客工作了。

    不幸的是,听起来你的问题有点不同,但我想我会张贴这个以防万一。