【问题标题】:boost::asio throws exception when pausedboost::asio 暂停时抛出异常
【发布时间】:2012-10-03 13:40:18
【问题描述】:

我有一个程序使用boost::asio 连接到远程机器,然后反复打印它接收到的任何内容。问题是,每当我暂停它或在它运行时对断点进行任何更改时,都会从read_until() 内部的某个地方抛出异常。为什么会发生这种情况,我应该怎么做?

这是在运行 OS X 10.8.2 和 Xcode 4.4.1 和 Apple clang 4.0 的 Mac 上。暂停程序后引发异常时的堆栈跟踪:

* thread #1: tid = 0x1d07, 0x00007fff86bc9d46 libsystem_kernel.dylib`__kill + 10, stop reason = signal SIGABRT
    frame #0: 0x00007fff86bc9d46 libsystem_kernel.dylib`__kill + 10
    frame #1: 0x00007fff8ec40df0 libsystem_c.dylib`abort + 177
    frame #2: 0x00007fff8c49ca17 libc++abi.dylib`abort_message + 257
    frame #3: 0x00007fff8c49a3c6 libc++abi.dylib`default_terminate() + 28
    frame #4: 0x00007fff8d05e887 libobjc.A.dylib`_objc_terminate() + 111
    frame #5: 0x00007fff8c49a3f5 libc++abi.dylib`safe_handler_caller(void (*)()) + 8
    frame #6: 0x00007fff8c49a450 libc++abi.dylib`std::terminate() + 16
    frame #7: 0x00007fff8c49b5b7 libc++abi.dylib`__cxa_throw + 111
    frame #8: 0x00000001000043df test`void boost::throw_exception<boost::system::system_error>(boost::system::system_error const&) + 111 at throw_exception.hpp:66
    frame #9: 0x0000000100004304 test`boost::asio::detail::do_throw_error(boost::system::error_code const&, char const*) + 68 at throw_error.ipp:38
    frame #10: 0x0000000100004272 test`boost::asio::detail::throw_error(boost::system::error_code const&, char const*) + 50 at throw_error.hpp:42
    frame #11: 0x0000000100002479 test`unsigned long boost::asio::read_until<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, std::allocator<char> >(boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >&, boost::asio::basic_streambuf<std::allocator<char> >&, std::string const&) + 73 at read_until.hpp:98
    frame #12: 0x00000001000012c5 test`main + 581 at main.cpp:21
    frame #13: 0x00007fff8983e7e1 libdyld.dylib`start + 1

【问题讨论】:

  • 看起来像一个未教过的例外?在 throw 处设置断点并找出抛出的类型。
  • 提升 1.51.0-stable。嗯,我怎么知道它是什么异常?

标签: c++ xcode exception boost-asio breakpoints


【解决方案1】:

当您暂停程序时,实际暂停是通过向其发送 POSIX 信号 (SIGSTOP) 来完成的。这样做的影响之一是系统调用(例如 read(),Boost 将在内部使用)返回错误 EINTR。这将触发read_until 的错误处理代码,如您所见,它会引发异常。

如果您想正确处理此问题,您可能需要使用带有boost::system::error_code 参数的重载,检查.value()EINTR(在errno.h 中定义),然后重试读取。

这看起来像

boost::system::error_code error;
boost::asio::streambuf message;
do {
    boost::asio::read(socket, message, boost::asio::transfer_exactly(body_size), error);
} while (error.value() == EINTR);

【讨论】:

    【解决方案2】:

    read_until() 有一个覆盖会在错误时抛出异常,如果你没有捕捉到这个,那么你会看到这个行为。如果您使用不接受boost::system::error_code&amp;boost::asio 覆盖,那么为了安全起见,您应该将这些调用包装在捕获const boost::system::error_code&amp;try 块中。在异常处理程序中,您应该检查异常以了解失败的根本原因是什么。

    try
    {
       boost::asio::read_until(...);
    }
    
    catch(const boost::system::error_code& err)
    {
       // read_until(...) failed, the reason is
       // contained in err
    }
    

    【讨论】:

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