Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

ERROR: enumerable_thread_specific prematurely deleted

Walter_D_
Beginner
354 Views

I encountered a strange problem with enumerable_thread_specific: a enumerable_thread_specific object got deleted prematurely when a root task using it was spawned from a variadic template function (which I added for convenience to a base of the task). See attached code. Tested using gcc 4.7.0 and 4.8 only.

It seems that, for some reason, the scope of the enumerable_thread_specific object is truncated when the variadic template is used for spawning the root task. In case the thread local object's destructor de-allocates from the heap, I get a segmentation fault (not with the simple test code attached).

0 Kudos
3 Replies
Christophe_H_Intel
354 Views

Hello, Walter,

I just tried your test case with a couple of additions.  I printed the addressed of the ETS on construction and destruction, and on construction of the my_tasks.  I am running

C:\cahuson\dvlp\trunk\tbb\1.0\build\windows_intel64_gcc_mingw4.8.0_debug>gcc --version
gcc (rubenvb-4.8.0) 4.8.0
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I am attaching the altered source and a patch containing my changes to enumerable_thread_specific.h.  The results I see are

C:\cahuson\dvlp\trunk\tbb\1.0\build\windows_intel64_gcc_mingw4.8.0_debug>test_gcc48_ets.exe
 functor Constructing 2292752
Created a my_task with d == 2292752
 Returned from SRAW
 result 1 = 499500
Destructing 2292752
 functor Constructing 2292752
Created a my_task with d == 2292752
 Returned from SRAW
 result 2 = 499500
Destructing 2292752
 functor Constructing 2292752
Start of variadic verion
Created a my_task with d == 2293072    <em><== NOTE: this ETS was never constructed</em>
return from variadic version
Destructing 2293072
 Returned from SRAW
pdata.begin() == 1
 result 3 = 0
Destructing 2292752

What I see is an incorrect parameter passed in the parameter pack to the constructor in (in my version) line 108.

It looks like a bug in GCC.  If you see something I don't, please let me know.

Best Regards,
Chris

0 Kudos
Walter_D_
Beginner
354 Views

Hi Chris,

I had a deeper look and it seems that the bug is in my code, not in gcc.

What happens is that my variadic template version of spawn_root_and_wait() creates a copy of the enumerable_thread_specific from the argument passed to it. The copy is then used but also destroyed inside this function. This was already clear from your test, since the destructor is called before "Returned from SRAW". Of course, the original object then from which the copy was taken has no data.

Thus, to avoid that one must make sure that the argument passed is a reference (or pointer) via std::ref, as in

my_task<2>::spawn_root_and_wait(std::ref(pdata),0,num,4);

cheers, Walter.

thanks for your help, Walter

0 Kudos
Christophe_H_Intel
354 Views

Hello, Walter,

I'm glad you were able to find it.  Now that you mention it, it does look like I didn't print anything from the enumerable_thread_specific copy-constructor, so I didn't see the copy being made.

Best Regards,
Chris

0 Kudos
Reply