[asio] io_service::run() asserting: "vector iterator not dereferencable"

Inside of win_iocp_handle_service.write_operation.do_completion_impl(), there is this block of code (Note I'm using Boost 1.40 Beta): #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. typename ConstBufferSequence::const_iterator iter = handler_op->buffers_.begin(); typename ConstBufferSequence::const_iterator end = handler_op->buffers_.end(); while (iter != end) { boost::asio::const_buffer buffer(*iter); boost::asio::buffer_cast<const char*>(buffer); ++iter; } #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) The call to buffers_.begin() is causing the assert. Looks like a container is getting invalidated/corrupted somehow. I have no idea why this is happening. I'm calling io_service::run() from its own worker thread in a continuous loop like so: for(;;) { boost::this_thread::sleep( boost::posix_time::milliseconds( 20 ) ); m_service.run(); } The class that is wrapping the io_service and serial_port objects invokes a post at construction (from the main thread), to start off a transparent yet continuous chain of reads over the serial port: m_service.post( boost::bind( &SerialClient::DoRead, this ) ); After that, externally I call a function that posts a write in a similar way. This write occurs after the above post for the read: m_service.post( boost::bind( &SerialClient::DoWrite, this, data ) ); When I step through the sequence of events, I see the following happen: - io_service and serial_port are constructed and initialized - io_service thread is started (But run() has not been called yet) - The DoRead() is posted to the io_service - The DoWrite() is posted to the io_service - io_service.run() is called from the worker thread for the first time - DoRead() is called from io_service::run(), which in turn calls serial_port::async_read_some() - DoWrite() is called from io_service::run(), which in turn calls boost::asio::async_write() on the serial_port - ReadCompleted() is invoked as the callback from the previous serial_port::async_read_some() call. It does NOT call async_read_some again (for testing, I disabled the looped reading). - After ReadCompleted() scope exits, it throws the assert Not sure what I'm doing wrong. Keep in mind that this whole time the COM port is not connected to anything, but I'm not sure if this will have anything to do with it. I've attached the code just in case you don't mind looking over it. --------- Robert Dailey

I figured out what my problem was. This was a container going out of scope and being destroyed. The iterators that still existed in ASIO were pointing to an invalid container. --------- Robert Dailey On Wed, Aug 26, 2009 at 1:09 PM, Robert Dailey<rcdailey@gmail.com> wrote:
Inside of win_iocp_handle_service.write_operation.do_completion_impl(), there is this block of code (Note I'm using Boost 1.40 Beta):
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) // Check whether buffers are still valid. typename ConstBufferSequence::const_iterator iter = handler_op->buffers_.begin(); typename ConstBufferSequence::const_iterator end = handler_op->buffers_.end(); while (iter != end) { boost::asio::const_buffer buffer(*iter); boost::asio::buffer_cast<const char*>(buffer); ++iter; } #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
The call to buffers_.begin() is causing the assert. Looks like a container is getting invalidated/corrupted somehow. I have no idea why this is happening. I'm calling io_service::run() from its own worker thread in a continuous loop like so:
for(;;) { boost::this_thread::sleep( boost::posix_time::milliseconds( 20 ) ); m_service.run(); }
The class that is wrapping the io_service and serial_port objects invokes a post at construction (from the main thread), to start off a transparent yet continuous chain of reads over the serial port:
m_service.post( boost::bind( &SerialClient::DoRead, this ) );
After that, externally I call a function that posts a write in a similar way. This write occurs after the above post for the read:
m_service.post( boost::bind( &SerialClient::DoWrite, this, data ) );
When I step through the sequence of events, I see the following happen:
- io_service and serial_port are constructed and initialized - io_service thread is started (But run() has not been called yet) - The DoRead() is posted to the io_service - The DoWrite() is posted to the io_service - io_service.run() is called from the worker thread for the first time - DoRead() is called from io_service::run(), which in turn calls serial_port::async_read_some() - DoWrite() is called from io_service::run(), which in turn calls boost::asio::async_write() on the serial_port - ReadCompleted() is invoked as the callback from the previous serial_port::async_read_some() call. It does NOT call async_read_some again (for testing, I disabled the looped reading). - After ReadCompleted() scope exits, it throws the assert
Not sure what I'm doing wrong. Keep in mind that this whole time the COM port is not connected to anything, but I'm not sure if this will have anything to do with it. I've attached the code just in case you don't mind looking over it.
--------- Robert Dailey
participants (1)
-
Robert Dailey