手动创建GL上下文(GCC)时出现分段错误

时间:2013-10-03 11:19:01

标签: c++ linux opengl gcc

我使用Boost线程。我有以下生产者 - 消费者设置:

ClassX(在主线程中运行)创建一些数据,它传递给ClassY(在自己的线程中运行)调用此方法:

 void ClassY::PushFrame(uint8_t *data) {

    try {
        boost::lock_guard<boost::mutex> lk(_myMutex);
        _frames.push(data);

        _data_cond.notify_one();
    } catch (...) {

    }
}

现在,在ClassY中,在operator()()的正文中,有一个循环从_frames队列中弹出数据并对其进行处理:

       while (true)  
        {
            boost::unique_lock<boost::mutex> lk(_myMutex);

            // we need a loop here as wait() may return spuriously
            while (_frames.empty()) { 
                // wait() will release the mutex and suspend the thread

                _data_cond.wait(lk);


            }

            ///wait was interrupted by notifcation of incoming new frame:
            uint8_t *frame  = _frames.front();


        //...........the rest of code.....
         }

_data_cond.wait(lk)上会出现分段错误,或者至少这是我认为的,因为我无法在发布模式下正确调试它,因此我使用printf()来查看它发生的位置。它总是只在循环开始时发生。它也仅在发布版本中发生,并在随机运行时抛出。 Ubuntu GCC 64位。

更新

经过一些检查之后,看起来seg错误的原因似乎不是提升线程,而是我在Linux上创建OpenGL上下文的方式。我无法找到创建它的方法。但是在使用{{3}时相反,一切都很好。

我就是这样做的:

        int visual_attribs[] = {
             GLX_RENDER_TYPE,
        GLX_RGBA_BIT,
        GLX_RED_SIZE, 8,
        GLX_GREEN_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_ALPHA_SIZE, 8,
        GLX_DEPTH_SIZE, 24,
        GLX_STENCIL_SIZE, 8,
            None
        };
        int context_attribs[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB, vmaj,
            GLX_CONTEXT_MINOR_VERSION_ARB, vmin,
            GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
            None
        };

        _xdisplay = XOpenDisplay(NULL);
        int fbcount = 0;
        _fbconfig = NULL;
        GLXPbuffer pbuf;
        //  _render_context
        if (!_xdisplay) {

            throw ;
        }
        /* get framebuffer configs, any is usable (might want to add proper attribs) */
        if (!(_fbconfig = glXChooseFBConfig(_xdisplay, DefaultScreen(_xdisplay), visual_attribs, &fbcount))) {
          throw;
        }

        /* get the required extensions */
        glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
        glXMakeContextCurrentARB = (glXMakeContextCurrentARBProc) glXGetProcAddressARB((const GLubyte *) "glXMakeContextCurrent");
        if (!(glXCreateContextAttribsARB && glXMakeContextCurrentARB)) {

            XFree(_fbconfig);
          throw;

        }

        /* create a context using glXCreateContextAttribsARB */
        if (!(_render_context = glXCreateContextAttribsARB(_xdisplay, _fbconfig[0], 0, True, context_attribs))) {

            XFree(_fbconfig);
            throw;

        }

        /* create temporary pbuffer */
        int pbuffer_attribs[] = {
            GLX_PBUFFER_WIDTH, 32,
            GLX_PBUFFER_HEIGHT, 32,
            None
        };
        pbuf = glXCreatePbuffer(_xdisplay, _fbconfig[0], pbuffer_attribs);

        XFree(_fbconfig);
        XSync(_xdisplay, False);

        /* try to make it the current context */
        if (!glXMakeContextCurrent(_xdisplay, pbuf, pbuf, _render_context)) {
            /* some drivers does not support context without default framebuffer, so fallback on
             * using the default window.
             */
            if (!glXMakeContextCurrent(_xdisplay, DefaultRootWindow(_xdisplay),
                    DefaultRootWindow(_xdisplay), _render_context)) {
                       throw;
            }
        }

退出时,析构函数会进行清理:

      glXMakeCurrent( _xdisplay, 0, 0 );
     glXDestroyContext( _xdisplay, _render_context );
     XCloseDisplay( _xdisplay );

这里有什么问题?怎么可能破坏在其他地方访问的内存?

0 个答案:

没有答案