[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;
}