boost :: asio выдает исключение при остановке

У меня есть программа, которая использует boost::asio подключиться к удаленному компьютеру, а затем многократно распечатывать все, что он получает. Проблема в том, что всякий раз, когда я приостанавливаю его или вносю какие-либо изменения в точки останова во время его работы, возникает исключение изнутри read_until(), Почему это происходит и что мне с этим делать?

Это на Mac под управлением OS X 10.8.2 с Xcode 4.4.1 и Apple clang 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

1

Решение

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
}
2

Другие решения

Когда вы приостанавливаете свою программу, фактическая пауза завершается отправкой ей сигнала 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);
3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector