Eliminar un objeto que contiene miembros de tipo smart_pointer resulta en un fallo del programa.
Tengo una clase muy simple que trabaja con boost::asio::ip::tcp::socket que ofrece esta simple interfaz:
class SimpleClient {
//private
boost::scoped_ptr<boost::asio::ip::tcp::socket> signal_socket;
protected:
ClientState state; //0: Listo para ser utilizado, no conectado, -1: error, 1: Conectado/activo
public:
SimpleClient();
virtual bool connect(const char* ip_address);
virtual void disconnect();
virtual bool sendMessage(const char* msg, int length);
virtual int getSignalData(char* msg, int length);
virtual ClientState getState();
};
Estoy intentando probar las funcionalidades de conexión usando boost.test pero la prueba parece estrellarse antes de completar:
#define BOOST_AUTO_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include "SimpleClient.hpp"
#include <boost test/unit_test.hpp="">
#include <string.h>
#define TARGET_IP "127.0.0.1"
#define BAD_IP "128.0.0.1"
BOOST_AUTO_TEST_CASE(basis_constructor_test){
SimpleClient* ut = new SimpleClient();
BOOST_CHECK_EQUAL(ut->getState(), ClientState::CL_READY);
delete ut;
}
BOOST_AUTO_TEST_CASE(connection_test) {
bool ret;
SimpleClient* ut = new SimpleClient();
BOOST_CHECK_EQUAL(ut->getState(), ClientState::CL_UNCON);
ret = ut->connect(BAD_IP);
BOOST_CHECK(!ret);
ret = ut->connect(TARGET_IP);
std::cout<<"HEY3"<<std::endl; boost_check(ret);=""></std::endl;><std::endl<<"val></std::endl<<"val><><std::endl; ut-="">disconnect();
std::cout<<"HEY5"<<std::endl; try{="" delete="" ut;="" }="" catch(const="" std::exception&="" ex)="" {=""></std::endl;><><std::endl; }="" catch(...)="" {="" std::cerr<<"error="" not=""></std::endl;><std::endl; }="" }="" ```="" esta="" prueba="" da="" esta="" salida,="" y="" no="" da="" el="" resumen="" habitual="" que="" boost.test="" produce:="" ```="" hey0="" hey1="" hey2="" hey3="" hey4="" val="" 1="" ```="" para="" completar,="" incluyo="" el="" código="" del="" constructor="" y="" el="" método="" connect:="" ```="" simpleclient::simpleclient()="" {="" cmd_socket.reset();="" signal_socket.reset();="" status_socket.reset();="" state="ClientState::CL_UNCON;" }="" bool="" simpleclient::connect(const="" char*="" ip_address)="" {="" boost::asio::io_context="" io_context;="" boost::system::error_code="" ec;="" if="" (signal_socket="" !="NULL" &&="" signal_socket-="">is_open() )
return true;
try {
boost::asio::ip::tcp::endpoint signal_endpoint(boost::asio::ip::make_address(ip_address), OE_SIGNAL_PORT);
boost::asio::socket_base::reuse_address option(true);
signal_socket.reset(new boost::asio::ip::tcp::socket(io_context, signal_endpoint));
signal_socket->set_option(option, ec);
if(ec)
std::cout<<><std::endl; signal_socket-="">connect(signal_endpoint, ec);
std::cout<<"HEY0"<<std::endl; if(ec)="" {=""></std::endl;><><><std::endl; return="" false;="" }=""></std::endl;><std::endl; }="" catch(...)="" {//catch(const="" boost::system::system_error&="" ex)="" {="" std::cout<<"system="" error:=""></std::endl;><std::endl;></std::endl;><><><std::endl; return="" false;="" }=""></std::endl;><std::endl; state="ClientState::CL_READY;" return="" true;="" }="" void="" simpleclient::disconnect()="" {="" if(signal_socket!="NULL" &&="" signal_socket-="">is_open()) {
signal_socket->shutdown(boost::asio::socket_base::shutdown_both);
signal_socket->close();
signal_socket.reset();
}
state = ClientState::CL_UNCON;
}
Esto parece estar vinculado a la eliminación del objeto SimpleClient, ¿hay alguna operación que deba hacer antes de destruir un smart-pointer o antes de destruir un socket conectado?
P.D. la aplicación no se bloquea con ningún mensaje y no produce ningún archivo de volcado o registro. Sé que no se completa correctamente, ya que el informe de prueba que genera boost.test en la consola no se imprime.</std::endl;></std::endl;></std::endl;></std::endl;></string.h>
davy.ai
Parece que el problema está relacionado con el
delete
del objetoSimpleClient
. Antes de destruir un puntero inteligente o un socket conectado, deberías asegurarte de llamar adisconnect()
para cerrar el socket y reiniciar el puntero inteligente.Es posible que la aplicación se esté bloqueando sin producir ningún archivo de volcado o registro. Puedes intentar depurar la aplicación para averiguar la causa exacta del bloqueo.