Boost Users :
Subject: Re: [Boost-users] [Asio] Crash on service delete
From: Indrek Sünter (indreksnt_at_[hidden])
Date: 2011-07-01 11:03:07
Removed some of the clumsy code.
I had a function that resolved an address and initiated async_connect; this
function was called from the socket thread.
When I called it from the main thread instead, the crash disappeared.
It seems that async_connect should not be called from the same service or
thread that the socket is working on.
I wonder if this is correct or I have made a mistake somewhere that causes
2011/6/24 Indrek Sünter <indreksnt_at_[hidden]>
> Thanks for the response.
> True, the source of the problem might be there. Commented socket creation
> out and it no longer crashed.
> With only async_connect left in (only call, for which the socket is used),
> it still crashes.
> Here is how I tried to circumvent this problem (and it probably still
> doesn't work):
> On destruction, I lock the class mutex and mark the class as broken (a
> boolean flag).
> All dispatched handlers start with a loop that checks if the class is
> broken and tries to lock the mutex. When the class is broken, the
> aforementioned socket shutdown code is called and the handler returns.
> With the help of another mutex, class destructor waits for the socket
> shutdown code to finish (which is called from the same service, on which the
> socket handlers are run - to avoid racing conditions).
> In every class function, the class state is checked for broken.
> It's really clumsy and although it's supposed to be bulletproof (in
> theory), it still doesn't work. There must be a better way to do this.
> Though, it seems strange that socket deinitialization went without
> problems, service was stopped, thread was joined and now service destruction
> There should no longer be nothing running on it, right?
> Any suggestions?
> On Fri, Jun 24, 2011 at 8:58 PM, Marat Abrarov <abrarov_at_[hidden]> wrote:
>> Hi, Indrek.
>> > // m_socket was associated with m_service
>> > m_socket->cancel();
>> > m_socket->shutdown( boost::asio::ip::tcp::socket::shutdown_both, ec );
>> > m_socket->close( ec );
>> > delete m_socket;
>> > m_socket = NULL;
>> > // Delete work on the service
>> > delete m_work;
>> > m_work = NULL;
>> > // Stop the service
>> > m_service->stop();
>> > // Join the thread this service was running on
>> > m_thread->interrupt();
>> > m_thread->join();
>> > delete m_thread;
>> > m_thread = NULL;
>> > // Crashes here
>> > delete m_service;
>> > m_service = NULL;
>> > Here's what VC10 reported:
>> > Access violation
>> > camc.exe!boost::asio::detail::socket_ops::send(unsigned int s, const
>> > * bufs, unsigned int count, int flags, boost::system::error_code & ec)
>> > 876 + 0x24 bytes C++
>> > camc.exe!boost::asio::detail::socket_select_interrupter::interrupt()
>> > 127 + 0x18 bytes C++
>> > camc.exe!boost::asio::detail::select_reactor::shutdown_service() Line 73
>> > camc.exe!boost::asio::detail::service_registry::~service_registry() Line
>> > + 0xf bytes C++
>> > camc.exe!boost::asio::detail::service_registry::`scalar deleting
>> > destructor'() + 0x16 bytes C++
>> > camc.exe!boost::asio::io_service::~io_service() Line 51 + 0x1f bytes C++
>> > camc.exe!boost::asio::io_service::`scalar deleting destructor'() + 0x16
>> > bytes C++
>> May be the source of your problem is located in yours async write
>> completion handler (it is often so - see asio-users
>> mailing list). It seems that your completion handler tries to use
>> destroyed m_socket.
>> Marat Abrarov.
>> Boost-users mailing list
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