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

Segmentation fault in handlers with shared_ptr's

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

接下来的工作方式:

问题是当我们启动应用程序并且第一个客户端尝试使用代理时,它工作正常(让客户端始终连接到代理,例如第一个获取其数据,发生断开连接,然后第二个才连接).但是当第二个尝试在此之后连接时,执行甚至无法到达 handleAccept 并在 atomicity.h__atomic_add 函数中捕获 SIGSEGV (我在 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。当他们每个人都完成所有操作或发生某些错误时,他们 reset 他们的 shared_ptr 到会话,因此它被释放。

为什么你 use/catch 在 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将在此之前销毁。