ASAN показывает кучу использования после освобождения, в то время как boost :: asio вызывает чистый recv на сокете - PullRequest
1 голос
/ 07 марта 2019

У меня около 100 открытых TCP-сокетов, которые контролируют некоторые удаленные устройства.Это чисто мастер-рабское общение.Если сервер является главным (который подключается к устройствам), а устройства являются подчиненными.

Мастер периодически отправляет запросы всем устройствам и некоторое время ожидает получения ответов.Только после того, как операция отправки считается успешной (вызывается handle_send обработчика), сокет будет запускать async_read_some до тех пор, пока сообщение не будет завершено.Когда сервер получает хорошее сообщение, он прекращает запуск async_read_some, так как он больше не должен получать никаких сообщений.

Случайно, случается, что ASAN жалуется на нераспределенный буфер в фазе recv (когда реальный системный вызов 'recvmsg'называется [см. boost 1.66 /usr/include/boost/asio/detail/impl/socket_ops.ipp:784])

Мы находимся на машине с Linux, и та же проблема возникает, когда я использую boost 1.53

Здесь идет трассировка стека:

==7779==ERROR: AddressSanitizer: heap-use-after-free on address 0x611001478a40 at pc 0x503308 bp 0x7ffdea424a70 sp 0x7ffdea424a40
WRITE of size 53 at 0x611001478a40 thread T0
\#0 0x503307 in __interceptor_recvmsg (/usr/tsp/bin/tspinger+0x503307)
\#1 0x8a62c7 in boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:784
\#2 0x8a5457 in boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:877
\#3 0x8a4ac3 in boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:55
\#4 0x681c4e in boost::asio::detail::reactor_op::perform() /usr/include/boost/asio/detail/reactor_op.hpp:44
\#5 0x6f9a98 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:743
\#6 0x6f8a30 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:774
\#7 0x603207 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
\#8 0x5fe649 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:401
\#9 0x5fc7d1 in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:154
\#10 0x5e5e85 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:62
0x611001478a40 is located 0 bytes inside of 209-byte region [0x611001478a40,0x611001478b11)
freed by thread T0 here:
==7779==AddressSanitizer CHECK failed: /builddir/build/BUILD/llvm-3.4.2.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc:184 "((id & (1u << 31))) == ((0))" (0x80000000, 0x0)
\#0 0x52fe0f in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/tsp/bin/tspinger+0x52fe0f)
\#1 0x535671 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/tsp/bin/tspinger+0x535671)
\#2 0x53bb8d in __sanitizer::StackDepotGet(unsigned int, unsigned long*) (/usr/tsp/bin/tspinger+0x53bb8d)
\#3 0x4f0c54 in __asan::AsanChunkView::GetFreeStack(__sanitizer::StackTrace*) (/usr/tsp/bin/tspinger+0x4f0c54)
\#4 0x52d096 in __asan::DescribeHeapAddress(unsigned long, unsigned long) (/usr/tsp/bin/tspinger+0x52d096)
\#5 0x52e211 in __asan_report_error (/usr/tsp/bin/tspinger+0x52e211)
\#6 0x503323 in __interceptor_recvmsg (/usr/tsp/bin/tspinger+0x503323)
\#7 0x8a62c7 in boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:784
\#8 0x8a5457 in boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:877
\#9 0x8a4ac3 in boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:55
\#10 0x681c4e in boost::asio::detail::reactor_op::perform() /usr/include/boost/asio/detail/reactor_op.hpp:44
\#11 0x6f9a98 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:743
\#12 0x6f8a30 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:774
\#13 0x603207 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
\#14 0x5fe649 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:401
\#15 0x5fc7d1 in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:154
\#16 0x5e5e85 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:62

Теперь буфер RX, объявленный в async_read some, называется

m_invector = vector<byte>(RX_BUFFER_SIZE);
socket_.async_read_some(boost::asio::buffer(m_invector),
                   std::bind(&RemoteObject::handle_read, shared_from_this(),
                      std::placeholders::_1, std::placeholders::_2));

Таким образом, буфер всегда чист при запуске async_read_some,В завершение я добавляю подпрограмму boost recv для систем, отличных от Windows

signed_size_type recv(socket_type s, buf* bufs, size_t count,
    int flags, boost::system::error_code& ec)
{
  clear_last_error();
  msghdr msg = msghdr();
  msg.msg_iov = bufs;
  msg.msg_iovlen = static_cast<int>(count);
  signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); //LINE 784
  if (result >= 0)
    ec = boost::system::error_code();
  return result;
}

Не могу понять: ASAN показывает ту же самую точку использования памяти и свободную, то есть boost / asio / detail / impl / socket_ops.ipp: 784, это системный вызов recvmsg.

У вас есть какие-нибудь подсказки?

Спасибо.

...