- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
These objects are created for detached threads and live till end of the program. Objects are destroyed when program ends. you can check this by calling parallel_for_each for 1000 times on the same data. If there are much more leaks then there is a memory leak
Consider the sample - in the sample below you will get similar leaks.
#include <thread> int main() { std::thread t([](){}); return 0; }
--Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I suppose you have comment everyhing out but still link with tbb. In this case there will be static initialization of TLS storage with auto_terminate key on program exit.
Regarding "be bothered about the leaks": you are not first who reports this false positive so it would be good to understand how we can hide this diagnistics for these particular hits.
--Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
These are not false positives. While it is true that the application program (user code) does not have a leak, none the less, heap space was allocated (e.g. static initialization of TLS storage with auto_terminate key on program exit, etc...), yet not returned. Hiding the information is not an appropriate action (even though it would cut down on the complaints about memory leaks). A better route IMHO is to have a static or stack space, that during initialization (where these persistent objects are allocated) perform a heap context switch to use the static or stack space, then heap context back just prior to entry into main. Seeing that you know how to overload new, delete, malloc, free, this should be a QED. The heap contex switch may have to take into consideration any additional context introduced with valgrind (though that be hidden with the overload).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This looks like an idea to make yet another TBB allocator:)
But anyway putting static structures to .data section sounds reasonable...
thanks,
--Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir,
Since it may be that you only have a few such dynamically allocated objects (or at least a few different types), the easiest route might be to use "placement new" on a piece of a static data block. IOW you do not malloc. use alloca if on the pre-main call stack or just grab the next n bytes of the static data block (aligned if you wish).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd also like to see some solution. Clang's address sanitizer complains about this same issue:
rnburn@localhost ~/bugs/tbb_leak $ ./a.out
================================================================= ==19570==ERROR: LeakSanitizer: detected memory leaks Direct leak of 3096 byte(s) in 3 object(s) allocated from: #0 0x4cb18b in operator new[](unsigned long) /root/clang-march30_15/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:64:37 #1 0x7f7666e1b21e in tbb::internal::task_stream<3>::initialize(unsigned int) /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/task_stream.h:94 #2 0x7f7666e17658 in tbb::internal::arena::arena(tbb::internal::market&, unsigned int) /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/arena.cpp:167 #3 0x7f7666e17812 in tbb::internal::arena::allocate_arena(tbb::internal::market&, unsigned int) /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/arena.cpp:191 #4 0x7f7666e14504 in tbb::internal::market::create_arena(unsigned int, unsigned long) /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/market.cpp:164 #5 0x7f7666e133a1 in tbb::internal::governor::init_scheduler(unsigned int, unsigned long, bool) /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/governor.cpp:163 #6 0x7f7666e10446 in tbb::internal::governor::local_scheduler() /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/governor.h:119 #7 0x7f7666e0f979 in tbb::internal::allocate_root_with_context_proxy::allocate(unsigned long) const /root/tbb/tbb43_20141023oss/build/linux_intel64_gcc_cc4.7.3_libc2.17_kernel3.10.25_debug/../../src/tbb/task.cpp:67 #8 0x4cd8e1 in operator new(unsigned long, tbb::internal::allocate_root_with_context_proxy const&) /usr/local/include/tbb/task.h:975:13 #9 0x4cc45a in tbb::interface7::internal::start_for<tbb::blocked_range<int>, tbb::internal::parallel_for_body<main::$_0, int>, tbb::auto_partitioner const>::run(tbb::blocked_range<int> const&, tbb::internal::parallel_for_body<main::$_0, int> const&, tbb::auto_partitioner const&) /usr/local/include/tbb/parallel_for.h:88:33 #10 0x4cc1d3 in void tbb::strict_ppl::parallel_for_impl<int, main::$_0, tbb::auto_partitioner const>(int, int, int, main::$_0 const&, tbb::auto_partitioner const&) /usr/local/include/tbb/parallel_for.h:254:9 #11 0x4cc078 in void tbb::strict_ppl::parallel_for<int, main::$_0>(int, int, main::$_0 const&) /usr/local/include/tbb/parallel_for.h:282:5 #12 0x4cbfad in main /home/rnburn/bugs/tbb_leak/main.cpp:15:3 #13 0x7f7665f1fb94 in __libc_start_main (/lib64/libc.so.6+0x24b94) SUMMARY: AddressSanitizer: 3096 byte(s) leaked in 3 allocation(s).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is not the same issue. As far as I can see there is a parallel_for call but not empty program.
--Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
Since it may be that you only have a few such dynamically allocated objects (or at least a few different types), the easiest route might be to use "placement new" on a piece of a static data block. IOW you do not malloc. use alloca if on the pre-main call stack or just grab the next n bytes of the static data block (aligned if you wish).
We have checked again, all needed objects are static and located in .data section. Memory leak reported due to pthread_key_create() call. We can't control pthread library.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Then it might be advisable to note this in a FAQ or known issues section of the documents (I didn't look to see if this is in there already).
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page