【问题标题】:Reading ftrace pipes with Boost::asio posix stream_descriptor使用 Boost::asio posix stream_descriptor 读取 ftrace 管道
【发布时间】:2016-11-14 19:20:38
【问题描述】:

我正在尝试构建一个在调试 fs 处从 ftrace pipes 读取的应用程序。

似乎在尝试从 trace_pipetrace_pipe_raw 使用 boost::asio API,管道中等待的事件正在 由 async_read 句柄处理并打印到屏幕上,但程序启动后到达的新事件不会触发 async_read 句柄。

运行下面的示例代码,我得到了所有在队列中等待的事件的打印,但我没有得到任何稍后到达的新事件的打印。

如果我尝试使用 mkfifo 从手动创建的管道中读取,但对于 ftrace 管道不起作用,则相同的示例可以完美运行。

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>

namespace asio = boost::asio;
#ifdef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
typedef asio::posix::stream_descriptor stream_descriptor;
#endif

class PipeReader
{
    typedef std::shared_ptr<PipeReader> PipeReaderPtr;
    typedef std::weak_ptr<PipeReader> PipeReaderWeakPtr;
public:
    static PipeReaderWeakPtr Create(asio::io_service& io_service, const std::string& path);

    void HandleRead(PipeReaderPtr me, const boost::system::error_code &error);
private:
    PipeReader(asio::io_service& io_service, const std::string& path);
    stream_descriptor m_pipe;
    char buf[4096];
};

PipeReader::PipeReaderWeakPtr PipeReader::Create(asio::io_service& io_service, const std::string& path)
{
    PipeReaderPtr ptr(new PipeReader(io_service, path));

    ptr->m_pipe.async_read_some(boost::asio::buffer(ptr->buf),
                                boost::bind(&PipeReader::HandleRead,
                                            ptr.get(), 
                                            ptr,
                                            asio::placeholders::error));
    return ptr;
}

PipeReader::PipeReader(asio::io_service& io_service, const std::string& path)
                       : m_pipe(io_service)
{
    int dev = open(path.c_str(), O_RDWR);
    if (dev == -1) {
        std::cout << "failed to open path - " << path << std::endl;
    }
    else
    {
        m_pipe.assign(dev);
    }
}

void PipeReader::HandleRead(PipeReaderPtr me, const boost::system::error_code &error) 
{
    if (!error) {
        std::string str(me->buf);

        std::cout << "got message: " << str << std::endl;
        m_pipe.async_read_some(boost::asio::buffer(me->buf),
                               boost::bind(&PipeReader::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);

    PipeReader::Create(io_service, "/sys/kernel/debug/tracing/trace_pipe");

    io_service.run();   
    return 0;
}

【问题讨论】:

  • 看起来 trace_pipe 文件没有实现异步接口(@98​​7654323@ 方法)。对于debugfssysfs 和其他“虚拟”文件系统下的文件,通常只实现用于访问这些文件的最常用接口。

标签: c++ linux-kernel boost-asio named-pipes ftrace


【解决方案1】:

我发现了问题。这是 ftrace 实现中的一个错误,导致 epoll 挂起。 该错误已在内核 3.16 中修复。

correspondence thread, commit in git hub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2012-06-12
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    相关资源
    最近更新 更多