Sunday, July 6th 2008, 5:08pm UTC+1

You are not logged in.

  • Login
  • Register

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains how this page works. You must be registered before you can use all the page's features. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

rlgomes

Beginner

Posts: 3

Location: San Mateo, California

1

Saturday, May 10th 2008, 8:02pm

Valgrind complains about possible memory leak in QT4.4

So I've been trying to use QT4.4 in a project of mine, because its really easy to use QThread and QThreadStorage across various platforms (awesome work guys!). Now my problem is that I've been using valgrind to make sure my application doesn't leak any memory and also doesn't have any bad memory accesses.

Here is a very simple example of my usage:

#include <QApplication>
#include <QPushButton>
#include <QThread>

#include <iostream>

using namespace std;

class Thread : public QThread
{
public:
Thread();
virtual ~Thread();
void run();
};

Thread::Thread()
{
}

Thread::~Thread()
{
}

void Thread::run()
{
cout << "here I am\n";
}

int main(int argc, char *argv[])
{
Thread t;
t.start();
t.wait();
return 0;
}


I Then build this by doing "qmake -project", "qmake", "make", and then I run my freshly created executable and the output is:

> ./test
here I am


All nice and dandy so far, now I run valgrind the following way "valgrind --leak-check=full ./test" and what i see is that it complains a bit about some code in QT itself:

==14654== 152 bytes in 1 blocks are possibly lost in loss record 7 of 12
==14654== at 0x4021BDE: calloc (vg_replace_malloc.c:397)
==14654== by 0x4010627: (within /lib/ld-2.7.so)
==14654== by 0x40106EB: _dl_allocate_tls (in /lib/ld-2.7.so)
==14654== by 0x4BA4C3C: pthread_create@@GLIBC_2.1 (in /lib/tls/i686/cmov/libpthread-2.7.so)
==14654== by 0x49BA8DD: QThread::start(QThread::Priority) (in /usr/lib/libQtCore.so.4.4.0)
==14654== by 0x8048CAA: main (in /home/neo/downloads/test/test)


==14654== 744 bytes in 3 blocks are possibly lost in loss record 9 of 12
==14654== at 0x4021A92: memalign (vg_replace_malloc.c:460)
==14654== by 0x4021B3F: posix_memalign (vg_replace_malloc.c:569)
==14654== by 0x4EEC103: (within /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EED330: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EAA50E: g_array_sized_new (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EAA616: g_array_new (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EF839F: g_static_private_set (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EB9D3F: g_get_filename_charsets (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EB9DB0: (within /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x4EF8659: g_thread_init_glib (in /usr/lib/libglib-2.0.so.0.1600.3)
==14654== by 0x50F2636: g_thread_init (in /usr/lib/libgthread-2.0.so.0.1600.3)
==14654== by 0x4AD1800: QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*) (in /usr/lib/libQtCore.so.4.4.0)

Now this is possible memory loss, I'm wondering that there could be two situations here either Valgrind is giving me a fall positive and if so I'd like to know if you guys have any handy supressions to add to the valgrind supression file that would filter out these cases ? The second possibility is that this is in fact a memory leak and I would hope to eliminate it as in my project i would start /stop threads quite frequently and if I lost 152 bytes each time this would add up quite fast.

Thanks for your time,
Rodney.
  • Go to the top of the page

2

Saturday, May 10th 2008, 10:51pm

try to put start and wait in a loop to see what happens

you will probably see that the number of possibly lost bytes doesn't increase

output for 1 loop

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ns@ns-00 toto]$ valgrind --leak-check=full ./toto | grep -v "here I am"
==9796== Memcheck, a memory error detector.
==9796== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==9796== Using LibVEX rev 1606, a library for dynamic binary translation.
==9796== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==9796== Using valgrind-3.2.0, a dynamic binary instrumentation framework.
==9796== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==9796== For more details, rerun with: -v
==9796==
==9796==
==9796== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1)
==9796== malloc/free: in use at exit: 11,345 bytes in 143 blocks.
==9796== malloc/free: 203 allocs, 60 frees, 48,413 bytes allocated.
==9796== For counts of detected errors, rerun with: -v
==9796== searching for pointers to 143 not-freed blocks.
==9796== checked 9,169,232 bytes.
==9796==
==9796== 288 bytes in 1 blocks are possibly lost in loss record 7 of 11
==9796==    at 0x4A1DB36: calloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==9796==    by 0x400F212: _dl_allocate_tls (dl-tls.c:304)
==9796==    by 0x6CFBA3B: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.4.so)
==9796==    by 0x648B4F8: QThread::start(QThread::Priority) (qthread_unix.cpp:443)
==9796==    by 0x4011BB: main (main.cpp:36)
==9796==
==9796== LEAK SUMMARY:
==9796==    definitely lost: 0 bytes in 0 blocks.
==9796==      possibly lost: 288 bytes in 1 blocks.
==9796==    still reachable: 11,057 bytes in 142 blocks.
==9796==         suppressed: 0 bytes in 0 blocks.
==9796== Reachable blocks (those to which a pointer was found) are not shown.
==9796== To see them, rerun with: --show-reachable=yes

output for 100 loop

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ns@ns-00 toto]$ valgrind --leak-check=full ./toto | grep -v "here I am"
==9682== Memcheck, a memory error detector.
==9682== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==9682== Using LibVEX rev 1606, a library for dynamic binary translation.
==9682== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==9682== Using valgrind-3.2.0, a dynamic binary instrumentation framework.
==9682== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==9682== For more details, rerun with: -v
==9682==
==9682==
==9682== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1)
==9682== malloc/free: in use at exit: 10,566 bytes in 128 blocks.
==9682== malloc/free: 1,036 allocs, 908 frees, 341,973 bytes allocated.
==9682== For counts of detected errors, rerun with: -v
==9682== searching for pointers to 128 not-freed blocks.
==9682== checked 17,555,040 bytes.
==9682==
==9682== 576 bytes in 2 blocks are possibly lost in loss record 6 of 9
==9682==    at 0x4A1DB36: calloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==9682==    by 0x400F212: _dl_allocate_tls (dl-tls.c:304)
==9682==    by 0x6CFBA3B: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.4.so)
==9682==    by 0x648B4F8: QThread::start(QThread::Priority) (qthread_unix.cpp:443)
==9682==    by 0x4011BB: main (main.cpp:36)
==9682==
==9682== LEAK SUMMARY:
==9682==    definitely lost: 0 bytes in 0 blocks.
==9682==      possibly lost: 576 bytes in 2 blocks.
==9682==    still reachable: 9,990 bytes in 126 blocks.
==9682==         suppressed: 0 bytes in 0 blocks.
==9682== Reachable blocks (those to which a pointer was found) are not shown.
==9682== To see them, rerun with: --show-reachable=yes

