From c6baad57dc475c3140b5a7954dba4e55fbc2d1a2 Mon Sep 17 00:00:00 2001 From: Pieter Hintjens Date: Thu, 3 Apr 2014 12:17:19 +0200 Subject: [PATCH] Fixed memory leak on zmq_sendmsg failure - when this call fails, caller has to use zmq_msg_close() to avoid memory leak on messages larger than 30 bytes --- doc/zlog.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++++- src/zframe.c | 4 +++- src/zproxy.c | 9 ++++++--- src/zsocket.c | 26 ++++++++++++++++++-------- src/zstr.c | 9 ++++++--- 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/doc/zlog.txt b/doc/zlog.txt index bee28df1e..d7f656204 100644 --- a/doc/zlog.txt +++ b/doc/zlog.txt @@ -8,6 +8,44 @@ zlog - logging class SYNOPSIS -------- ---- +// Constructor; the sender name is prepended to every message, and may +// not be null. +CZMQ_EXPORT zlog_t * + zlog_new (const char *sender); + +// Destructor +CZMQ_EXPORT void + zlog_destroy (zlog_t **self_p); + +// Set foreground logging on/off. By default, this is off on systems that +// can do background logging using syslog, and on for systems without syslog +// support. +CZMQ_EXPORT void + zlog_set_foreground (zlog_t *self, bool foreground); + +// Log error condition - highest priority +CZMQ_EXPORT void + zlog_error (zlog_t *self, const char *format, ...); + +// Log warning condition - high priority +CZMQ_EXPORT void + zlog_warning (zlog_t *self, const char *format, ...); + +// Log normal, but significant, condition - normal priority +CZMQ_EXPORT void + zlog_notice (zlog_t *self, const char *format, ...); + +// Log informational message - low priority +CZMQ_EXPORT void + zlog_info (zlog_t *self, const char *format, ...); + +// Log debug-level message - lowest priority +CZMQ_EXPORT void + zlog_debug (zlog_t *self, const char *format, ...); + +// Self test of this class +CZMQ_EXPORT int + zlog_test (bool verbose); ---- DESCRIPTION @@ -23,7 +61,15 @@ EXAMPLE ---- zlog_t *log = zlog_new ("zlog_test"); assert (log); - zlog_info (log, "%s, %s", "Hello", "World"); + zlog_error (log, "%s", "My pizza was stolen!"); + zlog_warning (log, "%s", "My pizza is late :("); + zlog_notice (log, "%s", "My pizza arrived on time"); + zlog_info (log, "%s", "My pizza smells great!"); + zlog_debug (log, "%s", "My pizza is round and flat"); + if (verbose) { + zlog_set_foreground (log, true); + zlog_notice (log, "%s", "My pizza arrived on time"); + } zlog_destroy (&log); ---- diff --git a/src/zframe.c b/src/zframe.c index 8ef1c6e30..0bbb9b52e 100644 --- a/src/zframe.c +++ b/src/zframe.c @@ -159,8 +159,10 @@ zframe_send (zframe_t **self_p, void *zocket, int flags) zmq_msg_init (©); if (zmq_msg_copy (©, &self->zmsg)) return -1; - if (zmq_sendmsg (zocket, ©, send_flags) == -1) + if (zmq_sendmsg (zocket, ©, send_flags) == -1) { + zmq_msg_close (©); return -1; + } } else { int rc = zmq_sendmsg (zocket, &self->zmsg, send_flags); diff --git a/src/zproxy.c b/src/zproxy.c index 5c2b30ab8..2110d6b9a 100644 --- a/src/zproxy.c +++ b/src/zproxy.c @@ -173,10 +173,13 @@ s_proxy_task (void *args, zctx_t *ctx, void *command_pipe) zmq_msg_t dup; zmq_msg_init (&dup); zmq_msg_copy (&dup, &msg); - zmq_sendmsg (capture, &dup, send_flags); + if (zmq_sendmsg (capture, &dup, send_flags)) + zmq_msg_close (&dup); + } + if (zmq_sendmsg (output, &msg, send_flags) == -1) { + zmq_msg_close (&msg); + break; } - int rc = zmq_sendmsg (output, &msg, send_flags); - assert (rc != -1); if (zmq_recvmsg (which, &msg, ZMQ_DONTWAIT) == -1) break; // Presumably EAGAIN send_flags = zsocket_rcvmore (which)? ZMQ_SNDMORE: 0; diff --git a/src/zsocket.c b/src/zsocket.c index 5fe60aa99..5245dbf1f 100644 --- a/src/zsocket.c +++ b/src/zsocket.c @@ -199,9 +199,9 @@ zsocket_type_str (void *self) // Accepts these flags: ZFRAME_MORE and ZFRAME_DONTWAIT. int -zsocket_sendmem (void *socket, const void *data, size_t size, int flags) +zsocket_sendmem (void *zocket, const void *data, size_t size, int flags) { - assert (socket); + assert (zocket); assert (size == 0 || data); int snd_flags = (flags & ZFRAME_MORE)? ZMQ_SNDMORE : 0; @@ -211,8 +211,12 @@ zsocket_sendmem (void *socket, const void *data, size_t size, int flags) zmq_msg_init_size (&msg, size); memcpy (zmq_msg_data (&msg), data, size); - int rc = zmq_sendmsg (socket, &msg, snd_flags); - return rc == -1? -1: 0; + if (zmq_sendmsg (zocket, &msg, snd_flags) == -1) { + zmq_msg_close (&msg); + return -1; + } + else + return 0; } @@ -226,8 +230,12 @@ zsocket_signal (void *zocket) { zmq_msg_t msg; zmq_msg_init_size (&msg, 0); - int rc = zmq_sendmsg (zocket, &msg, 0); - return rc == -1? -1: 0; + if (zmq_sendmsg (zocket, &msg, 0) == -1) { + zmq_msg_close (&msg); + return -1; + } + else + return 0; } @@ -241,8 +249,10 @@ zsocket_wait (void *zocket) { zmq_msg_t msg; zmq_msg_init (&msg); - int rc = zmq_recvmsg (zocket, &msg, 0); - return rc == -1? -1: 0; + if (zmq_recvmsg (zocket, &msg, 0) == -1) + return -1; + else + return 0; } diff --git a/src/zstr.c b/src/zstr.c index 482dfe53b..0aba9de4f 100644 --- a/src/zstr.c +++ b/src/zstr.c @@ -44,9 +44,12 @@ s_send_string (void *socket, bool more, char *string) zmq_msg_t message; zmq_msg_init_size (&message, len); memcpy (zmq_msg_data (&message), string, len); - int rc = zmq_sendmsg (socket, &message, more? ZMQ_SNDMORE: 0); - - return rc == -1? -1: 0; + if (zmq_sendmsg (socket, &message, more? ZMQ_SNDMORE: 0)) { + zmq_msg_close (&message); + return -1; + } + else + return 0; }