Я пытаюсь создать прокси, который работает правильно только для первого сеанса в одном запуске приложения. Он ловит 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
к нему. Когда каждое из них выполнит все действия или произойдет какая-либо ошибка, они reset
их shared_ptr
в сеансе, поэтому он освобожден.