LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-14-2009, 01:21 PM   #1
mrider
LQ Newbie
 
Registered: Oct 2006
Distribution: Debian
Posts: 28

Rep: Reputation: 1
Memory leak with X11 when window is invalid


Greetings - I hope I am putting this in proper forum.

A program I am working on reports a memory leak when an invalid window is referenced. I have some example code which shows the problem. The two functions are identical except that the first is called with a valid window, while the second is called with an invalid window. You can see the different ways I've tried to free the memory, but Valgrind always complains. BTW, the bolded line of code is the one Valgrind complains about. Is there a way to fix this?

Code:
#include <stdlib.h>
#include <stdio.h>
#include <Xutil.h>
#include <Xlib.h>

Display *display = 0;

int _invalid_window_handler(Display *dsp, XErrorEvent *err) {
    return 0;
}

void example1(Window win) {
    XSetErrorHandler(_invalid_window_handler);
    XWindowAttributes *attribs = calloc(1, sizeof(XWindowAttributes));
    if(attribs == NULL) {
        fprintf(stderr, "Unable to allocate space for XWindowAttributes");
        return;
    }
    Status status = XGetWindowAttributes(display, win, attribs);
    XSetErrorHandler(NULL);
    printf("example1 status: %d\n", status);
    XFree(attribs);
//    free(attribs);
//    if(status) {
//        XFree(attribs);
//    } else {
//        free(attribs);
//    }
}

void example2(Window win) {
    XSetErrorHandler(_invalid_window_handler);
    XWindowAttributes *attribs = calloc(1, sizeof(XWindowAttributes));
    if(attribs == NULL) {
        fprintf(stderr, "Unable to allocate space for XWindowAttributes");
        return;
    }
    Status status = XGetWindowAttributes(display, win, attribs);
    XSetErrorHandler(NULL);
    printf("example2 status: %d\n", status);
    XFree(attribs);
//    free(attribs);
//    if(status) {
//        XFree(attribs);
//    } else {
//        free(attribs);
//    }
}

int main(int argc, char* argv[]) {
    Window real = 0;
    int state_ignored = 0;
    display = XOpenDisplay(NULL);
    int success = XGetInputFocus(display, &real, &state_ignored);
    if(!success) {
        return -1;
    }
    Window fake = (Window)2L;

    example1(real);
    example2(fake);

    XCloseDisplay(display);
    display = 0;
    return 0;
}
What Valgrind has to say
==14330== Memcheck, a memory error detector.
==14330== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==14330== Using LibVEX rev 1804, a library for dynamic binary translation.
==14330== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==14330== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework.
==14330== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==14330== For more details, rerun with: -v ==14330==
example1 status: 1
example2 status: 0
==14330==
==14330== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 23 from 1) ==14330== malloc/free: in use at exit: 62 bytes in 2 blocks.
==14330== malloc/free: 90 allocs, 88 frees, 58,630 bytes allocated.
==14330== For counts of detected errors, rerun with: -v ==14330== searching for pointers to 2 not-freed blocks.
==14330== checked 105,428 bytes.
==14330==
==14330== 36 bytes in 1 blocks are definitely lost in loss record 2 of 2
==14330== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==14330== by 0x427C30D: (within /usr/lib/libxcb.so.1.0.0)
==14330== by 0x427AFB5: (within /usr/lib/libxcb.so.1.0.0)
==14330== by 0x427CBDC: xcb_wait_for_reply (in /usr/lib/libxcb.so.1.0.0)
==14330== by 0x407A1EA: _XReply (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x40592FB: _XGetWindowAttributes (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x4059451: XGetWindowAttributes (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x80487A0: example2 (test.c:39)
==14330== by 0x804884A: main (test.c:62)
==14330==
==14330== LEAK SUMMARY:
==14330== definitely lost: 36 bytes in 1 blocks.
==14330== possibly lost: 0 bytes in 0 blocks.
==14330== still reachable: 26 bytes in 1 blocks.
==14330== suppressed: 0 bytes in 0 blocks.
==14330== Reachable blocks (those to which a pointer was found) are not shown.

Last edited by mrider; 01-14-2009 at 01:56 PM. Reason: Oops, I bolded the one that's not having the problem...
 
Old 01-16-2009, 10:07 AM   #2
fantas
Member
 
Registered: Jun 2007
Location: Bavaria
Distribution: slackware, xubuntu
Posts: 143

Rep: Reputation: 22
Not much to contribute, just three points:

a) Valgrind isn't always 100% accurate regarding memory leaks, as for example with some X11 stuff (I only can tell from my own experience, I don't have an explanation for it, but it may have to do with that X11 has its own ways of managing memory allocations, so it could be that Valgrind simply doesn't have the means to look more closely into what's happening)
b) Always use the relating deallocation counterpart that goes along with the allocation function (i.e. malloc/calloc/realloc => free, or new => delete, ...). Valgrind could be too picky and count small differences already as a potential leak (even if it probably amounts to the same code logically internally)
c) Why not allocate the attributes on the stack ? The struct is small enough, and for small and especially small POD objects the stack is _way_ faster. Heap allocation is certainly not always the preferred method. What does Valgrind say if you change the code to

