5

Test program:

#include <tbb/parallel_invoke.h>

int main(void)
{
    tbb::parallel_invoke([]{},[]{});
    return 0;
}
  1. Compiled using g++ -std=c++11 tmp.cpp -ltbb
  2. Checked with

    valgrind --tool=memcheck --track-origins=yes \
             --leak-check=full --log-file=report ./a.out`
    
  3. libtbb version: 4.0, valgrind version: 3.8.1.

Part of the above test result:

possibly lost: 1,980 bytes in 6 blocks

Question is:

Is this a TBB bug?

Or is this possible lost actually safe, it's just some codes that valgrind does not consider safe?

Anton
  • 6,349
  • 1
  • 25
  • 53
gongzhitaao
  • 6,566
  • 3
  • 36
  • 44
  • I also have problems with memory leaks when I use tbb. – Alex VII May 30 '14 at 13:06
  • Same problem but only since I upgraded TBB to 4.3. It was working without leaks before with 4.2. I detect the leak using VLD. I suspect that the tasks are just not destroyed at all when the scheduler ends running. – Klaim Jan 04 '15 at 11:16
  • There is definitely a memory leak in TBB: see http://stackoverflow.com/questions/19273543/tbb-memory-leaks-when-using-inside-of-mfc-application – gast128 Oct 05 '15 at 12:45

1 Answers1

2

Most likely, it's a false positive, not a bug. There are at least few reasons:

  1. TBB uses its own memory allocator libtbbmalloc, it caches the memory till the process termination and can appear as a leak.
  2. TBB threads run and terminate asynchronously. It is likely that after main() termination, the worker threads are still running. It leads to the same impression for the valgrind

In order to reasonably accuse TBB for a leak, exclude the above factors, e.g:

  1. remove libtbbmalloc.so.2 or tbbmalloc.dll file so running an application with env.variable TBB_VERSION=1 will output TBB: ALLOCATOR malloc but not TBB: ALLOCATOR scalable_malloc
  2. make sure all the TBB threads are terminated

For example

int main()
{
    assert(tbb::tbb_allocator<int>::allocator_type() != tbb::tbb_allocator<int>::scalable);
    { // TBB scope
        tbb::task_scheduler_init scope;
        tbb::parallel_invoke([]{},[]{});
    } // TBB threads start termination here
    sleep(10); // wait for threads to terminate
    return 0;
}
Anton
  • 6,349
  • 1
  • 25
  • 53
  • What about in environments where inserting `sleep(10)` at the end of main won't pass code review? Is there a workaround for this issue, that would allow me to use TBB *and* valgrind *but not* `sleep(10)`? For example, some way to ask TBB to block until all worker threads are shut down cleanly? – Quuxplusone Nov 19 '14 at 18:50
  • 1
    it's the way to diagnose the problem, not to use in production of course – Anton Nov 19 '14 at 18:52
  • @Quuxplusone, there is preview feature which allows to wait for threads to terminate. So, *if* sleep solves the problem, you might consider this blocking termination feature of `tbb::task_scheduler_init` to do the same without sleep() – Anton Nov 19 '14 at 18:56