当内部线程读入缓冲区时,在调整大小时提升asio streambuf释放内存

时间:2016-07-05 20:32:14

标签: c++ multithreading boost-asio

我有一个提升asio应用程序,大部分时间都运行良好,但偶尔valgrind显示一个"无法替代的字节"错误。我怀疑发生的事情如下:

  • async_read_transfer_at_least()调用正在调整boost :: asio :: streambuf的大小,同时这样做会释放内存,但它还没有调整大小。
  • 此时有一个上下文切换到一些内部提升线程,可能是在执行io_service.run()时产生的。此线程从套接字读取数据并尝试为排队的async_read请求提供服务,并尝试将数据存储在缓冲区中。
  • 但缓冲区已被释放"通过正在处理的async_read()因此导致不可寻址的字节。

经过大量研究和阅读关于asio和streambufs的大多数帖子后,我还没有找到一个干净的方法来解决这个问题。 valgrind输出发布:

==2759== Syscall param recvmsg(msg.msg_iov[0]) points to unaddressable byte(s)
==2759==    at 0x3FB02E9920: __recvmsg_nocancel (in /lib64/libc-2.12.so)
==2759==    by 0x413897: boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) (socket_ops.ipp:784)
==2759==    by 0x41391E: boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) (socket_ops.ipp:873)
==2759==    by 0x451063: boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) (reactive_socket_recv_op.hpp:58)
==2759==    by 0x410520: boost::asio::detail::reactor_op::perform() (reactor_op.hpp:40)
==2759==    by 0x411FD2: boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) (epoll_reactor.ipp:623)
==2759==    by 0x4120D2: boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::                    system::error_code const&, unsigned long) (epoll_reactor.ipp:649)
==2759==    by 0x410387: boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (task_io_service                    _operation.hpp:38)
==2759==    by 0x412BD3: boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread                    _info&, boost::system::error_code const&) (task_io_service.ipp:372)
==2759==    by 0x4126FA: boost::asio::detail::task_io_service::run(boost::system::error_code&) (task_io_service.ipp:149)
==2759==    by 0x412EC8: boost::asio::io_service::run() (io_service.ipp:59)
==2759==    by 0x42F57F: abc::io::Reactor<boost::asio::io_service, abc::io::BoostNetworkSvc>::start() (abc_io_reactor.hpp:82)
==2759==  Address 0x4c34620 is 0 bytes inside a block of size 512 free'd
==2759==    at 0x4A06C79: free (vg_replace_malloc.c:530)
==2759==    by 0x44CEB5: __gnu_cxx::new_allocator<char>::deallocate(char*, unsigned long) (new_allocator.h:110)
==2759==    by 0x449943: std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long) (alloc_traits.h:383)
==2759==    by 0x4444C9: std::_Vector_base<char, std::allocator<char> >::_M_deallocate(char*, unsigned long) (stl_vector.h:178)
==2759==    by 0x4443C7: std::vector<char, std::allocator<char> >::_M_default_append(unsigned long) (vector.tcc:578)
==2759==    by 0x43DBC4: std::vector<char, std::allocator<char> >::resize(unsigned long) (stl_vector.h:676)
==2759==    by 0x441212: boost::asio::basic_streambuf<std::allocator<char> >::reserve(unsigned long) (basic_streambuf.hpp:326)
==2759==    by 0x43A4C1: boost::asio::basic_streambuf<std::allocator<char> >::prepare(unsigned long) (basic_streambuf.hpp:207)
==2759==    by 0x433349: boost::asio::detail::read_streambuf_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::al                    locator<char>, boost::asio::detail::transfer_at_least_t, boost::_bi::bind_t<void, boost::_mfi::mf1<void, abc::io::IProtocol, boost::system::error_code const&>, boost::_bi::list2<boost::_                    bi::value<abc::io::IProtocol*>, boost::arg<1> (*)()> > >::operator()(boost::system::error_code const&, unsigned long, int) (read.hpp:623)
==2759==    by 0x42C360: boost::asio::async_result<boost::asio::handler_type<boost::_bi::bind_t<void, boost::_mfi::mf1<void, abc::io::IProtocol, boost::system::error_code const&>, boost:                    :_bi::list2<boost::_bi::value<abc::io::IProtocol*>, boost::arg<1> (*)()> >, void (boost::system::error_code, unsigned long)>::type>::type boost::asio::async_read<boost::asio::basic_strea                    m_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, boost::asio::detail::transfer_at_least_t, boost::_bi::bind_t<void, boost:                    :_mfi::mf1<void, abc::io::IProtocol, boost::system::error_code const&>, boost::_bi::list2<boost::_bi::value<abc::io::IProtocol*>, boost::arg<1> (*)()> > >(boost::asio::basic_stream_socke                    t<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&, boost::asio::basic_streambuf<std::allocator<char> >&, boost::asio::detail::transfer_at_least_t, boost                    ::_bi::bind_t<void, boost::_mfi::mf1<void, abc::io::IProtocol, boost::system::error_code const&>, boost::_bi::list2<boost::_bi::value<abc::io::IProtocol*>, boost::arg<1> (*)()> >&&) (rea                    d.hpp:715)

0 个答案:

没有答案