Boost asio async_write_some 泄漏?

Boost asio async_write_some leaking?

我一直在搞一个使用 boost::asio 进行 UDP 和 SocketCAN 通信的应用程序。 今天,我发现了一些奇怪的事情——内存泄漏!

所以我抓住了我值得信赖的工具包,其中包括

echo 0 $(awk '/Private/ {print "+", }' /proc/`pidof main`/smaps) | bc

和 Allinea DDT 并着手诊断此问题。

我最终得到的是以下片段,它利用 boost::asio::posix::basic_stream_descriptor 作为基础 :

void Can::write(struct can_frame frame) {
  stream_.async_write_some(boost::asio::buffer(&frame, sizeof(frame)),
                           boost::bind(&Can::datSend, this)
  );
}

在这里,datSend 只是一个空函数,用于 ping 看门狗。 我也试过

void Can::write(struct can_frame frame) {
  stream_.write_some(boost::asio::buffer(&frame, sizeof(frame)));
}

但出于某种原因,这给出了一个异常(无效数据)。

这段代码的后端看起来像这样:

boost::asio::io_service ioService_;
boost::asio::posix::basic_stream_descriptor<> stream_;

Constructor() : stream_(ioService_) {
  socketDescriptor_ = socket(PF_CAN, SOCK_RAW, CAN_RAW);

  struct timeval timeout {
      .tv_sec = 5,
      .tv_usec = 0
  };

  if (setsockopt(socketDescriptor_, SOL_SOCKET, SO_RCVTIMEO,
                 reinterpret_cast<char *>(&timeout),
                 sizeof(timeout)) < 0) {
    throw std::string("Error setting CAN socket timeout");
  }

  strcpy(interfaceRequest_.ifr_name, interfaceName.c_str());
  ioctl(socketDescriptor_, SIOCGIFINDEX, &interfaceRequest_);
  socketAddress_.can_family = AF_CAN;
  socketAddress_.can_ifindex = interfaceRequest_.ifr_ifindex;
  stream_.assign(socketDescriptor_);

  if (bind(socketDescriptor_, (struct sockaddr *)&socketAddress_,
           sizeof(socketAddress_)) < 0) {
    throw std::string("Error in socket bind");
  }

}

之后我只是 运行 ioservice 就是这样:

void Can::iosThreadWorker() { ioService_.run(); }

我浏览了很多 Whosebug 主题以及 boost 文档,但似乎无法找到此函数会泄漏内存的原因。

增强版 - 1.60 G++ - 6.30 OS : Ubuntu 17.04

所以我深入挖掘并发现了关于 boost.io_service 的花絮:

io_service.run() 如果没有工作可完成 - 所以通过 运行 它然后发送更多要完成的异步工作,工作没有完成。

这源于一个问题,即有人翻转了 ioservice.run() 和异步读取回调分配以使代码看起来更好 - 现在在 运行 和 ioservice 之前没有工作堆积只需完成它的工作 return.