zeromq / zmqpp

0mq 'highlevel' C++ bindings
http://zeromq.github.io/zmqpp
Mozilla Public License 2.0
438 stars 195 forks source link

Valgrind disagree with pop_front() on received zmqpp::message #204

Open pavel-orekhov opened 6 years ago

pavel-orekhov commented 6 years ago

When I call pop_front() on message after sock.receive() valgrind starts to worry. I use 4.2.0+ version at intel64 (ubuntu 17.10) Please confirm the bug.

commit 818f9c37054a8b6ce8520fd80d72989993bc6ce5 (HEAD -> develop, origin/develop, origin/HEAD) Author: Ben Gray ben@benjamg.com Date: Fri Nov 3 11:29:06 2017 +0000 shifted tests to use last_endpoint to avoid port collisions (#203) commit f8ff127683dc555aa004c0e6e2b18d2354a375be (tag: 4.2.0)

A sample is here: popfront.cpp.txt

pavel-orekhov commented 6 years ago

I found a sentence:

If you do use zmq_msg_recv(), always release the received message as soon as you're done with it, by calling zmq_msg_close().

Queue to check it with pop_front()

rcane commented 6 years ago

The problem here is a bug in the move assignment operator of the frame class.

frame& frame::operator=(frame&& other)
{
    zmq_msg_init( &_msg );   <-- this line needs to go
    zmq_msg_move( &_msg, &other._msg );
    std::swap( _sent, other._sent );

    return *this;
}

The call to zmq_msg_init() at the beginning clears the zmq_msg_t object without closing it. Since zmq_msg_move() does that closing on the supplied _msg the solution is simple: just remove the zmq_msg_init() line.

Btw, the reason why valgrind is complaining about message::pop_front() is that this method erases the first element of the message from a std::vector<frame>. When doing this the vector needs to move all remaining frames thereby leaking memory for each of them.