views:

185

answers:

1

The code below shows a small 48 byte leak in valgrind.

#include <X11/Xlib.h>
#include <GL/glx.h>
#include <unistd.h>

int main( int argc, char* argv[] )
{
    Display* _display;
    Window _windowHandle;
    XVisualInfo* _visual;
    GLXContext _context;
    Atom _deleteWindowMessage;
    Atom _pingWindowMessage;

    _display = XOpenDisplay( NULL );

    int attributes[] = { GLX_RGBA,
                         GLX_DOUBLEBUFFER,
                         GLX_RED_SIZE, 8,
                         GLX_BLUE_SIZE, 8,
                         GLX_GREEN_SIZE, 8,
                         GLX_ALPHA_SIZE, 8,
                         GLX_DEPTH_SIZE, 8,
                         GLX_STENCIL_SIZE, 0,
                         0 };

    _visual = glXChooseVisual( _display, 
                               DefaultScreen( _display ),
                               attributes );

    _context = glXCreateContext( _display,
                                 _visual,
                                 0,
                                 GL_TRUE );

    Colormap colormap;

    colormap = XCreateColormap( _display, 
                                RootWindow( _display, _visual->screen ),
                                _visual->visual,
                                AllocNone );

    XSetWindowAttributes windowAttributes;

    windowAttributes.colormap = colormap;
    windowAttributes.border_pixel = 0;
    windowAttributes.event_mask = ExposureMask | StructureNotifyMask;


    _windowHandle = 
        XCreateWindow( _display,
                       RootWindow( _display, _visual->screen ),
                           0, 
                           0,
                           1280, 
                           720,
                           0,                      // Borderwidth
                           _visual->depth,         // Depth
                           InputOutput,
                           _visual->visual,
                           CWBorderPixel | CWColormap | CWEventMask,
                           &windowAttributes );
    XFreeColormap( _display, colormap );


    XMapWindow( _display, _windowHandle );

    // causes 48 byte leak...
    glXMakeCurrent( _display,
                    _windowHandle,
                    _context );

    sleep( 3 );

    XUnmapWindow( _display, _windowHandle );


    XDestroyWindow( _display, _windowHandle );


    glXMakeCurrent( _display, 
                    None,
                    NULL );

    glXDestroyContext( _display, _context );

    XFree( _visual );

    XCloseDisplay( _display );

    return 0;
}

All this code does is initialize a window for GLX rendering and then tear it down. The funny thing, is that as soon as I call glXMakeCurrent(), I leak 48 bytes... The valgrind output looks like this:

[developer@localhost ~]$ valgrind --tool=memcheck --leak-check=full ./simplex
==9531== Memcheck, a memory error detector
==9531== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==9531== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==9531== Command: ./simplex
==9531== 
==9531== 
==9531== HEAP SUMMARY:
==9531==     in use at exit: 248 bytes in 6 blocks
==9531==   total heap usage: 1,265 allocs, 1,259 frees, 2,581,764 bytes allocated
==9531== 
==9531== 48 bytes in 1 blocks are definitely lost in loss record 5 of 6
==9531==    at 0x400591C: malloc (vg_replace_malloc.c:195)
==9531==    by 0x349D0F8: ??? (in /usr/lib/nvidia/libGL.so.180.60)
==9531== 
==9531== LEAK SUMMARY:
==9531==    definitely lost: 48 bytes in 1 blocks
==9531==    indirectly lost: 0 bytes in 0 blocks
==9531==      possibly lost: 0 bytes in 0 blocks
==9531==    still reachable: 200 bytes in 5 blocks
==9531==         suppressed: 0 bytes in 0 blocks
==9531== Reachable blocks (those to which a pointer was found) are not shown.
==9531== To see them, rerun with: --leak-check=full --show-reachable=yes
==9531== 
==9531== For counts of detected and suppressed errors, rerun with: -v
==9531== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 30 from 8)

If you comment out the call to glXMakeCurrent() right before the sleep, the leak will go away... Of course, I need to make that call in order to render anything!

The real problem is that my app creates many child windows, each with GLX contexts associated... and each leaks this same 48 bytes... I don't know what else to try (the code is cleaning up the GLX context)... Any ideas?

+1  A: 

Ok, it looks like it really wasn't leaking.

Valgrind is still reporting the leak, but I wrote a test app that brings up thousands of windows in random locations and the memory is completely flat via top... So, looks like I'll need a suppression file for glx applications.

dicroce