Boost.Asio:发送太大消息时出现分段错误

鲍勃菲斯

我的程序将一些内部日志保存到.txt文件中。如果通过TCP(SSL加密)连接到该服务器,则程序将发送日志文件的内容。

这是发送数据的代码:

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()正在其自己的分离线程中运行。这可能是个问题吗?

PSIAlt

这是asio使用的常见问题。您正在使用发送缓冲区boost::asio::buffer(message),但不会复制数据。它只是为数据创建引用,您将负责此对象(您的message)生命周期,直到操作结束。但是,当您退出函数时,NIUserSession::write所有堆栈变量都将被破坏,包括您的message

要解决此问题,您应该将数据放入寿命更长的对象中,例如,放在shared_ptr中有效的示例可以是这样的:

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 it into callback to guarantee lifetime */
               ));
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Boost asio发送和接收消息

来自分类Dev

(Boost.Python)导入boost python模块后退出Python 3时出现分段错误

来自分类Dev

Boost asio错误10054

来自分类Dev

Boost Asio错误

来自分类Dev

Visual Studio 2013中的boost :: asio示例代码分段错误

来自分类Dev

Boost :: Asio。消息在哪个线程中发送?

来自分类Dev

使用boost :: timer作为定期调用的类的成员而破坏类时出现分段错误

来自分类Dev

在Boost中使用prim_minimum_spanning_tree时出现分段错误

来自分类Dev

使用boost.asio的免费async_ *函数时出现奇怪的错误

来自分类Dev

来自boost :: asio的Valgrind错误

来自分类Dev

boost mpi发送NULL消息

来自分类Dev

boost mpi发送NULL消息

来自分类Dev

Boost.spirit 使用复合语法解析时的分段错误

来自分类Dev

ASIO处理程序参数和boost :: bind,编译时错误

来自分类Dev

Boost.Python和Boost.Signals2:分段错误

来自分类Dev

使用Boost ASIO进行Boost异常处理

来自分类Dev

使用Boost ASIO进行Boost异常处理

来自分类Dev

Boost Asio - boost::bind 导致程序崩溃

来自分类Dev

Boost asio网络单独发送和接收

来自分类Dev

如何丢弃通过boost :: asio发送的数据?

来自分类Dev

通过boost :: asio发送原始数据

来自分类Dev

Boost Asio如何发送多个请求

来自分类Dev

使用boost :: asio通过UDP发送结构

来自分类Dev

如何丢弃通过boost :: asio发送的数据?

来自分类Dev

boost asio绑定端点

来自分类Dev

Boost :: Asio写锁

来自分类Dev

boost asio绑定端点

来自分类Dev

boost :: asio的应用

来自分类Dev

源自`boost :: asio :: streambuf`