Code:
// ...
XWindowAttributes attribs;
Status status = XGetWindowAttributes(display, win, &attribs);
// ...
HTH
 
Old 01-19-2009, 11:17 AM   #3
mrider
LQ Newbie
 
Registered: Oct 2006
Distribution: Debian
Posts: 28

Original Poster
Rep: Reputation: 1
Quote:
a) Valgrind isn't always 100% accurate regarding memory leaks, as for example with some X11 stuff (I only can tell from my own experience, I don't have an explanation for it, but it may have to do with that X11 has its own ways of managing memory allocations, so it could be that Valgrind simply doesn't have the means to look more closely into what's happening)
Yes - I've investigated more and I'm beginning to see what you describe. One thing I've noticed is that X11 only "leaks" once even when I call the problematic code many times. So I suspect X11 is simply allocating space to my stuff that Valgrind can't observe being deallocated. Possibly it is released after I disconnect from the display? Not sure...



Quote:
b) Always use the relating deallocation counterpart that goes along with the allocation function (i.e. malloc/calloc/realloc => free, or new => delete, ...). Valgrind could be too picky and count small differences already as a potential leak (even if it probably amounts to the same code logically internally)
Well yes, originally I was, but I started trying other things to try and get the memory leak to go away.



Quote:
c) Why not allocate the attributes on the stack ? The struct is small enough, and for small and especially small POD objects the stack is _way_ faster. Heap allocation is certainly not always the preferred method. What does Valgrind say if you change the code to (N.B. code not included)
Valgrind also reports a leak for that. In fact, I started out with the XWindowAttributes on the stack only. It really makes more sense to what I'm doing (which only has a passing resemblance to the code I posted). When Valgrind reported it as a leak, I thought that perhaps my problem was that X11 was allocating space on the heap for something inside the attributes, and the fact that I had no way of calling XFree meant that X11 had no way of knowing that it could be released.



Unless someone else has any suggestions, I think I'll go back to allocating the space on the stack and ignoring the potential memory leak - at least until I have more information.

Thanks for your responses!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Memory leak: How risky not to free allocated memory. kaz2100 Linux - General 1 12-24-2008 12:00 AM
Inactive memory issue, Freebsd (memory leak?) JasperB *BSD 7 08-12-2008 03:19 AM
Does this leak memory? C/C++ leosgb Programming 3 10-26-2007 01:04 AM
Memory leak? BillyGalbreath Linux - Software 6 09-24-2007 11:18 PM
Memory Leak when using memory debugging C program on SuSE SLES8 babalina Linux - Distributions 0 10-06-2003 09:39 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:12 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration