我一直在使用boost :: asio进行UDP和SocketCAN通信的应用程序。 今天,我注意到一些奇怪的东西 - 它正在泄漏内存!升压asio async_write_some泄漏?
所以我抓住我信赖的工具包,包括
echo 0 $(awk '/Private/ {print "+", $2}' /proc/`pidof main`/smaps) | bc
和Allinea DDT,并开始工作诊断这个问题。
我最终什么样的主意是下面的代码片段,它利用提高:: 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只是一个空函数坪看门狗。 我也试着
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
你的第一个怀疑应该永远是你自己的代码,而不是一个众所周知的,大量使用的库。你认为datSend()无关紧要,但这可能确实是泄漏发生的地方。请提供该功能的代码。 –
这是名副其实的空函数: 无效能:: datSend(){} 我用来登录此之际,但目前,它只是充当一个占位符。 –
您可以在主文件中设置一个调试钩子,并且一旦进入可疑功能,就可以在任何内存分配上设置一个断点。看看是否有任何人站出来 –