无法从boost::asio::io_service::run捕获异常
Unable to catch exception from boost::asio::io_service::run
我在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> >'
通过检查内核,我发现它发生在源自io_service::run()的boost::asio::write中。我做错了什么?
此外,我还尝试使用async_write重写TCP服务器,但这种情况仍然存在,但并不经常发生。
编辑1:如果我手动停止接收器导致管道破裂,我会得到完全相同的异常和完全相同的调用堆栈,但这次我可以处理。
编辑2:据我目前所知,不可捕获的异常可能是由于通过套接字发送的数据过多而过快造成的。但不确定。
terminate
中的错误消息实际上解释了发生了什么。boost::exception_detail::clone_impl
出现故障。在不深入研究代码的情况下,我假设它用于实现异常类的复制构造函数。如果此复制构造函数在异常处理过程中抛出异常,它将绕过异常块,并且异常将向上传播。(即使通过引用捕获,编译器仍可能进行复制。)
现在我不知道复制构造函数为什么失败;这个问题没有足够的答案。但这个与异步I/O有关的问题也有一个非常类似的问题,关键似乎是shared_ptr
在异常处理之前被销毁了。看起来很相似。
相关文章:
- join() 失败,如果在线程内部调用 io_context.run()
- 为什么我会收到"Run-Time Check Failure #2 - Stack around the variable 'pr' was corrupted"错误?
- C++ POCO - 如何在不使用 run() 方法的情况下启动线程池上的线程?
- TensorFlow c++ API 在 session->run() 上崩溃
- 如何在QT Creator中手动运行CMake和Run
- 使用 QtConcurrent::run() 修改成员变量?
- Windows Service 可以枚举桌面顶级窗口吗?
- 如何在QtConcurrent::run中启动QTimer或为什么QVector<QTimer*>不起作用
- std::condition_variable 在 QThread::run() 中的用法
- "Make run"在终端中打印"bin/prog"
- bad_weak_ptr使用从 boost::asio::io_context::service 继承的类
- 调用 dll 函数时"Run-Time Check Failure #0 - The value of ESP"
- Bash run 命令在子壳的后台运行
- C++ API-MS-WIN-SERVICE-PRIVATE-L1-1-1.DLL依赖项问题
- Bazel-run 不会加载在 Bazel Build 时加载的所有 TensorFlow 包
- 如何将字符串数组传递到 QtConcurrent::run 中?
- 提升::亚洲.确保仅在调用async_receive(..)后调用io_service.run()?
- "Feature X requires run-time support"的含义是什么?
- 如何传递以 "size determined at run time" 作为引用的动态分配数组?
- "Loop will run at most once (loop increment never executed)" C++