Boost logo

Boost Users :

Subject: Re: [Boost-users] [Asio] io_service destructor never completes
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2010-07-19 17:16:06


On Mon, Jul 19, 2010 at 2:55 PM, OvermindDL1 <overminddl1_at_[hidden]> wrote:
> On Tue, Jul 6, 2010 at 8:00 AM, Ragnar Cederlund
> <ragnar.cederlund_at_[hidden]> 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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net