
19 Jul
2010
19 Jul
'10
9:16 p.m.
On Mon, Jul 19, 2010 at 2:55 PM, OvermindDL1 <overminddl1@gmail.com> wrote: > On Tue, Jul 6, 2010 at 8:00 AM, Ragnar Cederlund > <ragnar.cederlund@illuminatelabs.com> wrote: >> On Fri, Jul 2, 2010 at 5:55 PM, Ragnar Cederlund <ragnar.cederlund...> >> wrote: >>> >>> I'm having trouble with the io_service destructor never completing. >> >> [...] >> >> I've finally been able to reproduce the hang on my own machine and have a >> small example that exhibits this problem (built using Visual Studio 2005 in >> debug mode): >> >> #include <iostream> >> #include <boost/asio.hpp> >> #include <boost/bind.hpp> >> >> using namespace boost::asio; >> >> class ConnectCommand; >> typedef boost::shared_ptr<ConnectCommand> ConnectCommandPtr; >> >> class ConnectCommand { >> public: >> ConnectCommand(io_service &io_service) >> : m_IoService(io_service) >> , m_Socket(io_service) >> {} >> >> void Execute() { >> std::cout << "Attempting connection" << std::endl; >> >> ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 7780); >> >> m_Socket.async_connect(ep, >> boost::bind(&ConnectCommand::Handle_Connect, >> this, placeholders::error)); >> >> // Stop without waiting for the result >> m_IoService.stop(); >> } >> >> private: >> void Handle_Connect(boost::system::error_code &e) >> { >> std::cout << "Connect returned: " << e << "." << std::endl; >> } >> >> boost::asio::io_service &m_IoService; >> boost::asio::ip::tcp::socket m_Socket; >> }; >> >> class AsioHang { >> public: >> >> void Run() { >> m_ConnectCommand.reset(new ConnectCommand(m_IoService)); >> m_ConnectCommand->Execute(); >> >> m_IoService.run(); >> } >> >> private: >> ConnectCommandPtr m_ConnectCommand; // destroyed after io_service object >> boost::asio::io_service m_IoService; >> }; >> >> int _tmain(int argc, _TCHAR* argv[]) >> { >> { >> AsioHang hang; >> hang.Run(); >> >> std::cout << "After Run()" << std::endl; >> } >> return 0; >> } >> >> >> In this example, there is a flaw in that the ConnectCommand is destroyed >> after the io_service object, but the ConnectCommand has a reference to the >> io_service. >> >> I would have expected this to lead to a crash or similar and this is indeed >> the case if I attach a debugger to the program and step through it. But if I >> just run the program without the debugger attached, the io_service >> destructor just never completes. >> >> I believe that a variation of the error in the code above is what caused the >> problems for me and I assume that this should be written off as more or less >> undefined behavior caused by badly managed object lifetimes. >> >> Thank you all who responded and thank you Sergei for pointing out that there >> is a specific asio mailing list. > > I am still not sure this is the issue in Wt then, as its code is well > used and worked in past Boost version. > > > Also, your example does not compile: > 1>q:\overminddl1's documents\visual studio > 2005\projects\boostasiobugtest\boostasiobugtest\boostasiobugtest.cpp(55) > : error C2061: syntax error : identifier '_TCHAR' > > > Changing that to a normal main function, I get these errors: > 1>r:\sdks\boost\built_head\include\boost-1_44\boost\bind\bind.hpp(313) > : error C2664: 'R boost::_mfi::mf1<R,T,A1>::operator > ()<ConnectCommand>(const U &,A1) const' : cannot convert parameter 2 > from 'const boost::system::error_code' to 'boost::system::error_code > &' > 1> with > 1> [ > 1> R=void, > 1> T=ConnectCommand, > 1> A1=boost::system::error_code &, > 1> U=ConnectCommand * > 1> ] > 1> Conversion loses qualifiers > 1> r:\sdks\boost\built_head\include\boost-1_44\boost\bind\bind_template.hpp(47) > : see reference to function template instantiation 'void > boost::_bi::list2<A1,A2>::operator ()<F,boost::_bi::list1<const > boost::system::error_code &>>(boost::_bi::type<T>,F &,A &,int)' being > compiled > 1> with > 1> [ > 1> A1=boost::_bi::value<ConnectCommand *>, > 1> A2=boost::arg<1>, > 1> F=boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>, > 1> T=void, > 1> A=boost::_bi::list1<const boost::system::error_code &> > 1> ] > 1> r:\sdks\boost\built_head\include\boost-1_44\boost\asio\detail\bind_handler.hpp(40) > : see reference to function template instantiation 'void > boost::_bi::bind_t<R,F,L>::operator ()<Arg1>(const A1 &)' being > compiled > 1> with > 1> [ > 1> R=void, > 1> F=boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>, > 1> L=boost::_bi::list2<boost::_bi::value<ConnectCommand > *>,boost::arg<1>>, > 1> Arg1=boost::system::error_code, > 1> A1=boost::system::error_code > 1> ] > 1> r:\sdks\boost\built_head\include\boost-1_44\boost\asio\detail\bind_handler.hpp(39) > : while compiling class template member function 'void > boost::asio::detail::binder1<Handler,Arg1>::operator ()(void)' > 1> with > 1> [ > 1> Handler=boost::_bi::bind_t<void,boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>,boost::_bi::list2<boost::_bi::value<ConnectCommand > *>,boost::arg<1>>>, > 1> Arg1=boost::system::error_code > 1> ] > 1> r:\sdks\boost\built_head\include\boost-1_44\boost\asio\basic_socket.hpp(650) > : see reference to class template instantiation > 'boost::asio::detail::binder1<Handler,Arg1>' being compiled > 1> with > 1> [ > 1> Handler=boost::_bi::bind_t<void,boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>,boost::_bi::list2<boost::_bi::value<ConnectCommand > *>,boost::arg<1>>>, > 1> Arg1=boost::system::error_code > 1> ] > 1> q:\overminddl1's documents\visual studio > 2005\projects\boostasiobugtest\boostasiobugtest\boostasiobugtest.cpp(24) > : see reference to function template instantiation 'void > boost::asio::basic_socket<Protocol,SocketService>::async_connect<boost::_bi::bind_t<R,F,L>>(const > boost::asio::ip::basic_endpoint<InternetProtocol> &,ConnectHandler)' > being compiled > 1> with > 1> [ > 1> Protocol=boost::asio::ip::tcp, > 1> SocketService=boost::asio::stream_socket_service<boost::asio::ip::tcp>, > 1> R=void, > 1> F=boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>, > 1> L=boost::_bi::list2<boost::_bi::value<ConnectCommand > *>,boost::arg<1>>, > 1> InternetProtocol=boost::asio::ip::tcp, > 1> ConnectHandler=boost::_bi::bind_t<void,boost::_mfi::mf1<void,ConnectCommand,boost::system::error_code > &>,boost::_bi::list2<boost::_bi::value<ConnectCommand > *>,boost::arg<1>>> > 1> ] > > > So I added a const to your Handle_Connect line to get void > Handle_Connect(const boost::system::error_code &e) and it now builds. > This was also on VS2k5. It now compiles, and when I run it, I get an > access violation with this call stack: > BoostASIOBugTest.exe!boost::shared_ptr<void>::~shared_ptr<void>() + > 0x3e bytes C++ >> BoostASIOBugTest.exe!boost::asio::detail::scoped_lock<boost::asio::detail::win_mutex>::scoped_lock<boost::asio::detail::win_mutex>(boost::asio::detail::win_mutex & m={...}) Line 37 C++ > BoostASIOBugTest.exe!boost::asio::detail::win_iocp_socket_service_base::destroy(boost::asio::detail::win_iocp_socket_service_base::base_implementation_type > & impl={...}) Line 79 C++ > BoostASIOBugTest.exe!boost::asio::stream_socket_service<boost::asio::ip::tcp>::destroy(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type > & impl={...}) Line 102 C++ > BoostASIOBugTest.exe!boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >>::~basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >>() Line 86 C++ > BoostASIOBugTest.exe!boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >>::~basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >>() Line 1054 + 0x3a bytes C++ > BoostASIOBugTest.exe!boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >>::~basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >>() + 0x2b bytes C++ > BoostASIOBugTest.exe!ConnectCommand::~ConnectCommand() + 0x2e bytes C++ > BoostASIOBugTest.exe!ConnectCommand::`scalar deleting destructor'() > + 0x2b bytes C++ > BoostASIOBugTest.exe!boost::checked_delete<ConnectCommand>(ConnectCommand > * x=0x003742c0) Line 34 + 0x2b bytes C++ > BoostASIOBugTest.exe!boost::detail::sp_counted_impl_p<ConnectCommand>::dispose() > Line 78 + 0xc bytes C++ > BoostASIOBugTest.exe!boost::detail::sp_counted_base::release() Line > 102 + 0xf bytes C++ > BoostASIOBugTest.exe!boost::detail::shared_count::~shared_count() > Line 221 C++ > BoostASIOBugTest.exe!boost::shared_ptr<ConnectCommand>::~shared_ptr<ConnectCommand>() > + 0x2e bytes C++ > BoostASIOBugTest.exe!AsioHang::~AsioHang() + 0x63 bytes C++ > BoostASIOBugTest.exe!main(int argc=1, char * * argv=0x00374128) Line 63 C++ > > > This is with the latest Boost Trunk as of about an hour ago, and the > issue in Wt is also still happening. As stated, Wt does not throw an > access violation, nor do I think it is even destroying anything, read > my above posts to see what is happening in ASIO in it. For note, my other thread archive url's for the Wt mailing list are here: http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTikCWpJKhChSrqeTzxRU2V-Cr0YrH-2TqQ4_s3F1%40mail.gmail.com&forum_name=witty-interest And for some reason sourceforge did not merge the latest ones into the thread, so here they are in order: http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTilhcgrxAG4-8ErbiML_PxI92ekCiYVtP7mcXHGz%40mail.gmail.com&forum_name=witty-interest http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTin_9kRIpswCIbqhQJq3zStfSGHRrGsHIGw4-sF7%40mail.gmail.com&forum_name=witty-interest http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTikjKeTR-g4JBPt9j8CFBcHmtR22lmo2DOWEgRfR%40mail.gmail.com&forum_name=witty-interest http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTimYC4pS_LdC7YBI9um5RdbOHE6p018i4bRnjBas%40mail.gmail.com&forum_name=witty-interest http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTimVE8r5di4Y2OwriESVgHb1jQo4o4nMeBCiHH28%40mail.gmail.com&forum_name=witty-interest