2012-04-08 5 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

편집은 초기화되지 않은 변수를 확인할 때 이것은 단지 문제가 있음을 시사한다. 이전에 오탐 (false positive)에 부딪쳤다는 것을 기억합니다.하지만 지금 생각할 때 그것은 초기화되지 않은 값입니다.

+0

오케이. 오 탐율이있는 이유는 무엇입니까? – qdii

+0

자세한 이유는 모르지만 최적화 된 바이너리를 단계별로 실행할 때 디버거가 매우 안정적이지 않은 것과 유사하다고 가정합니다. – Troubadour

+1

불쾌감은 없지만 내게는 들리지 않습니다. Valgrind의 설명서에서 읽은 것을 올바르게 기억하면 valgrind가 프로세서를 에뮬레이션하고 프로그램을 실행합니다. 이 확장 프로세서에서 opcode에 의해 영향을받은 메모리 위치를 추론합니다. 그렇기 때문에 최적화 된 코드가 이러한 수준에서 어떻게 차이를 만들 수 있는지를 알 수 없습니다. – qdii

0

실제 메모리 누수 가능성이 높습니다. Valgrind는 라이브러리에서도 누출을 감지합니다.

실제로 이것들은 예를 들어 초기화 할 때마다 한 번만 호출됩니다. 그것들은 기술적으로 누설 된 것이기는하지만 안전하게 무시할 수 있습니다. 또는 원한다면 누수가있는 곳을 조사 할 수 있습니다. 워드 프로세서를 확인


glXChooseFBConfig에 반환 값은 호출 XFree으로 해제 될 것으로 예상된다.