0

I am using boost message queue to communicate among different processes. I am transmitting an object of type Packet. To do this, I am using serialization and deserialization in send and receive functions.

However, when I try to send the data, I am getting this error: boost::interprocess_exception::library_error

No other information is given.

This is how I create message queues.

 for(i = 0; i< PROC_MAX_E ; i++){
        std::string mqName = std::string("mq") + std::to_string(i);
        std::cout << " Size of Packet is " << sizeof(Packet) << std::endl;
        message_queue mq(open_or_create, mqName.c_str(), MAX_QUEUE_SIZE_E, 100*sizeof(Packet)); // size of packet later
      }

This is my Packet :

 class Packet{
    public :
    Packet();
    Packet(uint32_t aType, uint32_t aProcId);
    ~Packet();
    uint32_t getType();
    union{
      uint32_t  mFuncId;
      //uint8_t   mResult8;
      uint32_t  mResult32;
      //uint64_t  mResult64;
      //bool      mResult;
      //uint8_t*  mAddr8;
      //uint32_t* mAddr32;
      //uint64_t* mAddr64;
      //char      mData[MAX_PACKET_SIZE]; // This will be used to store serialized data
    };

    friend class boost::serialization::access;

    template <class Archive>
    void serialize(Archive & ar, const unsigned int version){
      ar & _mType;
      ar & _mProcId;
      //ar & mData;
      ar & mFuncId;
      //ar & mResult32;
      }


    private :
    uint32_t _mType;
    uint32_t _mProcId;


  }; // end class

} // end namespace

This is my serialize and deserialize functions:

std::string IPC::_serialize(Packet aPacket){
    std::stringstream oss;
    boost::archive::text_oarchive oa(oss);
    oa << aPacket;
    std::string serialized_string (oss.str());
    return serialized_string;

  }



  Packet IPC::_deserialize(std::string aData){
    Packet p;
    std::stringstream iss;
    iss << aData;
    boost::archive::text_iarchive ia(iss);
    ia >>  p;
    return p;
  }

And this is my send and receive functions:

bool IPC::send(uint32_t aProcId, Packet aPacket){
    try{
        _mLogFile << "<-- Sending Data to Process : " << aProcId << std::endl;
        //uint32_t data = aPacket;
        std::string mqName = std::string("mq") + std::to_string(aProcId);
        message_queue mq(open_only, mqName.c_str());
        //serialize Packet
        std::cout << "Serializing \n";
        std::string data = _serialize(aPacket);
        std::cout << " Serialized data =" << data.data() << "Size = " << data.size()<< std::endl;
        mq.send(data.data(), data.size(), 0);
        //mq.send(&data, sizeof(uint32_t), 0);
    }catch(interprocess_exception &ex){
        _mLogFile << "***ERROR*** in IPC Send to process : " << aProcId << " " << ex.what() << std::endl;
        std::cout << "***ERROR*** in IPC Send to process : " << aProcId << " " << ex.what() << std::endl;
        _ipc_exit();
    }
  }

I am getting exception during mq.send

When I transmit only integers it works fine. Only with serialization and deserialization, I get this error

Any help is greatly appreciated.I am a little stuck as the exception message is also not clear. I am using boost 1_57_0

Rgds Sapan

Sapan
  • 1,593
  • 3
  • 24
  • 34
  • have you tried debugging? in gdb, `catch throw` helps. Also, add error handling around the (de)serialization function bodies (I'm not sure they are used). In particular, catch archive exceptions. – sehe Sep 20 '15 at 13:05
  • Catchpoint 3 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x625770, tinfo=0x416c90 , dest=0x4077a2 ) at ../../../../../src/lnx64/libstdc++-v3/libsupc++/eh_throw.cc:71 71 ../../../../../src/lnx64/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory. – Sapan Sep 21 '15 at 02:46
  • Just to add that the exception is coming while executing mq.send function – Sapan Sep 21 '15 at 08:21
  • Have you.... tried looking at the stack there (`bt`)? – sehe Sep 21 '15 at 08:23
  • Doing a little debugging and rearranging some code, I could see error coming in _serialize at line oa << Packet The exception that I get on this line is Program received signal SIGSEGV, Segmentation fault. 0x0000000000417767 in boost::archive::basic_text_oprimitive::save (this=0x7fffffffbf40, t=...) at /u/red22/flexras/tools/boost_1_57_0/include/boost/archive/basic_text_oprimitive.hpp:173 – Sapan Sep 21 '15 at 09:33
  • Good work. Now, to find the real cause. Just eliminate sources by commenting lines one at a time, maybe. Keep in mind you may have [undefined behaviour](https://en.wikipedia.org/wiki/Undefined_behavior) originating from somewhere else entirely. Check values in your debugger, or use a memory checker (valgrind, -fsanitize=undefined) to spot it. – sehe Sep 21 '15 at 09:34
  • @sehe Very strange behaviour. I am getting Segmentation Fault while executing line "oa << aPacket;" in function serialize. Any idea from this can come from. Or anything I could be missing? – Sapan Sep 22 '15 at 11:48
  • Yes. UB like I said before. You need to make this a SSCCE. – sehe Sep 22 '15 at 11:50
  • See also: [Nobody writes testcases anymore](http://kera.name/articles/2013/10/nobody-writes-testcases-any-more/) and [Solve your problem by almost asking a question on StackOverflow](http://blog.jerryorr.com/2014/04/solve-your-problem-by-almost-asking.html). – sehe Sep 22 '15 at 11:52

1 Answers1

0

Try closing or flushing the string steam before using the string.

std::string IPC::_serialize(Packet aPacket){
    std::stringstream oss; 
    {
        boost::archive::text_oarchive oa(oss);
        oa << aPacket;
    }
    return oss.str();
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • This also did not help. I added catch throw in gdb and got above exception. NOt sure what that exception means – Sapan Sep 21 '15 at 02:47