【问题标题】:Unable to catch exception from boost::asio::io_service::run无法从 boost::asio::io_service::run 捕获异常
【发布时间】:2016-05-26 12:27:38
【问题描述】:

我在 boost::asio 上有一个 TCP 服务器,它侦听一个连接,并在得到它之后开始使用 boost::asio::write 在循环中发送数据块。

bool TcpServer::StartTcpServer(std::shared_ptr<boost::asio::io_service>  io_service)
{
    m_ioservice = io_service;
    m_acceptor.reset(new boost::asio::ip::tcp::acceptor(*m_ioservice, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port)));
    m_socket = std::unique_ptr<boost::asio::ip::tcp::socket>(new boost::asio::ip::tcp::socket(*m_ioservice));

    m_socket->close();
    m_acceptor->async_accept(*m_socket, m_peer_endpoint,   boost::bind(&TcpServer::AcceptHandler, this, boost::asio::placeholders::error)); 

    m_io_thread.reset(new std::thread([this]{
    try
    {
        this->m_ioservice->run();
    }
    catch(const boost::system::system_error & err){print logs}
    catch(...){print another logs}
    }));
}

void TcpServer::AcceptHandler(const boost::system::error_code &ec)
{
    while(true)
    {
         try
         {
             boost::asio::write( *m_socket, boost::asio::buffer(data->c_str(), data->size()), boost::asio::transfer_all());  
         } 
         catch(const boost::system::system_error & err){print logs}
         catch(...){print another logs}
    }
}

如果我手动停止接收器,则会引发有关损坏管道的异常并正确处理。但有时会发生管道损坏(我想是连接不良的原因),异常奇迹般地通过所有捕获并终止应用程序:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'

检查核心我发现它发生在 boost::asio::write 中,起源于 io_service::run()。我做错了什么?

我也尝试使用 async_write 重写 TCP 服务器,但它仍然会发生,但不经常发生。

EDIT1:如果我手动停止接收器导致管道损坏,我会得到完全相同的异常和完全相同的调用堆栈,但我可以处理这个。

EDIT2:据我所知,不可捕获的异常可能是通过套接字发送的数据过快的结果。不过不确定。

【问题讨论】:

  • 你确定是例外吗?如果你catch(...),你会得到什么?
  • 我有一个打印输出说“在抛出 'boost::exception_detail::clone_impl<:exception_detail::error_info_injector>> 的实例后调用终止”什么( ):写:断管”。 catch(...) 没有捕获任何东西。
  • 它是从某个具有异常规范的函数中抛出的吗?看看this answer
  • 你无法捕获另一个线程中抛出的异常;这可能是你的问题。
  • 如果可能,能否提供minimal reproducible example

标签: c++ boost boost-asio


【解决方案1】:

terminate 中的错误消息实际上确实解释了正在发生的事情。 boost::exception_detail::clone_impl 失败。在不深入研究代码的情况下,我假设它用于实现异常类的复制构造函数。如果这个拷贝构造函数在异常处理过程中抛出异常,它将绕过异常块,异常向上传播。 (即使您通过引用捕获,编译器仍可能进行复制。)

现在我不知道为什么复制构造函数失败了;没有足够的问题知道。但是与异步 I/O 相关的this question 有一个非常相似的问题,关键似乎是shared_ptr 在异常处理之前被销毁了。看起来很相似。

【讨论】:

    猜你喜欢
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多