From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30467 invoked by alias); 25 Apr 2014 13:57:41 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 30430 invoked by uid 48); 25 Apr 2014 13:57:35 -0000 From: "thomas.sanchz at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/60966] New: std::call_once sometime hangs Date: Fri, 25 Apr 2014 13:57:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 4.8.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: thomas.sanchz at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-04/txt/msg01914.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60966 Bug ID: 60966 Summary: std::call_once sometime hangs Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: thomas.sanchz at gmail dot com Hi, I'm really sorry for the vague bug report and not being able to give a small piece of code to reproduce the bug. Here is what I'm experiencing: I developed a small library which performs http request, the library is built around curl. I'm using std::promise/future in order to push a task to do in the thread were all the operation on the handle is done. for example, here is an example of some of the piece of the code I have: { std::promise promise; auto future = promise.get_future(); io.dispatch([this, &promise] { checkHandles(); promise.set_value(); }); future.get(); } Sometimes, it can hangs on the set_value() with this kind of stack trace: (gdb) bt #0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185 #1 0x00007ffff74f766c in std::condition_variable::wait(std::unique_lock&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x0000000000647555 in std::condition_variable::wait(std::unique_lock&, std::__future_base::_State_base::wait()::{lambda()#1}) (this=0xa28990, __lock=..., __p=...) at /usr/include/c++/4.8/condition_variable:93 #3 0x0000000000643d1c in std::__future_base::_State_base::wait (this=0xa28958) at /usr/include/c++/4.8/future:327 #4 0x00000000006b29bf in std::__basic_future::_M_get_result (this=0x7fffffffa150) at /usr/include/c++/4.8/future:595 #5 0x00000000006b1626 in std::future::get (this=0x7fffffffa150) at /usr/include/c++/4.8/future:760 #6 0x00000000006acb21 in HTTPP::HTTP::client::detail::Manager::~Manager (this=0x9efe90, __in_chrg=) at /home/daedric/perso/httpp/src/httpp/http/client/Manager.cpp:113 #7 0x000000000069d92a in std::default_delete::operator() (this=0x9f1168, __ptr=0x9efe90) at /usr/include/c++/4.8/bits/unique_ptr.h:67 #8 0x000000000069d53c in std::unique_ptr >::reset (this=0x9f1168, __p=0x9efe90) at /usr/include/c++/4.8/bits/unique_ptr.h:262 #9 0x000000000069b17f in HTTPP::HttpClient::~HttpClient (this=0x9f10c8, __in_chrg=) at /home/daedric/perso/httpp/src/httpp/HttpClient.cpp:48 #10 0x000000000065724e in etcd::Etcd::Connection::~Connection (this=0x9f10c0, __in_chrg=) at /home/daedric/work/broker/broker/etcd/Etcd.cpp:28 #11 0x000000000065727e in std::default_delete::operator() (this=0xa27780, __ptr=0x9f10c0) at /usr/include/c++/4.8/bits/unique_ptr.h:67 #12 0x0000000000655f1b in std::unique_ptr >::~unique_ptr (this=0xa27780, __in_chrg=) at /usr/include/c++/4.8/bits/unique_ptr.h:184 #13 0x000000000065483e in std::_Destroy > > (__pointer=0xa27780) at /usr/include/c++/4.8/bits/stl_construct.h:93 #14 0x000000000065295c in std::_Destroy_aux::__destroy >*> (__first=0xa27780, __last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:103 #15 0x000000000064fefb in std::_Destroy >*> (__first=0xa27780, __last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:126 #16 0x000000000064c065 in std::_Destroy >*, std::unique_ptr > > (__first=0xa27780, __last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:151 #17 0x000000000064d4c8 in std::vector >, std::allocator > > >::_M_erase_at_end (this=0x7fffffffaf00, __pos=0xa27780) at /usr/include/c++/4.8/bits/stl_vector.h:1352 #18 0x00000000006489c0 in std::vector >, std::allocator > > >::clear (this=0x7fffffffaf00) at /usr/include/c++/4.8/bits/stl_vector.h:1126 #19 0x000000000063ccb0 in etcd::Etcd::~Etcd (this=0x7fffffffaea0, __in_chrg=) at /home/daedric/work/broker/broker/etcd/Etcd.cpp:264 #20 0x000000000063118c in basic::test_method (this=0x7fffffffd68f) at /home/daedric/work/broker/tests/etcd/tree.cpp:70 #21 0x00000000006300cf in basic_invoker () at /home/daedric/work/broker/tests/etcd/tree.cpp:12 #22 0x000000000063bd64 in boost::unit_test::ut_detail::invoker::invoke (this=0x7fffffffd6ef, f=@0x9e8048: 0x6300bb ) at /usr/include/boost/test/utils/callback.hpp:56 #23 0x000000000063bbb4 in boost::unit_test::ut_detail::callback0_impl_t::invoke (this=0x9e8040) at /usr/include/boost/test/utils/callback.hpp:89 #24 0x00000000006ded01 in boost::unit_test::ut_detail::callback0_impl_t > >::invoke() () #25 0x00000000006feeb6 in boost::execution_monitor::catch_signals(boost::unit_test::callback0 const&) () #26 0x00000000006ff6c3 in boost::execution_monitor::execute(boost::unit_test::callback0 const&) () #27 0x00000000006deddb in boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::unit_test::test_case const&) () #28 0x00000000006cd8a4 in boost::unit_test::framework_impl::visit(boost::unit_test::test_case const&) () #29 0x00000000006f62dc in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) () #30 0x00000000006c902b in boost::unit_test::framework::run(unsigned long, bool) () #31 0x00000000006dca94 in boost::unit_test::unit_test_main(boost::unit_test::test_suite* (*)(int, char**), int, char**) () #32 0x00007ffff6e8eec5 in __libc_start_main (main=0x62caa0
, argc=1, argv=0x7fffffffe4e8, init=, fini=, rtld_fini=, stack_end=0x7fffffffe4d8) at libc-start.c:287 #33 0x000000000062ff7f in _start () (gdb) (gdb) thread 2 [Switching to thread 2 (Thread 0x7ffff2011700 (LWP 5256))] #0 pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:94 94 ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S: No such file or directory. (gdb) bt #0 pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:94 #1 0x000000000069e5c3 in __gthread_once (__once=0xa289c4, __func=0x62ab50 <__once_proxy@plt>) at /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:699 #2 0x00000000006a2cd9 in std::call_once ()>&, bool&), std::__future_base::_State_base* const, std::reference_wrapper ()> >, std::reference_wrapper >(std::once_flag&, void (std::__future_base::_State_base::*&&)(std::function ()>&, bool&), std::__future_base::_State_base* const&&, std::reference_wrapper ()> >&&, std::reference_wrapper&&) (__once=..., __f=) at /usr/include/c++/4.8/mutex:786 #3 0x00000000006a1689 in std::__future_base::_State_base::_M_set_result(std::function ()>, bool) (this=0xa28958, __res=..., __ignore_failure=false) at /usr/include/c++/4.8/future:358 #4 0x00000000006b19df in std::promise::set_value (this=0x7fffffffa1a0) at /usr/include/c++/4.8/future:1197 #5 0x00000000006ac879 in HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#2}::operator()() const () at /home/daedric/perso/httpp/src/httpp/http/client/Manager.cpp:111 #6 0x00000000006b0a05 in boost::asio::asio_handler_invoke(HTTPP::HTTP::client::detail::Manager::__lambda5, ...) (function=...) at /usr/include/boost/asio/handler_invoke_hook.hpp:64 #7 0x00000000006b0448 in boost_asio_handler_invoke_helpers::invoke(HTTPP::HTTP::client::detail::Manager::__lambda5 &, HTTPP::HTTP::client::detail::Manager::__lambda5 &) (function=..., context=...) at /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37 #8 0x00000000006b0b3c in boost::asio::detail::completion_handler::do_complete(boost::asio::detail::io_service_impl *, boost::asio::detail::operation *, const boost::system::error_code &, std::size_t) (owner=0x9f0830, base=0xa2bd20) at /usr/include/boost/asio/detail/completion_handler.hpp:68 #9 0x00000000006a1970 in boost::asio::detail::task_io_service_operation::complete (this=0xa2bd20, owner=..., ec=..., bytes_transferred=0) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:37 #10 0x00000000006c21b3 in boost::asio::detail::task_io_service::do_run_one (this=0x9f0830, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:384 #11 0x00000000006c1eb7 in boost::asio::detail::task_io_service::run (this=0x9f0830, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:153 #12 0x00000000006c246d in boost::asio::io_service::run (this=0x9efa48) at /usr/include/boost/asio/impl/io_service.ipp:59 #13 0x00000000006bf00b in HTTPP::UTILS::ThreadPool::run(std::function) (this=0x9f10c8, fct=...) at /home/daedric/perso/httpp/src/httpp/utils/ThreadPool.cpp:114 #14 0x00000000006c0d0e in std::_Mem_fn)>::operator()(HTTPP::UTILS::ThreadPool *) const (this=0xa275c0, __object=0x9f10c8) at /usr/include/c++/4.8/functional:601 #15 0x00000000006c0bd1 in std::_Bind)>(HTTPP::UTILS::ThreadPool*, HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>::__call(, std::_Index_tuple<0ul, 1ul>) (this=0xa275c0, __args=) at /usr/include/c++/4.8/functional:1296 #16 0x00000000006c0aec in std::_Bind)>(HTTPP::UTILS::ThreadPool*, HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>::operator()<, void>(void) (this=0xa275c0) at /usr/include/c++/4.8/functional:1355 #17 0x00000000006c0a7e in std::_Bind_simple)>(HTTPP::UTILS::ThreadPool*, HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>()>::_M_invoke<>(std::_Index_tuple<>) (this=0xa275c0) at /usr/include/c++/4.8/functional:1732 #18 0x00000000006c09d5 in std::_Bind_simple)>(HTTPP::UTILS::ThreadPool*, HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>()>::operator()(void) (this=0xa275c0) at /usr/include/c++/4.8/functional:1720 #19 0x00000000006c096e in std::thread::_Impl)>(HTTPP::UTILS::ThreadPool*, HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>()> >::_M_run(void) (this=0xa275a8) at /usr/include/c++/4.8/thread:115 #20 0x00007ffff74fabf0 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #21 0x00007ffff7bc4182 in start_thread (arg=0x7ffff2011700) at pthread_create.c:312 #22 0x00007ffff6f6830d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 Valgrind showed this on another run: ==3079== Thread 2: ==3079== Invalid read of size 4 ==3079== at 0x4E44A91: pthread_once (pthread_once.S:111) ==3079== by 0x69E5C2: __gthread_once(int*, void (*)()) (gthr-default.h:699) ==3079== by 0x6A2CD8: void std::call_once ()>&, bool&), std::__future_base::_State_base* const, std::reference_wrapper ()> >, std::reference_wrapper >(std::once_flag&, void (std::__future_base::_State_base::*&&)(std::function ()>&, bool&), std::__future_base::_State_base* const&&, std::reference_wrapper ()> >&&, std::reference_wrapper&&) (mutex:786) ==3079== by 0x6A1688: std::__future_base::_State_base::_M_set_result(std::function ()>, bool) (future:358) ==3079== by 0x6B19DE: std::promise::set_value() (future:1197) ==3079== by 0x6AC7D6: HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#1}::operator()() const (Manager.cpp:90) ==3079== by 0x6B0809: void boost::asio::asio_handler_invoke(HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#1}, ...) (handler_invoke_hook.hpp:64) ==3079== by 0x6B0352: void boost_asio_handler_invoke_helpers::invoke(HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#1}&, {lambda()#1}&) (handler_invoke_helpers.hpp:37) ==3079== by 0x6B0947: boost::asio::detail::completion_handler::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (completion_handler.hpp:68) ==3079== by 0x6A196F: boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (task_io_service_operation.hpp:37) ==3079== by 0x6C21B2: boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) (task_io_service.ipp:384) ==3079== by 0x6C1EB6: boost::asio::detail::task_io_service::run(boost::system::error_code&) (task_io_service.ipp:153) ==3079== Address 0xdf926d4 is 132 bytes inside a block of size 136 free'd ==3079== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==3079== by 0x6AA993: __gnu_cxx::new_allocator, (__gnu_cxx::_Lock_policy)2> >::deallocate(std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>*, unsigned long) (new_allocator.h:110) ==3079== by 0x6AA570: std::allocator_traits, (__gnu_cxx::_Lock_policy)2> > >::deallocate(std::allocator, (__gnu_cxx::_Lock_policy)2> >&, std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>*, unsigned long) (alloc_traits.h:377) ==3079== by 0x6AB95D: std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>::_M_destroy() (shared_ptr_base.h:417) ==3079== by 0x64977D: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:161) ==3079== by 0x645AA8: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:546) ==3079== by 0x643E09: std::__shared_ptr::~__shared_ptr() (shared_ptr_base.h:781) ==3079== by 0x69CD89: std::shared_ptr::~shared_ptr() (shared_ptr.h:93) ==3079== by 0x6B1809: std::promise::~promise() (future:1136) ==3079== by 0x6AC9C9: HTTPP::HTTP::client::detail::Manager::~Manager() (Manager.cpp:93) ==3079== by 0x69D929: std::default_delete::operator()(HTTPP::HTTP::client::detail::Manager*) const (unique_ptr.h:67) ==3079== by 0x69D53B: std::unique_ptr >::reset(HTTPP::HTTP::client::detail::Manager*) (unique_ptr.h:262) For some reason the bug seems to occurs *ONLY* when I use promise/future in the destructor or in function called from the destructor. Could it be related to some optimization performed by either the compiler or the linker ? How can I help to debug such an issue ? If it can be of any help the code I've problem with is the destructor of this class: https://github.com/daedric/httpp/blob/master/src/httpp/http/client/Manager.cpp I'm using GCC 4.8.2 on an ubuntu 14.04 with the default library. Thanks,