代码之家  ›  专栏  ›  技术社区  ›  Stephen Furlani

OpenGL/Carbon/Cocoa内存管理自动释放问题

  •  0
  • Stephen Furlani  · 技术社区  · 15 年前

    Hoooboy

    我又有一个记忆问题。

    我在C++中创建了一个碳(AGL)窗口,它告诉我我是 autorelease -在没有游泳池的地方游泳。

    休斯敦大学。。。什么?

    我以为碳存在于 NSAutoreleasePool

    当我呼唤 glEnable(GL_TEXTURE_2D) 做一些事情,它给了我一个 EXC_BAD_ACCESS 警告-但是如果航空地面照明窗口一直没有 release 那它不应该存在吗?设置 set objc-non-blocking-mode (gdb) 不会让问题消失的。

    所以我想我的问题是碳/可可/NSAutoReleasePool是怎么回事?

    还有…是否有用于Objective-C++的资源?因为像这样的垃圾不断发生在我身上。

    谢谢,

    -史蒂芬

    ---代码---

    测试绘图功能

    void Channel::frameDraw( const uint32_t frameID)
    {
        eq::Channel::frameDraw( frameID );
                getWindow()->makeCurrent(false);
        glEnable(GL_TEXTURE_2D); // Throws Error Here
    }
    

    通电(以下代码来自均衡器API,即LGPL Eyescale)

    void Window::makeCurrent( const bool useCache ) const
    {
        if( useCache && getPipe()->isCurrent( this ))
            return;
    
        _osWindow->makeCurrent();
    }
    
    void AGLWindow::makeCurrent() const
    {
        aglSetCurrentContext( _aglContext );
        AGLWindowIF::makeCurrent();
    
        if( _aglContext )
        {
            EQ_GL_ERROR( "After aglSetCurrentContext" );
        }
    }
    

    _aglContext 是我单步执行时的有效内存位置(即不为空)。

    - S!

    ---错误---

    859 2958110720 //Users/slate/Documents/equalizer/XCode/../lib/client/aglWindow.cpp:367   278 Created AGL context 0x4867200 shared with 0
    *** __NSAutoreleaseNoPool(): Object 0x1fc4a950 of class NSCarbonWindowContentView autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0x1fc4b120 of class NSCFArray autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0x1f410f50 of class NSMutableParagraphStyle autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0x45063f0 of class NSCFDictionary autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0x2f2ed50 of class NSPathStore2 autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0x44bf380 of class NSCFData autoreleased with no pool in place - just leaking
    *** __NSAutoreleaseNoPool(): Object 0xa026cb08 of class NSCFString autoreleased with no pool in place - just leaking
    etc...
    

    ---堆栈---

    #0  0x9252d3f1 in __NSAutoreleaseNoPool ()
    #1  0x9243a794 in _CFAutoreleasePoolAddObject ()
    #2  0x9243a4aa in -[NSObject(NSObject) autorelease] ()
    #3  0x9372d023 in -[NSCarbonWindow initWithCarbonWindowRef:takingOwnership:disableOrdering:] ()
    #4  0x9345bdee in _cocoaAppApplicationEventHandler ()
    #5  0x920f00a9 in DispatchEventToHandlers ()
    #6  0x920ef370 in SendEventToEventTargetInternal ()
    #7  0x920ef1cf in SendEventToEventTargetWithOptions ()
    #8  0x92114e44 in SendShowHideEvent ()
    #9  0x921148b1 in _ShowHideWindows ()
    #10 0x92177341 in ShowWindow ()
    #11 0x2a01fab0 in eq::AGLWindow::configInitAGLWindow (this=0x400d260) at /Users/slate/Documents/equalizer/XCode/../lib/client/aglWindow.cpp:541
    #12 0x2a01f380 in eq::AGLWindow::configInitAGLDrawable (this=0x400d260) at /Users/slate/Documents/equalizer/XCode/../lib/client/aglWindow.cpp:393
    #13 0x2a01eb32 in eq::AGLWindow::configInit (this=0x400d260) at /Users/slate/Documents/equalizer/XCode/../lib/client/aglWindow.cpp:148
    #14 0x2a0a25b9 in eq::Window::configInitOSWindow (this=0x283795f0, initID=0) at /Users/slate/Documents/equalizer/XCode/../lib/client/window.cpp:435
    #15 0x2a09f31b in eq::Window::configInit (this=0x283795f0, initID=0) at /Users/slate/Documents/equalizer/XCode/../lib/client/window.cpp:394
    #16 0x2a0a1226 in eq::Window::_cmdConfigInit (this=0x283795f0, command=@0x4009120) at /Users/slate/Documents/equalizer/XCode/../lib/client/window.cpp:720
    #17 0x2a0ae8d5 in eq::net::CommandFunc<eq::net::Dispatcher>::operator() (this=0x1ed023b4, command=@0x4009120) at commandFunc.h:50
    #18 0x2a0adf4a in eq::net::Dispatcher::invokeCommand (this=0x283795f0, command=@0x4009120) at /Users/slate/Documents/equalizer/XCode/../lib/net/dispatcher.cpp:121
    #19 0x2a102ec4 in eq::net::Session::_invokeObjectCommand (this=0x3061600, command=@0x4009120) at /Users/slate/Documents/equalizer/XCode/../lib/net/session.cpp:622
    #20 0x2a10448c in eq::net::Session::invokeCommand (this=0x3061600, command=@0x4009120) at /Users/slate/Documents/equalizer/XCode/../lib/net/session.cpp:575
    #21 0x2a0901d3 in eq::Pipe::_runThread (this=0x28377c00) at /Users/slate/Documents/equalizer/XCode/../lib/client/pipe.cpp:310
    #22 0x2a0987e4 in eq::Pipe::PipeThread::run (this=0x28377a80) at pipe.h:419
    #23 0x2a01a307 in eq::base::Thread::_runChild (this=0x28377a80) at /Users/slate/Documents/equalizer/XCode/../lib/base/thread.cpp:125
    #24 0x2a01a48d in eq::base::Thread::runChild (arg=0x28377a80) at /Users/slate/Documents/equalizer/XCode/../lib/base/thread.cpp:101
    #25 0x958aea19 in _pthread_start ()
    #26 0x958ae89e in thread_start ()
    

    感谢您提供有关设置env nsautoreleasehaltnopool=yes的提示。为什么是 _cocoaAppApplicationEventHandler 甚至牵涉到这里?我正在将一个agl/carbon插件导入到cgl/cocoa应用程序…可可粉会覆盖所有的碳吗?

    根据MacWindows.h

    /*
     *  [Mac]ShowWindow()
     *  
     *  Mac OS X threading:
     *    Not thread safe
     *  
     *  Availability:
     *    Mac OS X:         in version 10.0 and later in Carbon.framework [32-bit only]
     *    CarbonLib:        in CarbonLib 1.0 and later
     *    Non-Carbon CFM:   in InterfaceLib 7.1 and later
     */
    #if TARGET_OS_MAC
        #define MacShowWindow ShowWindow
    #endif
    extern void 
    MacShowWindow(WindowRef window)                               AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER;
    

    这应该只是一个直接的碳排放呼吁…所以我不知道可可为什么要这么做。这看起来很奇怪,它在这里不起作用,但在另一个项目中却很管用。所有的配置设置等在项目之间都是相同的,所以我很难理解为什么这是一个问题。

    - S!

    1 回复  |  直到 15 年前
        1
  •  1
  •   Stephen Furlani    15 年前

    呃,

    所以如果其他人也在寻找类似的答案,我会把我的发现贴出来。

    答案是碳窗口是作为可可应用程序的可可插件的一部分生成的。因此,Carbon窗口需要遵循两个Carbon中的所有内存管理规则。 可可。因此,为什么创建对nscarbonwindow的引用并尝试将其添加到自动释放池中。

    1)一个解决方案是不要使用碳(duh),因为苹果比Adobe更快地将其弃用。P

    2)另一个解决方案是手动添加Carbon窗口并正确管理内存。因为我用的是碳原料药,所以我真的做不到。

    3)第三种解决方案是将程序分开。在单独的.app中使用CarbonAPI,而不是Cocoa插件。这就是我要做的,只需通过machports或在两个应用程序之间传递信息。

    希望这能帮助别人。当然,MT个人建议是1。

    -史蒂芬

    推荐文章