2013-02-25 98 views
1

我正在寫一個smpp客戶端,我有一個問題,我無法解決。我寫了一個tcp_client類內部io_service對象類來封裝TCP交際的全部過程。從那以後,我意識到我需要在繼承類,控制,運行到完成另一個任務,所以,我修改了tcp_client來初始化繼承類的構造函數的io_service對象,並從那裏。boost io_service初始化SIGSEGV

tcp_client類:

class tcp_client 
{ 
public: 
    tcp_client(boost::asio::io_service &_io_service, tcp::resolver::iterator endpoint_iterator) 
     : m_io_service(_io_service), socket_(_io_service) 
    { 
     connect_start(endpoint_iterator); 
     // this works OK 
    } 

    tcp_client(boost::asio::io_service &_io_service) 
    :m_io_service(_io_service),socket_(m_io_service) 
    { 
     // SIGSEGV 
    } 

    tcp_client(void) 
    :m_io_service(tcp_io_service),socket_(m_io_service) 
    { 
     // Works OK 
    } 

    void connect(const char *host, const char *port) 
    { 
    if(get_tcp_status()==CONNECTED || get_tcp_status()==CONNECTING) 
    { 
     do_close(); 
    } 
    tcp::resolver::query query(host,port); 
    tcp::resolver resolver(m_io_service); 
    tcp::resolver::iterator iterator = resolver.resolve(query); 
    connect_start(iterator); 
    m_io_service_thread = boost::thread(boost::bind(&boost::asio::io_service::run,&m_io_service)); 
    } 
private: 
    boost::asio::io_service &tcp_io_service; 
    ......................... 
    ......................... 
} 

在構造

tcp_client(boost::asio::io_service &_io_service) 
     :m_io_service(_io_service),socket_(m_io_service) 
     { 

     } 

我接收SIGSEGV信號,約互斥。其他構造者工作得很好,但這阻止了我。我可以繼續使用可以正常工作的其他構造函數進行開發,但是我想知道這裏有什麼問題,只是爲了體育(學習)。

,我使用的這個繼承的類是:

class smpp_client : public tcp_client 
{ 
private: 
    boost::asio::io_service smpp_io_service; 
public: 
    smpp_client(boost::asio::io_service &_io_service, tcp::resolver::iterator endpoint_iterator) 
     :tcp_client(_io_service,endpoint_iterator), 
     m_smpp_status(SC_BIND_DISCONNECTED), 
     rx_thread_exit(false) 
     { 
    m_windowing = 10; 
    initialize_stack(); 
     } 

    smpp_client(void): 
     tcp_client(smpp_io_service), 
     m_smpp_status(SC_BIND_DISCONNECTED), 
     rx_thread_exit(false) 
     { 
    m_windowing = 10; 
    initialize_stack(); 
    //smpp_io_service.post(boost::bind(&smpp_client::rx_loop,this)); 
     } 
........... 
........... 
} 

這個類中的第一個構造工程確定,但第二次調用tcp_client是上升一個SIGSERV信號的構造。

主要是:

/*boost::asio::io_service io_service; 
tcp::resolver::query query(argv[1],argv[2]); 
tcp::resolver resolver(io_service); 
tcp::resolver::iterator iterator = resolver.resolve(query); 

smpp_client c(io_service,iterator); 

boost::thread t(boost::bind(&boost::asio::io_service::run,&io_service));*/ 

smpp_client c; // --> HERE SIGSEGV 

我已用gdb和Valgrind的測試,在輸出的信息是相同的:

計劃接收信號SIGSEGV,分割故障。 來自/lib64/libpthread.so.0的pthread_mutex_lock()中的0x00007ffff6bdbe64

我檢查當時的所有地址和值,但我不知道如何解決它。

我使用Linux Slackware的13.37與提升1.49和gcc 4.7.1

PD:完整的代碼可以在https://github.com/jpcordovae/smpp_client觀看,但在這個錯誤沒有更新。

回答

2

第二個構造不工作,因爲你提到過未初始化的成員smpp_io_service作爲基類構造函數的參數。在C++中,首先調用所有基類構造函數,並啓動非靜態成員。

請參閱有關初始化命令的詳細信息this問題。

當使用io_service對象創建第一個構造早些時候,這就是爲什麼代碼工作就好了。

+0

TY非常多,我讓smpp_io_service靜態的,它反正再完美的作品:) – 2013-02-25 18:43:12

+0

,我如果前檢查與GDB和我沒有問題讀取smpp_io_service的有效地址,所以,糾正我,如果我認爲有效地址不意味着有效的初始化。 – 2013-02-25 18:59:01

+0

是的,你是對的。地址是有效的,因爲內存已分配 - 只有構造函數尚未執行 – 2013-02-25 19:32:22

0

嘗試採取看看_io_service說法。確保它已被正確定義並且不爲零。此外,socket_對象是您的套接字對象,您似乎正在初始化爲m_io_service。套接字對象不是io_service對象。確保將其初始化爲適當類型的套接字對象。我使用SSL,所以這是我的初始化:

boost::shared_ptr<boost::asio::io_service> IOServ(new boost::asio::io_service); 
IOService = IOServ; 
pSocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(*IOService, ctx); 
boost::asio::async_connect(pSocket->lowest_layer(), EndpointIterator, 
    boost::bind(&SSLSocket::HandleConnect, this, boost::asio::placeholders::error)); 
+0

我做到了,GDB給了我一個有效的地址,或者我認爲這是一個有效的地址,也許是時間去搜索一本關於C++的好書了帶有初始化章節。 – 2013-02-25 19:01:24