[thread] Memory leak in Boost.Thread?

Hello, a Fedora user has reported a potential memory leak in Boost.Thread (see https://bugzilla.redhat.com/show_bug.cgi?id=627875 for details), detected with Valgrind in (at least) versions 1.41.0 and 1.44.0. Following is a code snippet allowing to reproduce the issue: ==================================== #include <boost/thread.hpp> void someWork() { double a; for(int i= 0;i< 1000;i++) { a+=log((double)i); } } int main() { for(int i = 0; i< 10; ++i) { boost::thread_group pool; for(int j = 0; j< 100; ++j) { pool.create_thread(someWork); } pool.join_all(); } } ==================================== Then, following is Valgrind's report: ==================================== ==6442== Memcheck, a memory error detector ==6442== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==6442== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==6442== Command: ./boost_leak ==6442== ==6442== ==6442== HEAP SUMMARY: ==6442== in use at exit: 8 bytes in 1 blocks ==6442== total heap usage: 5,967 allocs, 5,966 frees, 701,720 bytes allocated ==6442== ==6442== 8 bytes in 1 blocks are still reachable in loss record 1 of 1 ==6442== at 0x4C2615D: malloc (vg_replace_malloc.c:195) ==6442== by 0x4E3F989: boost::detail::get_once_per_thread_epoch() (in /usr/lib64/libboost_thread-mt.so.1.44.0) ==6442== by 0x4E39923: ??? (in /usr/lib64/libboost_thread-mt.so.1.44.0) ==6442== by 0x4E39BC8: boost::detail::get_current_thread_data() (in /usr/lib64/libboost_thread-mt.so.1.44.0) ==6442== by 0x4E3A528: boost::this_thread::interruption_enabled() (in /usr/lib64/libboost_thread-mt.so.1.44.0) ==6442== by 0x4E3A548: boost::this_thread::disable_interruption::disable_interruption() (in /usr/lib64/libboost_thread-mt.so.1.44.0) ==6442== by 0x404DC4: boost::shared_mutex::lock() (in /tmp/boost_leak) ==6442== by 0x40588D: boost::lock_guard<boost::shared_mutex>::lock_guard(boost::shared_mutex&) (in /tmp/boost_leak) ==6442== by 0x405DB5: boost::thread* boost::thread_group::create_thread<void (*)()>(void (*)()) (in /tmp/boost_leak) ==6442== by 0x403B91: main (in /tmp/boost_leak) ==6442== ==6442== LEAK SUMMARY: ==6442== definitely lost: 0 bytes in 0 blocks ==6442== indirectly lost: 0 bytes in 0 blocks ==6442== possibly lost: 0 bytes in 0 blocks ==6442== still reachable: 8 bytes in 1 blocks ==6442== suppressed: 0 bytes in 0 blocks ==6442== ==6442== For counts of detected and suppressed errors, rerun with: -v ==6442== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6) ==================================== Is that really a memory leak? Kind Regards Denis

Hello,
a Fedora user has reported a potential memory leak in Boost.Thread (see https://bugzilla.redhat.com/show_bug.cgi?id=627875 for details), detected with Valgrind in (at least) versions 1.41.0 and 1.44.0.
Is that really a memory leak?
most likely not. the memory in question is freed by a deleter of pthread_key_create, which means when the (main) thread is exited. valgrind apparently does the leak checking before that. here's the code in question: http://svn.boost.org/svn/boost/trunk/libs/thread/src/pthread/once.cpp

2010/8/27 Denis Arnaud <denis.arnaud_boost@m4x.org>
Hello,
a Fedora user has reported a potential memory leak in Boost.Thread (see https://bugzilla.redhat.com/show_bug.cgi?id=627875 for details), detected with Valgrind in (at least) versions 1.41.0 and 1.44.0.
Apparently, as per https://bugzilla.redhat.com/show_bug.cgi?id=627875#c7 , it seems there is a bug in Boost Thread. As I'm not a specialist in that area, I prefer to hand it over to more savvy developers on the list. Do not hesitate to answer directly on Bugzilla. Regards Denis

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 29 September 2010, Denis Arnaud wrote:
2010/8/27 Denis Arnaud <denis.arnaud_boost@m4x.org>
Hello,
a Fedora user has reported a potential memory leak in Boost.Thread (see https://bugzilla.redhat.com/show_bug.cgi?id=627875 for details), detected with Valgrind in (at least) versions 1.41.0 and 1.44.0.
Apparently, as per https://bugzilla.redhat.com/show_bug.cgi?id=627875#c7 , it seems there is a bug in Boost Thread.
As I'm not a specialist in that area, I prefer to hand it over to more savvy developers on the list. Do not hesitate to answer directly on Bugzilla.
As far as I can tell, the "fix" for this "bug" is to insure some per-thread memory is freed just before the entire program exits? The only point to doing that would be to quiet valgrind. Maybe the reason posix threads don't invoke their per-thread data destructors is that it is pointless? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkyjkNUACgkQ5vihyNWuA4UqbwCeP9SYukja0bDnp0txFRgHfJ0a sxIAoMmO4Fw+0T13v/0QPVWFAt+kuxXB =VDET -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 29 September 2010, Frank Mori Hess wrote:
Maybe the reason posix threads don't invoke their per-thread data destructors is that it is pointless?
Err, I meant to say they don't invoke when the thread is killed due to the main thread exiting. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkyjkVMACgkQ5vihyNWuA4Ug+QCcCM+vjYDMtIQ8cQ4dxgMWtRS2 RBQAn0BfA8ETCYasXN2kqCuoN2dr0W6x =Lte8 -----END PGP SIGNATURE-----

2010/9/30 <boost-request@lists.boost.org>
Date: Wed, 29 Sep 2010 15:17:40 -0400 From: Frank Mori Hess <frank.hess@nist.gov>
a Fedora user has reported a potential memory leak in Boost.Thread (see https://bugzilla.redhat.com/show_bug.cgi?id=627875 for details), detected with Valgrind in (at least) versions 1.41.0 and 1.44.0.
Apparently, as per https://bugzilla.redhat.com/show_bug.cgi?id=627875#c7, it seems there is a bug in Boost Thread.
As I'm not a specialist in that area, I prefer to hand it over to more savvy developers on the list. Do not hesitate to answer directly on Bugzilla.
As far as I can tell, the "fix" for this "bug" is to insure some per-thread memory is freed just before the entire program exits? The only point to doing that would be to quiet valgrind.
Maybe the reason posix threads don't invoke their per-thread data
destructors is that it is pointless? I mean to say they don't invoke when the thread is killed due to the main thread exiting.
What do you think of Bart's suggestion in https://bugzilla.redhat.com/show_bug.cgi?id=627875#c9 (i.e., adding "some comments in the two source files libs/thread/src/pthread/once.<https://svn.boost.org/trac/boost/browser/trunk/libs/thread/src/pthread/once.cpp> cpp<https://svn.boost.org/trac/boost/browser/trunk/libs/thread/src/pthread/once.cpp>and libs/thread/src/pthread/<https://svn.boost.org/trac/boost/browser/trunk/libs/thread/src/pthread/thread.cpp> thread.cpp<https://svn.boost.org/trac/boost/browser/trunk/libs/thread/src/pthread/thread.cpp>, that even when an application exit()s normally it is possible that the destructor is not invoked, together with the a reference to the POSIX specs that explain this behavior, e.g., http://opengroup.org/onlinepubs/9699919799/functions/_Exit.html#tag_16_01_03... )? I've looked into the Gmane archive of the Boost developer list ( http://search.gmane.org/?query=thread+memory+leak&group=gmane.comp.lib.boost.devel), and that issue has been raised several times during (at least) the last six years, with sometimes the same recommendation: to add some comments in the source code. For instance, http://thread.gmane.org/gmane.comp.lib.boost.devel/145329/focus=145333, http://thread.gmane.org/gmane.comp.lib.boost.devel/96846/focus=97232, http://thread.gmane.org/gmane.comp.lib.boost.devel/187881/focus=187893. Regards Denis
participants (3)
-
Denis Arnaud
-
Frank Mori Hess
-
Stefan Strasser