具有shared_ptr的处理程序中的分段错误

问题描述 投票:0回答:1

我正在尝试使代理仅在执行一次应用中的第一个会话中正常工作。它捕获SIGSEGV试图处理第二个。

它以另一种方式工作:

  • 客户端连接
  • 代理连接到终端服务器(每个会话唯一连接)
  • 代理将数据发送到服务器,从服务器获取处理的数据并将处理的数据发送到客户端
  • 代理断开与服务器和客户端的连接

问题是,当我们启动应用程序并且第一个客户端尝试使用代理时,它工作正常(如果客户端始终连接到代理,例如第一个客户端获取了其数据,发生了断开连接,然后只有第二个客户端连接了)。但是,当第二个尝试在此之后尝试连接时,执行甚至无法到达handleAccept并在SIGSEGV__atomic_add函数中捕获atomicity.h(我在Linux上工作)。

我无法理解我是否使处理程序错误,使用shared_ptr错误,或同时使用这两种方法。

[run在创建Proxy对象以使其接受并处理客户端连接后被调用一次:

void Proxy::run() // create the very first session and keep waiting for other connections
{
    auto newSession = std::make_shared<Session>(ioService_);

    acceptor_.async_accept(
        newSession->getClientSocket(),
        [&](const boost::system::error_code &error) // handler is made according to boost documentation
        {
            handleAccept(newSession, error);
        }
    );

    ioService_.run();
}

handleAccept做几乎相同的事情,但也使会话开始在客户端和终端服务器之间传输数据:

void Proxy::handleAccept(std::shared_ptr<Session> session, const boost::system::error_code &error) // handle the new connection and keep waiting other ones
{
    if (!error)
    {
        session->connectToServer(serverEndpoint_);
        session->run(); // two more shared_ptr's to session are appeared here and we just let it go (details are further)
    }

    auto newSession = std::make_shared<Session>(ioService_);

    acceptor_.async_accept(
        newSession->getClientSocket(),
        [&](const boost::system::error_code &error)
        {
            handleAccept(newSession, error);
        }
    );
}

Session包含两个Socket对象(服务器和客户端),每个对象都具有shared_ptr。当他们每个人都将执行所有操作或发生某些错误时,他们会将resetshared_ptr发送给会话,以便将其释放。

c++ boost shared-ptr gnu
1个回答
3
投票

为什么要在handleAccept(...)中通过引用使用/捕获局部变量?:

 acceptor_.async_accept(
        newSession->getClientSocket(),
        [&](const boost::system::error_code &error)
        {
            handleAccept(newSession, error);
        }
    );

您要使用:

 acceptor_.async_accept(
        newSession->getClientSocket(),
        [this, newSession](const boost::system::error_code &error)
        {
            handleAccept(newSession, error);
        }
    );

lambda将在函数完成后运行,并且在此之前销毁局部变量newSession。

© www.soinside.com 2019 - 2024. All rights reserved.