2016-07-11 8 views
1

私のプログラムは内部ログを.txtファイルに保存します。 TCP(SSL暗号化)経由で接続すると、プログラムはログファイルの内容を送信します。Boost.Asio:大きすぎるメッセージを送信するとセグメンテーションエラーが発生する

これは、データを送信しているコードです:

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(); 
    } 
} 

のでNIUserSession::writeを文字列としてログファイルの内容を渡されます。

プログラムが非常に長い時間実行されていない場合、ログファイルは短く、すべて正常に動作します。しかし、それがしばらく実行され、ログファイルが長くなったり長くなったりすると、プログラムはデータを送信しようとするとSIGSEGVを受信します。これはgdbログです:

Writing message 

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7ffff4fe1700 (LWP 21047)] 
__memcpy_sse2_unaligned() at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33 
33  ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory. 
(gdb) where 
#0 __memcpy_sse2_unaligned() at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33 
#1 0x00007ffff7998454 in ??() from /lib/x86_64-linux-gnu/libssl.so.1.0.0 
#2 0x00007ffff79985c3 in ??() from /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 ??() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#11 0x00007ffff566e184 in start_thread (arg=0x7ffff4fe1700) at pthread_create.c:312 
#12 0x00007ffff5b8237d in clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 

私はなぜそれが起こっているのか分かりません。おそらくサイズをboost::asio::bufferにする必要がありますか?

また、io_service::run()は、独自の分離スレッドで実行されています。これが問題なのでしょうか?

+0

valgrindはエラーが発生した行番号を与えることができます。試しましたか? –

+0

さて、私は 'async_write'を使うので、Boost.Asioのどこかに深くなければならないと思います。 'write'関数が呼び出されますが、' writeHandler'は決して到達されません。しかし、私はまだそれを試すことができます。 – Bobface

+0

非常に奇妙な、valgrindと私はsigsegvを受け取りません... – Bobface

答えて

6

これはasioの使用に関する一般的な問題です。 boost::asio::buffer(message)を使用してバッファを送信していますが、データはコピーされません。データの参照を作成するだけで、操作が終了するまでこのオブジェクト(お客様のmessage)の責任を負うことになります。しかし、あなたが関数を終了するときにNIUserSession::writeあなたのmessageを含むすべてのスタック変数が破壊されます。

この問題を解決するには、データをより寿命の長いオブジェクトに配置する必要があります。たとえば、shared_ptrなどです。有効な例は、次のようなものです。

関連する問題