[BUG] ftrace: Boost asio does not play well with trace_pipe
From: Gal Kaplan
Date: Tue Jul 12 2016 - 09:05:46 EST
Hi,
I'm trying to build an application that reads from the ftrace trace
pipes at the debug fs.
I came across an interesting issue,
it seems that when trying to read asynchronously from trace_pipe or
trace_pipe_raw using boost::asio API, the events waiting in pipe being
processed but new events are not reported to boost handlers and the
async read is never called for new events.
I verified the piece of code below works well with manually created
pipes (using mkfifo) but not working with trace_pipe or
trace_pipe_raw.
I would appreciate your opinions on this issue.
Please personally CC me in any answer/comment you post in response to
this issue.
Thanks,
Gal Kaplan
#include <boost/asio.hpp>
#include <string>
#include <iostream>
#include <boost/bind.hpp>
namespace asio = boost::asio;
#ifdef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
typedef asio::posix::stream_descriptor stream_descriptor;
#endif
class FileReader
{
typedef std::shared_ptr<FileReader> FileReaderPtr;
typedef std::weak_ptr<FileReader> FileReaderWeakPtr;
public:
static FileReaderWeakPtr Create(asio::io_service& io_service,
const std::string& path);
void HandleRead(FileReaderPtr me, const boost::system::error_code &error);
private:
FileReader(asio::io_service& io_service, const std::string& path);
stream_descriptor m_InputStream;
char buf[4096];
};
FileReader::FileReaderWeakPtr FileReader::Create(asio::io_service& io_service,
const std::string& path)
{
FileReaderPtr ptr(new FileReader(io_service, path));
ptr->m_InputStream.async_read_some(boost::asio::buffer(ptr->buf),
boost::bind(&FileReader::HandleRead, ptr.get(), ptr,
asio::placeholders::error));
return ptr;
}
FileReader::FileReader(asio::io_service& io_service, const
std::string& path) : m_InputStream(io_service)
{
int dev = open(path.c_str(), O_RDWR);
if (dev == -1) {
std::cout << "failed to open path - " << path << std::endl;
}
else
{
m_InputStream.assign(dev);
}
}
void FileReader::HandleRead(FileReaderPtr me, const
boost::system::error_code &error)
{
if (!error)
{
std::string str(me->buf);
std::cout << "got message: " << str << std::endl;
m_InputStream.async_read_some(boost::asio::buffer(me->buf),
boost::bind(&FileReader::HandleRead, this, me,
asio::placeholders::error));
}
else
{
std::cout << "got error - " << error.message() << std::endl;
}
}
int main()
{
boost::asio::io_service io_service;
boost::asio::io_service::work dummy(io_service);
FileReader::Create(io_service, "/sys/kernel/debug/tracing/trace_pipe");
io_service.run();
return 0;
}