c++ - Boost.Asio segfault, ni idea por qué
segmentation-fault boost-asio (1)
Creo que descubrí el problema. Tenga en cuenta el orden de declaración de los miembros del Server
:
boost::shared_ptr<Connection> connection;
boost::asio::io_service io_service;
boost::asio::signal_set signal_monitor;
La orden de destrucción se realiza en el orden opuesto de la declaración. Esto significa que primero signal_monitor
, luego io_service
y finalmente la connection
se destruyen. Pero la connection
contiene un boost::asio::ip::tcp::socket
contiene una referencia a io_service
, que se destruyó.
Y de hecho, esto es más o menos lo que está sucediendo, y también causa una segfault:
int main(int argc, char **argv) {
auto io_service = new boost::asio::io_service();
auto socket = new boost::asio::ip::tcp::socket(*io_service);
delete io_service;
delete socket;
return 0;
}
Declarar la connection
después de io_service
resuelve el problema.
Maldita sea
Este es un SSCCE de mi proyecto Boost.Asio basado en los ejemplos. Me tomó alrededor de una hora rastrear el error hasta esto:
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
class Connection {
public:
Connection(boost::asio::io_service& io_service) : socket(io_service) {}
private:
boost::asio::ip::tcp::socket socket;
};
class Server {
public:
Server() : signal_monitor(io_service) {
signal_monitor.add(SIGINT);
signal_monitor.add(SIGTERM);
signal_monitor.async_wait(
boost::bind(&Server::handle_signal_caught, this)
);
}
void run() {
// comment out the next line and there''s no segfault
connection.reset(new Connection(io_service));
io_service.run();
}
private:
void handle_signal_caught() {
io_service.stop();
}
boost::shared_ptr<Connection> connection;
boost::asio::io_service io_service;
boost::asio::signal_set signal_monitor;
};
int main(int argc, char **argv) {
Server server;
server.run();
return 0;
}
Cuando envío una señal (ctrl + C), el programa falla por defecto en lugar de cerrarse. Me he pasado la última media hora mirando esto, pero simplemente no veo por qué esto segfault, ¿alguno de ustedes puede detectar el problema?