내 asio 기반 응용 프로그램에서 오류 처리에 문제가 있습니다. async_read/async_write 함수를 사용하여 asio 단일 스레드/단일 io_service를 사용하고 완성 처리기에서 나에게 전달 된 오류 코드가 null이 아닌 경우 오류가 발생하기 때문에 해당 .message() 메서드를 호출하면 segfault가 발생합니다. -category 포인터가 null을 가리 킵니다. 그러나 실제 값은 항상 정확합니다.부스트 asio 오류 범주가 null입니다.
이상하게도 테스트 응용 프로그램에서이를 재현 할 수 없습니다. 이것은 내가 여기에 예상대로 작동) (메시지를 호출하고 있지만, 오류의 경우에있어 어떤 본질적 :
void do_write(std::shared_ptr<std::vector<unsigned char>> , std::shared_ptr<boost::asio::ip::tcp::socket>);
void do_read(std::shared_ptr<std::vector<unsigned char>> buf, std::shared_ptr<boost::asio::ip::tcp::socket> sock)
{
boost::asio::async_read(*sock, boost::asio::buffer(*buf), boost::asio::transfer_exactly(100000),
[sock, buf](const boost::system::error_code& ec, std::size_t bytes)
{
std::cout << "read\n";
if (ec) {
std::cout << ec.message() << std::flush;
} else {
do_write(buf, sock);
}
});
}
void do_write(std::shared_ptr<std::vector<unsigned char>> buf, std::shared_ptr<boost::asio::ip::tcp::socket> sock)
{
boost::asio::async_write(*sock, boost::asio::buffer(*buf), [sock, buf](const boost::system::error_code& ec, std::size_t bytes)
{
std::cout << "write\n";
if (ec) {
std::cout << ec.message() << std::flush;
} else {
do_read(buf, sock);
}
});
}
int main()
{
auto buf = std::make_shared<std::vector<unsigned char>>(100000);
unsigned short port = 1113;
boost::asio::io_service ios;
boost::asio::ip::tcp::acceptor acptr {ios, boost::asio::ip::tcp::endpoint{boost::asio::ip::tcp::v4(), port}};
auto socket = std::make_shared<boost::asio::ip::tcp::socket>(acptr.get_io_service());
acptr.async_accept(*socket, [socket, buf](const boost::system::error_code& ec)
{
do_read(buf, socket);
});
ios.run();
}
내가 생각하지 않는 내 응용 프로그램의 수명에 문제가, AddressSanitizer은 찾을 수 없습니다 잠재적 인 오류가 있으며 아무런 문제없이 수백 메가 바이트의 데이터를 이동할 수 있습니다. 또한 message()에 대한 주석 처리 만 제거하면 서버는 계속 실행되어 새로운 연결을 올바르게 처리합니다. 어쨌든 충돌이 발생할 때 콜 스택이 있습니다 :
https://gist.github.com/mariusherzog/82f24caf9eea4d94946706aa8c025ef1 범주는 프레임 11에서 null을 가리 킵니다.
나는 그 소리 3.9.1과 GCC와 부스트 1.62로 리눅스를 사용 5.4.0
팁 주셔서 감사합니다. 오류 범주 (get_misc_category)는 Meyer의 싱글 톤을 통해 액세스됩니다. 중단 점을 입력하면 실제 인스턴스는 처음부터 메모리에서 모두 null입니다. 이것이 asio의 버그일까요? –
또한 내 응용 프로그램에서 여러 번 호출됩니다. 다른 번역 단위로 인한 것 같습니다 ... –
더 중요한 것은'get_misc_category()'***가 **입니다. * Meyer의 싱글 톤. 그게 잘못되면 내가 잘못 가고 있다고 상상할 수있는 유일한 것은 런타임 링크입니다. – sehe