2010-11-14 5 views
2

Im obtenir une erreur de segmentation de pthread_mutex_lock, voici mon backtrace:Segmentation fault sur boost :: asio :: :: ip tcp :: accepteur

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff61b03f0 in pthread_mutex_lock() from /lib/libpthread.so.0 
(gdb) bt 
#0 0x00007ffff61b03f0 in pthread_mutex_lock() from /lib/libpthread.so.0 
#1 0x000000000041141f in boost::asio::detail::posix_mutex::lock (this=0x1) 
    at /usr/include/boost/asio/detail/posix_mutex.hpp:71 
#2 0x00000000004242ee in boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >::basic_socket_acceptor(boost::asio::io_service&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const&, bool)() 
#3 0x000000000041c7df in Server (this=0x7fffffffe210) at src/server.cpp:12 
#4 0x00000000004280bd in main() at src/main.cpp:21 
(gdb) 

mon code:

#include "server.h" 

#include "client.h" 



#include <iostream> 

#include <boost/thread.hpp> 

#include <boost/bind.hpp> 



#include "defines.h" 



#include "server.h" 
#include "client.h" 

#include <iostream> 
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 

#include "defines.h" 

Irc::Server::Server() 
{ 
    // 
} 

Irc::Server::~Server() 
{ 
    m_clients.clear(); 
} 

void Irc::Server::start() 
{ 
    m_acceptor = new boost::asio::ip::tcp::acceptor(io); 
} 

void Irc::Server::startAccept() 
{ 
    SocketPtr p(new boost::asio::ip::tcp::socket(io)); 
    boost::asio::ip::tcp::resolver resolver(io); 
    boost::asio::ip::tcp::resolver::query query(SERVER_ADDRESS, SERVER_PORT); 
    boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); 
    m_acceptor->open(endpoint.protocol()); 
    m_acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 
    m_acceptor->bind(endpoint); 
    m_acceptor->listen(); 
    m_acceptor->async_accept(*p, 
     boost::bind(&Irc::Server::clientHandler, this, 
     p)); 
} 

void Irc::Server::clientHandler(SocketPtr newSocket) 
{ 
    typedef boost::shared_ptr<boost::thread> ThreadsPool; 
    typedef std::vector<ThreadsPool> Threads; 
    Threads threads; 
    for (int i = 0; i < 2; ++i) { 
     ThreadsPool p(new boost::thread(boost::bind(
      &boost::asio::io_service::run, &io))); 
     threads.push_back(p); 
    } 
    for (Threads::iterator it = threads.begin(); it != threads.end(); ++it) 
     (*it)->join(); 

    ClientPtr p(new Client(newSocket)); 
    m_clients[newSocket] = p; 
    SocketPtr new_(new boost::asio::ip::tcp::socket(io)); 
    m_acceptor->async_accept(*new_, 
     boost::bind(&Irc::Server::clientHandler, this, new_)); 
} 


#ifndef SERVER_H 
#define SERVER_H 

namespace Irc 
{ 
    class Client; 
    class Server; 
} //namespace Irc 

#include <boost/asio.hpp> 
#include <map> 

typedef boost::shared_ptr<Irc::Client> ClientPtr; 
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> SocketPtr; 
typedef std::map<SocketPtr, ClientPtr> ClientsMap; 

class Irc::Server 
{ 
    public: 
     Server(); 
     ~Server(); 

     void start(); 

     void startAccept(); 

     void clientHandler(SocketPtr); 

     ClientsMap::iterator begin() { return m_clients.begin(); } 
     ClientsMap::iterator end() { return m_clients.end(); } 

    private: 
     boost::asio::ip::tcp::acceptor* m_acceptor; 
     boost::asio::io_service io; 
     ClientsMap m_clients; 
}; 
#endif 
+1

Comme il vient du constructeur de m_acceptor, je ne peux que deviner que l'objet io donné en tant que paramètre est pas correctement initialisé . – Timo

+0

n'est ni un * ni un & ... –

+1

Oui, mais si, par exemple, l'objet Serveur et io sont définis dans la même portée, le serveur contstructor peut être appelé avant le constructeur pour io. Vous pourriez peut-être poster plus de code. – Timo

Répondre

0

Vous devez publiez plus de code (Server :: Server()) et publiez les fichiers dans des blocs de code séparés pour plus de lisibilité.

Essayez de changer io être un pointeur, et l'initialisation explicitement dans votre constructeur:

Irc::Server::Server() : io() 
{ 
    start(); 
    startAccept(); 
}