output for 10000 loop

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ns@ns-00 toto]$ valgrind --leak-check=full ./toto | grep -v "here I am"
==31891== Memcheck, a memory error detector.
==31891== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==31891== Using LibVEX rev 1606, a library for dynamic binary translation.
==31891== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==31891== Using valgrind-3.2.0, a dynamic binary instrumentation framework.
==31891== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==31891== For more details, rerun with: -v
==31891==
==31891==
==31891== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1)
==31891== malloc/free: in use at exit: 11,582 bytes in 127 blocks.
==31891== malloc/free: 83,944 allocs, 83,817 frees, 29,505,909 bytes allocated.
==31891== For counts of detected errors, rerun with: -v
==31891== searching for pointers to 127 not-freed blocks.
==31891== checked 17,556,280 bytes.
==31891==
==31891== 576 bytes in 2 blocks are possibly lost in loss record 7 of 10
==31891==    at 0x4A1DB36: calloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==31891==    by 0x400F212: _dl_allocate_tls (dl-tls.c:304)
==31891==    by 0x6CFBA3B: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.4.so)
==31891==    by 0x648B4F8: QThread::start(QThread::Priority) (qthread_unix.cpp:443)
==31891==    by 0x4011BB: main (main.cpp:36)
==31891==
==31891== LEAK SUMMARY:
==31891==    definitely lost: 0 bytes in 0 blocks.
==31891==      possibly lost: 576 bytes in 2 blocks.
==31891==    still reachable: 11,006 bytes in 125 blocks.
==31891==         suppressed: 0 bytes in 0 blocks.
==31891== Reachable blocks (those to which a pointer was found) are not shown.
==31891== To see them, rerun with: --show-reachable=yes

notice also that these bytes are allocated in _dl_allocate_tls, not in QThread::start
ie: not by Qt
Nicolas

This post has been edited 4 times, last edit by "Nicolas SOUCHON" (May 10th 2008, 11:07pm)

  • Go to the top of the page

rlgomes

Beginner

Posts: 3

Location: San Mateo, California

3

Sunday, May 11th 2008, 12:18am

Now that you mention if I had looked closely I would have seen that in fact the call is into the pthreads library. I googled for this and have found that if you don't use the pthread_detach call on each of your pthread_create calls the you are going to in fact be leaking these bytes all the time (source http://gelorakan.wordpress.com/2007/11/2…ry-leak-solved/).

I also opened up the source for QThread and found that qthread_unix.cpp (since I'm on linux) does not have any call to pthread_detach. This isn't a big issue since it doesn't add up but it would be nice to have a nice clean solution since the rest of the code is well written ;)

For now I will simply have line to suppress this warning in my valgrind suppression file.

Rodney.
  • Go to the top of the page

4

Sunday, May 11th 2008, 9:00am

I'm not very familiar with Valgrind.
I used it with one of my application and had a very very ... long list
of possible errors that I've estimated as to be ignored.
Could you please send an example of Valgrind suppression file?
Nicolas
  • Go to the top of the page

rlgomes

Beginner

Posts: 3

Location: San Mateo, California

5

Monday, May 12th 2008, 6:33pm

In valgrind its pretty easy to generate suppression rules because you can run it with --gen-suppressions=yes and then you can pick for each of the "issues" which ones to generate (to your STDOUT) the suppression rule. Then you add that to your supression file and reference it in your valgrind run with --supessions=yoursupressionfile.

That's the shorter answer I could put a valgrind example up for this case if you'd really like ? (or we can take this offline on our personal email)

Rodney.
  • Go to the top of the page

6

Monday, May 12th 2008, 7:26pm

Thank you

I've done it with --gen-suppressions
Nicolas
  • Go to the top of the page

Rate this thread