This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/60966] New: std::call_once sometime hangs


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<void> 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<std::mutex>&) () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x0000000000647555 in
std::condition_variable::wait<std::__future_base::_State_base::wait()::{lambda()#1}>(std::unique_lock<std::mutex>&,
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<void>::_M_get_result
(this=0x7fffffffa150) at /usr/include/c++/4.8/future:595
#5  0x00000000006b1626 in std::future<void>::get (this=0x7fffffffa150) at
/usr/include/c++/4.8/future:760
#6  0x00000000006acb21 in HTTPP::HTTP::client::detail::Manager::~Manager
(this=0x9efe90, __in_chrg=<optimized out>) at
/home/daedric/perso/httpp/src/httpp/http/client/Manager.cpp:113
#7  0x000000000069d92a in
std::default_delete<HTTPP::HTTP::client::detail::Manager>::operator()
(this=0x9f1168, __ptr=0x9efe90) at /usr/include/c++/4.8/bits/unique_ptr.h:67
#8  0x000000000069d53c in std::unique_ptr<HTTPP::HTTP::client::detail::Manager,
std::default_delete<HTTPP::HTTP::client::detail::Manager> >::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=<optimized out>) at
/home/daedric/perso/httpp/src/httpp/HttpClient.cpp:48
#10 0x000000000065724e in etcd::Etcd::Connection::~Connection (this=0x9f10c0,
__in_chrg=<optimized out>) at /home/daedric/work/broker/broker/etcd/Etcd.cpp:28
#11 0x000000000065727e in
std::default_delete<etcd::Etcd::Connection>::operator() (this=0xa27780,
__ptr=0x9f10c0) at /usr/include/c++/4.8/bits/unique_ptr.h:67
#12 0x0000000000655f1b in std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >::~unique_ptr (this=0xa27780,
__in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/unique_ptr.h:184
#13 0x000000000065483e in std::_Destroy<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> > > (__pointer=0xa27780) at
/usr/include/c++/4.8/bits/stl_construct.h:93
#14 0x000000000065295c in
std::_Destroy_aux<false>::__destroy<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >*> (__first=0xa27780,
__last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:103
#15 0x000000000064fefb in std::_Destroy<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >*> (__first=0xa27780,
__last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:126
#16 0x000000000064c065 in std::_Destroy<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >*,
std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> > > (__first=0xa27780,
__last=0xa27788) at /usr/include/c++/4.8/bits/stl_construct.h:151
#17 0x000000000064d4c8 in std::vector<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >,
std::allocator<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> > > >::_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::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> >,
std::allocator<std::unique_ptr<etcd::Etcd::Connection,
std::default_delete<etcd::Etcd::Connection> > > >::clear (this=0x7fffffffaf00)
at /usr/include/c++/4.8/bits/stl_vector.h:1126
#19 0x000000000063ccb0 in etcd::Etcd::~Etcd (this=0x7fffffffaea0,
__in_chrg=<optimized out>) 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<boost::unit_test::ut_detail::unused>::invoke<void
(*)()> (this=0x7fffffffd6ef, f=@0x9e8048: 0x6300bb <basic_invoker()>) at
/usr/include/boost/test/utils/callback.hpp:56
#23 0x000000000063bbb4 in
boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,
void (*)()>::invoke (this=0x9e8040) at
/usr/include/boost/test/utils/callback.hpp:89
#24 0x00000000006ded01 in boost::unit_test::ut_detail::callback0_impl_t<int,
boost::unit_test::(anonymous
namespace)::zero_return_wrapper_t<boost::unit_test::callback0<boost::unit_test::ut_detail::unused>
> >::invoke() ()
#25 0x00000000006feeb6 in
boost::execution_monitor::catch_signals(boost::unit_test::callback0<int>
const&) ()
#26 0x00000000006ff6c3 in
boost::execution_monitor::execute(boost::unit_test::callback0<int> 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 <main>, argc=1,
argv=0x7fffffffe4e8, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, 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<void
(std::__future_base::_State_base::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>&, bool&),
std::__future_base::_State_base* const,
std::reference_wrapper<std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()> >, std::reference_wrapper<bool>
>(std::once_flag&, void
(std::__future_base::_State_base::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>&, bool&),
std::__future_base::_State_base* const&&,
std::reference_wrapper<std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()> >&&,
std::reference_wrapper<bool>&&) (__once=..., __f=<unknown type in
/home/daedric/work/broker/build/tests/etcd/Test_Etcd_tree, CU 0x2582b2, DIE
0x296a80>)
    at /usr/include/c++/4.8/mutex:786
#3  0x00000000006a1689 in
std::__future_base::_State_base::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>, bool) (this=0xa28958,
__res=..., __ignore_failure=false) at /usr/include/c++/4.8/future:358
#4  0x00000000006b19df in std::promise<void>::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::~Manager()::__lambda5>(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::~Manager()::__lambda5,
HTTPP::HTTP::client::detail::Manager::~Manager()::__lambda5>(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<HTTPP::HTTP::client::detail::Manager::~Manager()::__lambda5>::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<void ()>)
(this=0x9f10c8, fct=...) at
/home/daedric/perso/httpp/src/httpp/utils/ThreadPool.cpp:114
#14 0x00000000006c0d0e in std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>::operator()<HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0&,
void>(HTTPP::UTILS::ThreadPool *) const (this=0xa275c0, __object=0x9f10c8) at
/usr/include/c++/4.8/functional:601
#15 0x00000000006c0bd1 in std::_Bind<std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>(HTTPP::UTILS::ThreadPool*,
HTTPP::UTILS::ThreadPool::start(HTTPP::UTILS::ThreadPool::ThreadInit)::__lambda0)>::__call<void,
0ul, 1ul>(<unknown type in
/home/daedric/work/broker/build/tests/etcd/Test_Etcd_tree, CU 0x322b8a, DIE
0x3501ae>, std::_Index_tuple<0ul, 1ul>) (this=0xa275c0, __args=<unknown type in
/home/daedric/work/broker/build/tests/etcd/Test_Etcd_tree, CU 0x322b8a, DIE
0x3501ae>) at /usr/include/c++/4.8/functional:1296
#16 0x00000000006c0aec in std::_Bind<std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>(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<std::_Bind<std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>(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<std::_Bind<std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>(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<std::_Bind_simple<std::_Bind<std::_Mem_fn<void
(HTTPP::UTILS::ThreadPool::*)(std::function<void()>)>(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<void
(std::__future_base::_State_base::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>&, bool&),
std::__future_base::_State_base* const,
std::reference_wrapper<std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()> >, std::reference_wrapper<bool>
>(std::once_flag&, void
(std::__future_base::_State_base::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>&, bool&),
std::__future_base::_State_base* const&&,
std::reference_wrapper<std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()> >&&,
std::reference_wrapper<bool>&&) (mutex:786)
==3079==    by 0x6A1688:
std::__future_base::_State_base::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>, bool) (future:358)
==3079==    by 0x6B19DE: std::promise<void>::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}>(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}>(HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#1}&,
{lambda()#1}&) (handler_invoke_helpers.hpp:37)
==3079==    by 0x6B0947:
boost::asio::detail::completion_handler<HTTPP::HTTP::client::detail::Manager::~Manager()::{lambda()#1}>::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::posix_mutex>&,
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<std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>, (__gnu_cxx::_Lock_policy)2>
>::deallocate(std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>, (__gnu_cxx::_Lock_policy)2>*,
unsigned long) (new_allocator.h:110)
==3079==    by 0x6AA570:
std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>, (__gnu_cxx::_Lock_policy)2> >
>::deallocate(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>, (__gnu_cxx::_Lock_policy)2>
>&, std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>, (__gnu_cxx::_Lock_policy)2>*,
unsigned long) (alloc_traits.h:377)
==3079==    by 0x6AB95D:
std::_Sp_counted_ptr_inplace<std::__future_base::_State_base,
std::allocator<std::__future_base::_State_base>,
(__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<std::__future_base::_State_base,
(__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:781)
==3079==    by 0x69CD89:
std::shared_ptr<std::__future_base::_State_base>::~shared_ptr()
(shared_ptr.h:93)
==3079==    by 0x6B1809: std::promise<void>::~promise() (future:1136)
==3079==    by 0x6AC9C9: HTTPP::HTTP::client::detail::Manager::~Manager()
(Manager.cpp:93)
==3079==    by 0x69D929:
std::default_delete<HTTPP::HTTP::client::detail::Manager>::operator()(HTTPP::HTTP::client::detail::Manager*)
const (unique_ptr.h:67)
==3079==    by 0x69D53B: std::unique_ptr<HTTPP::HTTP::client::detail::Manager,
std::default_delete<HTTPP::HTTP::client::detail::Manager>
>::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,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]