c++ - Boost.Asio: Segmentation fault when sending too big message -
my program saves internal logs .txt file. if connect via tcp (ssl encrypted), program send contents of log file.
this code sending data:
void niusersession::write(std::string message) { std::cout << "writing message" << std::endl; message.append("<eof>"); boost::system::error_code ec; boost::asio::async_write(this->socket_, boost::asio::buffer(message), boost::asio::transfer_all(), boost::bind(&niusersession::writehandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred())); } void niusersession::writehandler(const boost::system::error_code &error, std::size_t bytes_transferred) { std::cout << "write handler" << std::endl; if(error) { std::cout << "write handler error: " << error.message() << std::endl; this->disconnect(); } }
so niusersession::write
gets passed logfile contents string.
if program not running long time logfile short , works fine. however, if runs while , log file gets longer , longer, program receive sigsegv
when tries send data. gdb log:
writing message program received signal sigsegv, segmentation fault. [switching thread 0x7ffff4fe1700 (lwp 21047)] __memcpy_sse2_unaligned () @ ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.s:33 33 ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.s: no such file or directory. (gdb) #0 __memcpy_sse2_unaligned () @ ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.s:33 #1 0x00007ffff7998454 in ?? () /lib/x86_64-linux-gnu/libssl.so.1.0.0 #2 0x00007ffff79985c3 in ?? () /lib/x86_64-linux-gnu/libssl.so.1.0.0 #3 0x00000000004b7eca in boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ssl::detail::write_op<boost::asio::const_buffers_1>, boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, boost::asio::const_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, niusersession, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<niusersession*>, boost::arg<1> (*)(), boost::arg<2> > > > >::operator()(boost::system::error_code, unsigned long, int) () #4 0x00000000004b8bf8 in boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, boost::asio::const_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, niusersession, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<niusersession*>, boost::arg<1> (*)(), boost::arg<2> > > >::operator()(boost::system::error_code const&, unsigned long, int) () #5 0x00000000004b7e6c in boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ssl::detail::write_op<boost::asio::const_buffers_1>, boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, boost::asio::const_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, niusersession, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<niusersession*>, boost::arg<1> (*)(), boost::arg<2> > > > >::operator()(boost::system::error_code, unsigned long, int) () #6 0x00000000004b965c in boost::asio::detail::reactive_socket_send_op<boost::asio::mutable_buffers_1, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t, boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ssl::detail::write_op<boost::asio::const_buffers_1>, boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > >, boost::asio::const_buffers_1, boost::asio::detail::transfer_all_t, boost::_bi::bind_t<void, boost::_mfi::mf2<void, niusersession, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<niusersession*>, boost::arg<1> (*)(), boost::arg<2> > > > > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) () #7 0x00000000004add59 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) () #8 0x00000000004ad911 in boost::asio::detail::task_io_service::run(boost::system::error_code&) () #9 0x00000000004a9c1f in netinterface::init() () #10 0x00007ffff641aa60 in ?? () /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #11 0x00007ffff566e184 in start_thread (arg=0x7ffff4fe1700) @ pthread_create.c:312 #12 0x00007ffff5b8237d in clone () @ ../sysdeps/unix/sysv/linux/x86_64/clone.s:111
i don't understand why happening. maybe have give size boost::asio::buffer
?
also, io_service::run()
running in own detached thread. problem?
this common issue asio usage. sending buffer using boost::asio::buffer(message)
, not copy data. creating reference data , responsible object (your message
) lifetime until operation ends. when exit function niusersession::write
stack variables destroyed, including message
.
to fix should place data object longer lifetime, example shared_ptr. valid example can this:
void niusersession::write(std::string &message_orig) { std::cout << "writing message" << std::endl; std::shared_ptr message = std::make_shared<std::string>( message_orig ); message->append("<eof>"); boost::system::error_code ec; boost::asio::async_write(this->socket_, boost::asio::buffer(*message), boost::asio::transfer_all(), boost::bind(&niusersession::writehandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred(), message /* <- capture callback guarantee lifetime */ )); }
Comments
Post a Comment