tags:

views:

1354

answers:

3

I am trying to debug a large application build using Qt/C++ and valgrind is reporting a lot of memory leak from internal Qt stuff. Could anyone share a proper valgrind suppression file for Qt apps ?

Thanks !

Eg.

#include <qobject.h>
int main()
{
  QObject o;
  return 0;
}

returns:

$ valgrind  --leak-check=full  --show-reachable=yes  ./leak
==12655== Memcheck, a memory error detector
==12655== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==12655== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==12655== Command: ./leak
==12655== 
==12655== 
==12655== HEAP SUMMARY:
==12655==     in use at exit: 744 bytes in 7 blocks
==12655==   total heap usage: 28 allocs, 21 frees, 1,640 bytes allocated
==12655== 
==12655== 16 bytes in 1 blocks are still reachable in loss record 1 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x6203124: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 96 bytes in 1 blocks are still reachable in loss record 2 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x62030FC: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 96 bytes in 1 blocks are still reachable in loss record 3 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x62041CD: QWaitCondition::QWaitCondition() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6200EAF: ??? (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62010A0: ??? (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6203132: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 120 bytes in 1 blocks are still reachable in loss record 4 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x61FE681: QMutex::QMutex(QMutex::RecursionMode) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6200DC8: QThreadData::QThreadData(int) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x620310C: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 120 bytes in 1 blocks are still reachable in loss record 5 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x61FE681: QMutex::QMutex(QMutex::RecursionMode) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6200DE9: QThreadData::QThreadData(int) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x620310C: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 120 bytes in 1 blocks are still reachable in loss record 6 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x61FE681: QMutex::QMutex(QMutex::RecursionMode) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6200E77: ??? (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62010A0: ??? (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6203132: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== 176 bytes in 1 blocks are still reachable in loss record 7 of 7
==12655==    at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220)
==12655==    by 0x6201092: ??? (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x6203132: QThreadData::current() (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x62FC4BC: QObject::QObject(QObject*) (in /usr/lib/libQtCore.so.4.5.2)
==12655==    by 0x4008D2: main (in /tmp/Qt/bin/leak)
==12655== 
==12655== LEAK SUMMARY:
==12655==    definitely lost: 0 bytes in 0 blocks
==12655==    indirectly lost: 0 bytes in 0 blocks
==12655==      possibly lost: 0 bytes in 0 blocks
==12655==    still reachable: 744 bytes in 7 blocks
==12655==         suppressed: 0 bytes in 0 blocks
==12655== 
==12655== For counts of detected and suppressed errors, rerun with: -v
==12655== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 8)
+1  A: 

The above valgrind log reports 0 leaks, i.e. there are no errors.

Intransigent Parsnip
A: 
still reachable: 744 bytes in 7 blocks

If you release QObject o? Do still have the same result?

Update: Just to clarify, this memory will be released by the os when you close the application (so it is not a leak).

However for you own sake it is always good to write a destructor that releases the memory, and it always feels nice to know that you have control over what is allocated and deallocated. (so you don't end up with real memory leaks...)

Johan
Feel free to comment if you downvote.... I don't see any problem with that users should release the memory they alloc (even if it is hidden under a big chunk of qt)
Johan
+2  A: 

--show-reachable shows memory that hasn't actually leaked, even though valgrind calls it a loss record. Your test app doesn't leak any memory.

You don't need any valgrind suppressions for this particular case. For others, maybe, but you should use valgrind's --gen-suppressions option to generate those suppressions for you.

Matt Rogers