2012-10-03 86 views
1

我有一個程序使用boost::asio連接到遠程機器,然後重複打印出它收到的任何內容。問題是,無論我暫停它還是在運行時對斷點進行任何更改,都會在read_until()之內的某處引發異常。爲什麼會發生這種情況,我該怎麼辦?boost :: asio在暫停時拋出異常

這是在Mac上運行的OS X 10.8.2與Xcode 4.4.1和蘋果鐺4.0。從當一個異常被暫停程序後拋出堆棧跟蹤:

* 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 
+0

看起來像一個受過教育的例外?在throw處設置一個斷點並找出拋出的類型。 –

+0

什麼版本的提升? –

+0

提升1.51.0穩定。嗯,我怎麼弄清楚它是什麼樣的例外? –

回答

2

read_until()有一個覆蓋,將扔在錯誤的例外,如果你不抓住這點,你就會看到此行爲。如果您使用的boost::asio覆蓋不包含boost::system::error_code&,則爲了安全起見,您應該將這些調用包裝在try區塊中,該區塊捕獲const boost::system::error_code&。在異常處理程序中,您應該檢查異常以查看失敗的根本原因。

try 
{ 
    boost::asio::read_until(...); 
} 

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

在您暫停計劃,實際的暫停是通過發送一個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);