2012-04-08 112 views
1

我已经创建了一个类来正确初始化和清除Xlib和glx。使用glXCreateContext的内存泄漏

OpenGLContext::OpenGLContext() 
    :m_display(nullptr) 
    ,m_context(nullptr) 
    ,m_vi(nullptr) 
{ 
    memset(&m_cmap, 0, sizeof(Colormap)); 
    memset(&m_swa, 0, sizeof(XSetWindowAttributes)); 
    memset(&m_win, 0, sizeof(Window)); 
    m_display = XOpenDisplay(NULL); 
    assert(m_display); 

    static int dblBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12, GLX_DOUBLEBUFFER, None}; 
    m_vi = glXChooseVisual(m_display, DefaultScreen(m_display), dblBuf); 
    m_context = glXCreateContext(m_display, m_vi, None, True); 
    m_cmap = XCreateColormap(m_display, RootWindow(m_display, m_vi->screen), m_vi->visual, AllocNone); 
    m_swa.colormap = m_cmap; 
    m_win = XCreateWindow(
       m_display, 
       RootWindow( m_display, m_vi->screen ), 
       0, 0, /* width */ 640, /* height */ 480, 0, m_vi->depth, InputOutput, m_vi->visual, 
       CWBorderPixel | CWColormap | CWEventMask, &m_swa 
      ); 

    char* dummy[] = { "", 0 }; 
    XSetStandardProperties(m_display, m_win, "glxsimple", "glxsimple", None, dummy, 0, NULL); 
    glXMakeCurrent(m_display, m_win, m_context); 
    XMapWindow(GetDisplay(), GetWindow()); 
} 

OpenGLContext::~OpenGLContext() 
{ 
    XUnmapWindow(m_display, m_win); 
    glXMakeCurrent(m_display, None, NULL); 
    XFreeColormap(m_display, m_cmap); 
    XDestroyWindow(m_display, m_win); 
    glXDestroyContext(m_display, m_context); 
    XFree(m_vi); 
    XCloseDisplay(m_display); 
} 

不幸的是,valgrind报告了内存泄漏。

==28742== 12,796 (584 direct, 12,212 indirect) bytes in 1 blocks are definitely lost in loss record 631 of 637 
==28742== at 0x4C29F5D: malloc (vg_replace_malloc.c:263) 
==28742== by 0xBCD7E7C: driConcatConfigs (in /usr/lib64/mesa/swrastg_dri.so) 
==28742== by 0xBCDBDFF: dri_init_screen_helper (in /usr/lib64/mesa/swrastg_dri.so) 
==28742== by 0xBCDAF0D: drisw_init_screen (in /usr/lib64/mesa/swrastg_dri.so) 
==28742== by 0xBCD8583: driCreateNewScreen (in /usr/lib64/mesa/swrastg_dri.so) 
==28742== by 0x5295604: driswCreateScreen (in /usr/lib64/opengl/xorg-x11/lib/libGL.so.1.2) 
==28742== by 0x527412B: __glXInitialize (in /usr/lib64/opengl/xorg-x11/lib/libGL.so.1.2) 
==28742== by 0x5270154: glXGetFBConfigs (in /usr/lib64/opengl/xorg-x11/lib/libGL.so.1.2) 
==28742== by 0x5270B57: glXChooseFBConfig (in /usr/lib64/opengl/xorg-x11/lib/libGL.so.1.2) 
==28742== by 0x4E9A7CE: ??? (in /usr/lib64/librrfaker.so) 
==28742== by 0x4E5B676: glXChooseVisual (in /usr/lib64/librrfaker.so) 
==28742== by 0x46D23B: Zion::Core::OpenGLContext::OpenGLContext() (OpenGLContext.cpp:23) 

请注意,我正在使用VirtualGL(解释librrfaker.so)。有什么我做错了吗?或者我应该认为这是VirtualGL方面的一个错误?

回答

1

你不应该自动假设这是一个错误。在处理优化的库时,valgrind有时会返回错误的结果。为了确保您需要确保您运行的是库的未优化版本。

编辑

This extract from a valgrind manual认为,这只是一个问题,当它会检查未初始化的变量。我记得之前被误报所击中,但是现在我想到它确实是未初始化的值。

+0

好的。为什么会有误报? – qdii 2012-04-08 19:44:43

+0

我不知道详细的原因,但我认为它类似于调试器在逐步优化的二进制文件时不太可靠的方式。 – Troubadour 2012-04-08 19:55:41

+1

没有冒犯,但对我来说听起来不太可能。如果我没有记错Valgrind的文档中读到的内容,valgrind会模拟一个处理器并让程序在其上运行。从这个扩展的处理器中可以推断哪些内存位置受到操作码的影响。这就是为什么我无法看到优化​​的代码如何在这样的级别上发挥作用。 – qdii 2012-04-09 08:14:07

0

这可能是一个真正的内存泄漏,Valgrind也检测库中的泄漏。

在实践中 - 如果这些函数仅在初始化时调用一次,例如。虽然他们在技术上是泄漏的 - 你可以放心地忽略它们,或者如果你喜欢,你可以调查泄漏的上游,如果来源是可用的。


检查文档,上glXChooseFBConfig返回值预计将与XFree调用它被释放。