Summary: | [C++11] Segmentation fault with std::async and released shared state | ||
---|---|---|---|
Product: | gcc | Reporter: | Ai Azuma <ai.azuma> |
Component: | libstdc++ | Assignee: | Jonathan Wakely <redi> |
Status: | RESOLVED FIXED | ||
Severity: | normal | ||
Priority: | P3 | ||
Version: | 4.8.0 | ||
Target Milestone: | 4.7.2 | ||
Host: | Target: | ||
Build: | Known to work: | 4.6.4 | |
Known to fail: | 4.7.2, 4.8.0 | Last reconfirmed: | 2012-08-17 00:00:00 |
Attachments: | Command-line log |
I suspect the problem is that when _Async_state_common calls _M_thread.join() to wait for the async task, the derived destructor of _Async_state_impl has already run and has destroyed the shared state. If that's correct, the fix would be to add: ~_Async_state_impl() { _M_join(); } Author: redi Date: Sat Aug 25 23:01:40 2012 New Revision: 190672 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190672 Log: PR libstdc++/54297 * include/std/future (~_Async_state_impl): Join thread before derived class members are destroyed. (~_Async_state_common): Only define non-trivial destructor when included from future.cc for ABI compatibility reasons. * src/c++11/future.cc (_GLIBCXX_ABI_COMPAT_ASYNC): Define. * testsuite/30_threads/async/54297.cc: New. Added: trunk/libstdc++-v3/testsuite/30_threads/async/54297.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/future trunk/libstdc++-v3/src/c++11/future.cc Author: redi Date: Sat Aug 25 23:06:07 2012 New Revision: 190673 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190673 Log: PR libstdc++/54297 * include/std/future (~_Async_state_impl): Join thread before derived class members are destroyed. (~_Async_state_common): Only define non-trivial destructor when included from future.cc for ABI compatibility reasons. * src/c++11/future.cc (_GLIBCXX_ABI_COMPAT_ASYNC): Define. * testsuite/30_threads/async/54297.cc: New. Added: branches/gcc-4_7-branch/libstdc++-v3/testsuite/30_threads/async/54297.cc Modified: branches/gcc-4_7-branch/libstdc++-v3/ChangeLog branches/gcc-4_7-branch/libstdc++-v3/include/std/future branches/gcc-4_7-branch/libstdc++-v3/src/c++11/future.cc fixed Author: redi Date: Sun Aug 26 13:49:44 2012 New Revision: 190685 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190685 Log: PR libstdc++/54297 * src/c++11/future.cc (~_Async_state_common): Move to... * src/c++11/compatibility-thread-c++0x.cc (~_Async_state_common): Here. (_GLIBCXX_ABI_COMPAT_ASYNC): Rename to _GLIBCXX_ASYNC_ABI_COMPAT. * include/std/future (_GLIBCXX_ABI_COMPAT_ASYNC): Likewise. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/future trunk/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc trunk/libstdc++-v3/src/c++11/future.cc Author: redi Date: Sun Aug 26 14:09:12 2012 New Revision: 190687 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190687 Log: PR libstdc++/54297 * src/c++11/future.cc (~_Async_state_common): Move to... * src/c++11/compatibility-thread-c++0x.cc (~_Async_state_common): Here. (_GLIBCXX_ABI_COMPAT_ASYNC): Rename to _GLIBCXX_ASYNC_ABI_COMPAT. * include/std/future (_GLIBCXX_ABI_COMPAT_ASYNC): Likewise. Modified: branches/gcc-4_7-branch/libstdc++-v3/ChangeLog branches/gcc-4_7-branch/libstdc++-v3/include/std/future branches/gcc-4_7-branch/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc branches/gcc-4_7-branch/libstdc++-v3/src/c++11/future.cc |
Created attachment 28043 [details] Command-line log The following code causes segfault with GCC 4.8.0 20120812, -std=c++11 and -pthread. ///////////////////////////////////////////////////////////// #include <chrono> #include <thread> #include <future> int work() { std::this_thread::sleep_for(std::chrono::seconds(1)); return 0; } int main() { // Note that the following explicitly named future object // is not necessary to reproduce the problem. std::future<int> f = std::async(std::launch::async, &work); } ///////////////////////////////////////////////////////////// The last invocation of std::future<int>'s destructor blocks the calling thread until the thread launched by std::async finishes the work, according to the 4th bullet of [futures.async]/5. Therefore, this program should terminate successfully. This program also results in segfault with GCC 4.7.2 20120811, but not with 4.6.4 20120810.