[zeromq-dev] [PATCH]
Daniel Sentenac
sentenac at ego-gw.it
Mon Oct 11 09:19:37 CEST 2010
Martin Sustrik wrote:
> Hi Daniel,
>> I've tried to apply your patch, however, I've realised there's a
>> problem there. When you close the message, you may still use it in
>> the next iteration, thus accessing deinitialised data.
>>
>> We have to think of something more sophisticated...
> Have a look at the attached patch. It's a patch for maint, however,
> same thing should work for master. Can you check in your use case and
> confirm it solves the leak? When you do so, I'll commit the patch to
> both maint and master.
>
> Martin
> ------------------------------------------------------------------------
>
> diff --git a/src/pub.cpp b/src/pub.cpp
> index 4e73b19..d4a1824 100644
> --- a/src/pub.cpp
> +++ b/src/pub.cpp
> @@ -133,13 +133,25 @@ int zmq::pub_t::xsend (zmq_msg_t *msg_, int flags_)
> }
>
> // Push the message to all destinations.
> + int passivised = 0;
> for (pipes_t::size_type i = 0; i != active;) {
> if (!write (pipes [i], msg_))
> - content->refcnt.sub (1);
> + passivised++;
> else
> i++;
> }
>
> + // If some of the pipes we've tried to send the message to have become
> + // passive we have to subtract corresponding number of references from
> + // the message. If there are no more references on the message we can
> + // destroy it.
> + if (passivised) {
> + if (!content->refcnt.sub (passivised)) {
> + msg_->flags &= ~ZMQ_MSG_SHARED;
> + zmq_msg_close (msg_);
> + }
> + }
> +
> // Detach the original message from the data buffer.
> int rc = zmq_msg_init (msg_);
> zmq_assert (rc == 0);
>
Hi Martin,
I just tried your patch and I get a crash of the server starting from
two receiver clients with following trace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1282638944 (LWP 17487)]
0x00b07daa in memcpy () from /lib/tls/libc.so.6
(gdb) bt
#0 0x00b07daa in memcpy () from /lib/tls/libc.so.6
#1 0xb7e1ab0e in zmq::zmq_engine_t::out_event (this=0x8093b08) at
encoder.hpp:117
#2 0xb7e01380 in zmq::epoll_t::loop (this=0x8088990) at epoll.cpp:193
#3 0xb7e013f3 in zmq::epoll_t::worker_routine (arg_=0x8088990) at
epoll.cpp:210
#4 0xb7e15645 in zmq::thread_t::thread_routine (arg_=0x80889b0) at
thread.cpp:99
#5 0x00c1d3cc in start_thread () from /lib/tls/libpthread.so.0
#6 0x00b65c3e in clone () from /lib/tls/libc.so.6
I think the problem comes from a useless reference subtraction in the
first test case, since you subtract all the passivised in a second time.
I tried the following and it works well with no leak in my video
distribution test:
// Push the message to all destinations.
int passivised = 0;
for (pipes_t::size_type i = 0; i != active;) {
if (!write (pipes [i], msg_) )
passivised++;
else
i++;
}
// If some of the pipes we've tried to send the message to have become
// passive we have to subtract corresponding number of references from
// the message. If there are no more references on the message we can
// destroy it.
if (passivised) {
if (!content->refcnt.sub (passivised)) {
msg_->flags &= ~ZMQ_MSG_SHARED;
zmq_msg_close (msg_);
}
}
More information about the zeromq-dev
mailing list