Boost logo

Boost Users :

Subject: [Boost-users] [asio] io_service::run() asserting: "vector iterator not dereferencable"
From: Robert Dailey (rcdailey_at_[hidden])
Date: 2009-08-26 14:09:32


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





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