ERROR: enumerable_thread_specific prematurely deleted

ERROR: enumerable_thread_specific prematurely deleted

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).

AttachmentSize
Download test.cpp5.53 KB
4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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

Attachments: 

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

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

Leave a Comment

Please sign in to add a comment. Not a member? Join today