在第二次调用boost :: asio :: udp socket :: async_recv上的SIGSEGV在worker boost :: thread上

时间:2019-04-02 09:26:39

标签: boost-asio boost-thread

我第二次调用start_receive()时,在下一堂课中得到了SIGSEGV。它可以在我的open()函数中正常工作,但是在收到输入后似乎失败,我尝试重新启动以侦听更多输入:

#0  0x0000555555584154 in boost::asio::basic_io_object<boost::asio::datagram_socket_service<boost::asio::ip::udp>, true>::get_service (this=0x100007f00000000)
    at /usr/include/boost/asio/basic_io_object.hpp:225
#1  0x000055555558398b in boost::asio::basic_datagram_socket<boost::asio::ip::udp, boost::asio::datagram_socket_service<boost::asio::ip::udp> >::async_receive_from<boost::asio::mutable_buffers_1, boost::_bi::bind_t<int, boost::_mfi::mf2<int, Vast::net_udpNC_MChandler, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<Vast::net_udpNC_MChandler*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (this=0x100007f00000000, buffers=..., 
    sender_endpoint=..., handler=...)
    at /usr/include/boost/asio/basic_datagram_socket.hpp:895
#2  0x000055555557a889 in Vast::net_udpNC_MChandler::start_receive (
    this=0x7fffffff5c70) at net_udpnc_mchandler.cpp:58
#3  0x000055555557aa77 in Vast::net_udpNC_MChandler::handle_input (
    this=0x7fffffff5c70, error=..., bytes_transferred=24)
    at net_udpnc_mchandler.cpp:100
#4  0x000055555557abb3 in Vast::net_udpNC_MChandler::handle_buffer (
    this=0x7fffffff5c70, buf=0x7fffffffdad0 "\035\300", bytes_transferred=24)
    at net_udpnc_mchandler.cpp:114
#5  0x000055555556397f in test_process_encoded ()
    at unittest_net_udpnc_mchandler.cpp:43
#6  0x000055555556400e in main () at unittest_net_udpnc_mchandler.cpp:101

标题:

class net_udpNC_MChandler
    {
    public:
        net_udpNC_MChandler(ip::udp::endpoint local_endpoint);

        //MChandler will run its own io_service
        int open (AbstractRLNCMsgReceiver *msghandler);

        int handle_buffer (char *buf, std::size_t bytes_transferred);

    protected:

        //Start the receiving loop
        void start_receive ();

        // handling incoming message
        int handle_input (const boost::system::error_code& error,
                          std::size_t bytes_transferred);

    private:
        ip::udp::socket             *_udp;
        ip::udp::endpoint           _remote_endpoint_;
        ip::udp::endpoint           _local_endpoint;
        ip::udp::endpoint           MC_address;
        char                        _buf[VAST_BUFSIZ];
        AbstractRLNCMsgReceiver     *_msghandler = NULL;

        io_service                  *_io_service;
        boost::thread               *_iosthread;

};

源文件:

net_udpNC_MChandler::net_udpNC_MChandler(ip::udp::endpoint local_endpoint) :
        MC_address(ip::address::from_string("239.255.0.1"), 1037)
    {
        _io_service = new io_service();
        _local_endpoint = local_endpoint;
    }

    int net_udpNC_MChandler::open(AbstractRLNCMsgReceiver *msghandler) {
        _msghandler = msghandler;

        if (_udp == NULL) {
            _udp = new ip::udp::socket(*_io_service);
            _udp->open(ip::udp::v4());
            _udp->set_option(ip::udp::socket::reuse_address(true));
            _udp->set_option(ip::multicast::join_group(MC_address.address ()));

            boost::system::error_code ec;

            _udp->bind(MC_address, ec);

            std::cout << "net_udpnc_mchandler::open " + ec.message() << std::endl;

            if (ec)
            {
                std::cout << "net_udpnc_mchandler:: open MC address failed" << ec.message() << std::endl;
            }

            //Add async receive to io_service queue
            start_receive();

            std::cout << "net_udpnc_mchandler::open _udp->_local_endpoint: " << _udp->local_endpoint() << " _local_endpoint" << _local_endpoint << std::endl;

            //Start the thread handling async receives
            _iosthread = new boost::thread(boost::bind(&boost::asio::io_service::run, _io_service));
        }

        return 0;
    }

    void net_udpNC_MChandler::start_receive()
    {
        _udp->async_receive_from(
            boost::asio::buffer(_buf, VAST_BUFSIZ), _remote_endpoint_,
            boost::bind(&net_udpNC_MChandler::handle_input, this,
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred));
    }

    // handling incoming message
    int net_udpNC_MChandler::handle_input (const boost::system::error_code& error,
          std::size_t bytes_transferred)
    {

        RLNCHeader header;

        if (!error)
        {
            //Store UDP messages

            char *p = _buf;

            memcpy(&header, p, sizeof(RLNCHeader));


            if (RLNCHeader_factory::isRLNCHeader (header) && header.enc_packet_count > 1)
                {
                    CPPDEBUG("net_udpnc_mchandler::handle_input: Encoded packet received" << std::endl);
                    process_encoded (bytes_transferred);
                }

            //Restart waiting for new packets
            start_receive();
        }
        else {
            CPPDEBUG("Error on UDP socket receive: " << error.message() << std::endl;);
        }
        return -1;
    }

最奇怪的是,如果我使用不带参数的默认构造函数(即没有local_endpoint),则一切正常,此SIGSEGV不会出现。但是,一旦我将构造函数更改为当前的构造函数,就会得到SIGSEGV。

_io_service是一个类对象,除了析构函数之外,它不会在其他任何地方被破坏,所以我不知道如何为其获取SIGSEGV ...

对处理程序类是否有无参数构造函数的要求?

0 个答案:

没有答案