Solved Memory leak in QtConcurrent::run() ?
-
Hello,
I am experiencing some unpleasant problem with QtConcurrent::run(). Sometimes it has possibly lost bytes sometimes it does not. Can someone explain me what is happening here? Thank you. QT Version - qt5-base 5.13.0, GCC version - 9.1.0, Arch Linux
Code here:
#include <qfuture.h> #include <QtConcurrent/QtConcurrent> QFuture<int> AsyncFunction() { auto task = QtConcurrent::run([]() { return 5; }); return task; } void testAsyncException() { auto task = AsyncFunction(); task.waitForFinished(); } int main () { testAsyncException(); }
Valgrind output: "valgrind --leak-check=full ./Sandbox" - Grep Error Summary for 10 runs
==13333== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13336== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13345== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13354== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13363== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13372== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==13381== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==13391== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ==13400== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==13406== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Valgrind output for the error:
==14117== Memcheck, a memory error detector ==14117== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==14117== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==14117== Command: ./Sandbox ==14117== ==14117== ==14117== HEAP SUMMARY: ==14117== in use at exit: 19,884 bytes in 23 blocks ==14117== total heap usage: 79 allocs, 56 frees, 98,073 bytes allocated ==14117== ==14117== 320 bytes in 1 blocks are possibly lost in loss record 21 of 23 ==14117== at 0x483AB65: calloc (vg_replace_malloc.c:752) ==14117== by 0x4012AC1: allocate_dtv (in /usr/lib/ld-2.29.so) ==14117== by 0x4013431: _dl_allocate_tls (in /usr/lib/ld-2.29.so) ==14117== by 0x4D991AD: pthread_create@@GLIBC_2.2.5 (in /usr/lib/libpthread-2.29.so) ==14117== by 0x4946F9B: QThread::start(QThread::Priority) (in /usr/lib/libQt5Core.so.5.13.0) ==14117== by 0x4949E44: QThreadPoolPrivate::startThread(QRunnable*) (in /usr/lib/libQt5Core.so.5.13.0) ==14117== by 0x494AEEB: QThreadPoolPrivate::tryStart(QRunnable*) (in /usr/lib/libQt5Core.so.5.13.0) ==14117== by 0x494B5E9: QThreadPool::start(QRunnable*, int) (in /usr/lib/libQt5Core.so.5.13.0) ==14117== by 0x10AEE2: QtConcurrent::RunFunctionTaskBase<int>::start(QThreadPool*) (qtconcurrentrunbase.h:87) ==14117== by 0x10AC75: QtConcurrent::RunFunctionTaskBase<int>::start() (qtconcurrentrunbase.h:78) ==14117== by 0x10A493: std::enable_if<!QtPrivate::HasResultType<AsyncFunction()::{lambda()#1}>::Value, QFuture<decltype ({parm#1}())> >::type QtConcurrent::run<AsyncFunction()::{lambda()#1}>(QtPrivate::HasResultType) (qtconcurrentrun.h:108) ==14117== by 0x10A3AF: AsyncFunction() (main.cpp:9) ==14117== ==14117== LEAK SUMMARY: ==14117== definitely lost: 0 bytes in 0 blocks ==14117== indirectly lost: 0 bytes in 0 blocks ==14117== possibly lost: 320 bytes in 1 blocks ==14117== still reachable: 19,564 bytes in 22 blocks ==14117== suppressed: 0 bytes in 0 blocks ==14117== Reachable blocks (those to which a pointer was found) are not shown. ==14117== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==14117== ==14117== For counts of detected and suppressed errors, rerun with: -v ==14117== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0
-
This is no memleak in a way you should worry about, it's one block which is needed to handle the different threads afaiu. It's created once and not deleted because there may be other threads created afterwards.
And even if you define it as memleak it's not Qt's fault since pthread is not Qt. And searching for dl_allocate_tls will show you that others also stumbled upon this. -
Awesome, thank you.. I was not sure because the possibly lost block was not reported by valgrind on each run.