提升asio async_write_some泄漏?

时间:2017-09-26 11:40:02

标签: c++ boost memory-leaks boost-asio socketcan

我一直在搞乱使用boost :: asio进行UDP和SocketCAN通信的应用程序。 今天,我注意到一些奇怪的东西 - 它正在泄漏记忆!

所以我抓住了由

组成的可靠工具包
echo 0 $(awk '/Private/ {print "+", $2}' /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(); }

我已经浏览了相当多的stackoverflow主题以及提升文档,但似乎无法找到此函数泄漏内存的原因。

Boost版本 - 1.60 G ++ - 6.30 操作系统:Ubuntu 17.04

1 个答案:

答案 0 :(得分:1)

所以我挖得更深一点,发现这个关于boost.io_service:

的小窍门

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

这源于一个问题,有人翻了ioservice.run()和异步读取回调赋值使代码看起来更好 - 现在没有工作堆积在运行之前,ioservice可以完成它的工作并返回。