2013-08-02 24 views
4

這是一個基於示例的Boost.Asio項目中的SSCCE。我花了大約一個小時,跟蹤bug到這一點:Boost.Asio segfault,不知道爲什麼

#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; 
} 

當我發出信號(Ctrl + C)的程序段錯誤,而不是很好地關閉。我花了最後半個小時看這個,但我不明白爲什麼會出現段錯誤,你們中的任何人都可以發現這個問題嗎?

回答

7

我想我發現了這個問題。需要注意的Server成員的聲明順序:

boost::shared_ptr<Connection> connection; 
boost::asio::io_service io_service; 
boost::asio::signal_set signal_monitor; 

銷燬順序在聲明相反的順序進行。這意味着首先signal_monitor,然後io_service和最後connection被破壞。但是connection包含一個boost::asio::ip::tcp::socket,其中包含對io_service的引用,該引用被破壞。

事實上,這幾乎是什麼事情發生,並導致段錯誤太:

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; 
} 

聲明connectionio_service後解決了這個問題。

該死的

相關問題