I am experiencing an issue with boost 1.74 on linux. I am trying to have a server that asynchronously reads data from a tcp socket, and then closes when the client disconnect. My code looks like: class SimpleTCPServerTest::SocketHandler { public: explicit SocketHandler(boost::asio::ip::tcp::socket inputSocket ) : socket(std::move(inputSocket)) { socket.set_option(boost::asio::socket_base::keep_alive(true)); } boost::asio::ip::tcp::socket socket; }; SimpleTCPServerTest::SimpleTCPServerTest(std::string address, int port) : m_address(std::move(address)), m_port(port), m_ioc(boost::asio::io_context(1)), m_acceptor(boost::asio::ip::tcp::acceptor(m_ioc)), readTimer(m_ioc){ std::vector<char> buffer_data(1024); this->m_buffer = boost::asio::buffer(buffer_data); } bool SimpleTCPServerTest::open() { //auto const address = boost::asio::ip::make_address(ip); boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), static_cast<unsigned short>(m_port)); boost::system::error_code ec; // Open the acceptor m_acceptor.open(endpoint.protocol(), ec); if (ec) { LOG_ERROR("SimpleTCPServerTest", "Failed to open acceptor: " << ec.message()); return false; } // Allow address reuse m_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); if (ec) { LOG_ERROR("SimpleTCPServerTest", "Failed to set reuse option in acceptor: " << ec.message()); return false; } // Bind to the server address m_acceptor.bind(endpoint, ec); if (ec) { LOG_ERROR("SimpleTCPServerTest", "Failed to bind acceptor: " << ec.message()); return false; } // Start listening for connections m_acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); if (ec) { LOG_ERROR("SimpleTCPServerTest", "acceptor failed to start listening: " << ec.message()); return false; } m_acceptor.async_accept(boost::asio::make_strand(m_ioc), [this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket) { on_accept(ec, std::move(socket)); }); m_iocRunThread = boost::thread([this] { m_ioc.run(); LOG_INFO("Exiting run thread"); }); return true; } } void SimpleTCPServerTest::on_accept(boost::system::error_code ec, boost::asio::ip::tcp::socket socket) { LOG_INFO("Client is connected"); m_socketHandler = std::make_unique<SocketHandler>(std::move(socket)); read(); } void SimpleTCPServerTest::read() { LOG_INFO("SimpleTCPServerTest", "Waiting a new message"); readTimer.expires_from_now(boost::posix_time::milliseconds(50)); readTimer.async_wait([this](boost::system::error_code ec) { LOG_INFO("Timer expired"); if (ec != boost::asio::error::operation_aborted) return; LOG_INFO("Timer expired with error"); m_socketHandler->socket.cancel(); }); m_socketHandler->socket.async_read_some(m_buffer, [this](const boost::system::error_code error, // Result of operation. std::size_t bytes_transferred) { if (error) { LOG_INFO("Client disconnected: " << error.message()); signalReadyToStop.emitSignal(); // HERE IT CRASHES return; } std::string dataString(boost::asio::buffer_cast<const char*>(m_buffer), bytes_transferred); LOG_INFO("Data was received: Size: " << bytes_transferred << " " << dataString); // Reset the buffer std::vector<char> buffer_data(1024); this->m_buffer = boost::asio::buffer(buffer_data); this->read(); }); } SimpleTCPServerTest::~SimpleTCPServerTest() { LOG_INFO("Terminating"); readTimer.cancel(); m_acceptor.cancel(); m_socketHandler->socket.cancel(); m_ioc.stop(); m_iocRunThread.join(); } The client is a simple python client that sends a few messages before disconnecting. my main.cpp is like: std::atomic<bool> m_runFlag = true; SimpleTCPServerTest server; server.signalReadyToStop.connect([&m_runFlag](){ m_runFlag =false; }); server.open(); while(m_runFlag) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } LOG_INFO("Exiting test"); } The problem is that the code always crashes when returning from the async_read (indicated with "HERE IT CRASHES COMMENT") with error SIGABRT tcache_thread_shutdown(): unaligned tcache chunk detected. Even if I remove the return statement there, I still have the crash when calling m_ioc.stop(). It seems the error occurs when exiting from the m_iocRunThread (the "Exiting run thread" log is executed) What am I doing wrong? Thanks everyone
participants (1)
-
Maria Tirindelli