dovecot-2.1: ioloop: I/O and timeout leak messages now include t...

dovecot at dovecot.org dovecot at dovecot.org
Wed Feb 1 22:04:32 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/0308a33d9f99
changeset: 14045:0308a33d9f99
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Feb 01 22:04:26 2012 +0200
description:
ioloop: I/O and timeout leak messages now include the io_add()/timeout_add() source line number.
This helps figuring out the leak especially when using ASLR. Also in 64bit
systems there's no increased memory usage, because the line number replaces
only padding.

diffstat:

 src/lib/ioloop-private.h |   2 ++
 src/lib/ioloop.c         |  18 +++++++++++++-----
 src/lib/ioloop.h         |   9 +++++----
 3 files changed, 20 insertions(+), 9 deletions(-)

diffs (123 lines):

diff -r e3c4a86fb63b -r 0308a33d9f99 src/lib/ioloop-private.h
--- a/src/lib/ioloop-private.h	Wed Feb 01 21:27:45 2012 +0200
+++ b/src/lib/ioloop-private.h	Wed Feb 01 22:04:26 2012 +0200
@@ -29,6 +29,7 @@
 
 struct io {
 	enum io_condition condition;
+	unsigned int source_linenum;
 
 	io_callback_t *callback;
         void *context;
@@ -49,6 +50,7 @@
 
 struct timeout {
 	struct priorityq_item item;
+	unsigned int source_linenum;
 
         unsigned int msecs;
 	struct timeval next_run;
diff -r e3c4a86fb63b -r 0308a33d9f99 src/lib/ioloop.c
--- a/src/lib/ioloop.c	Wed Feb 01 21:27:45 2012 +0200
+++ b/src/lib/ioloop.c	Wed Feb 01 22:04:26 2012 +0200
@@ -29,6 +29,7 @@
 
 #undef io_add
 struct io *io_add(int fd, enum io_condition condition,
+		  unsigned int source_linenum,
 		  io_callback_t *callback, void *context)
 {
 	struct io_file *io;
@@ -42,6 +43,7 @@
 	io->io.callback = callback;
         io->io.context = context;
 	io->io.ioloop = current_ioloop;
+	io->io.source_linenum = source_linenum;
 	io->refcount = 1;
 	io->fd = fd;
 
@@ -139,12 +141,13 @@
 }
 
 #undef timeout_add
-struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback,
-			    void *context)
+struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum,
+			    timeout_callback_t *callback, void *context)
 {
 	struct timeout *timeout;
 
 	timeout = i_new(struct timeout, 1);
+        timeout->source_linenum = source_linenum;
         timeout->msecs = msecs;
 	timeout->ioloop = current_ioloop;
 
@@ -459,14 +462,17 @@
 		struct io_file *io = ioloop->io_files;
 		struct io *_io = &io->io;
 
-		i_warning("I/O leak: %p (%d)", (void *)io->io.callback, io->fd);
+		i_warning("I/O leak: %p (line %u, fd %d)",
+			  (void *)io->io.callback,
+			  io->io.source_linenum, io->fd);
 		io_remove(&_io);
 	}
 
 	while ((item = priorityq_pop(ioloop->timeouts)) != NULL) {
 		struct timeout *to = (struct timeout *)item;
 
-		i_warning("Timeout leak: %p", (void *)to->callback);
+		i_warning("Timeout leak: %p (line %u)", (void *)to->callback,
+			  to->source_linenum);
 		timeout_free(to);
 	}
 	priorityq_deinit(&ioloop->timeouts);
@@ -627,6 +633,7 @@
 
 	old_io_file = (struct io_file *)old_io;
 	new_io = io_add(old_io_file->fd, old_io->condition,
+			old_io->source_linenum,
 			old_io->callback, old_io->context);
 	io_remove(_io);
 	return new_io;
@@ -639,7 +646,8 @@
 	if (old_to->ioloop == current_ioloop)
 		return old_to;
 
-	new_to = timeout_add(old_to->msecs, old_to->callback, old_to->context);
+	new_to = timeout_add(old_to->msecs, old_to->source_linenum,
+			     old_to->callback, old_to->context);
 	timeout_remove(_timeout);
 	return new_to;
 }
diff -r e3c4a86fb63b -r 0308a33d9f99 src/lib/ioloop.h
--- a/src/lib/ioloop.h	Wed Feb 01 21:27:45 2012 +0200
+++ b/src/lib/ioloop.h	Wed Feb 01 22:04:26 2012 +0200
@@ -46,10 +46,11 @@
    Don't try to add multiple handlers for the same type. It's not checked and
    the behavior will be undefined. */
 struct io *io_add(int fd, enum io_condition condition,
+		  unsigned int source_linenum,
 		  io_callback_t *callback, void *context);
 #define io_add(fd, condition, callback, context) \
 	CONTEXT_CALLBACK(io_add, io_callback_t, \
-			 callback, context, fd, condition)
+			 callback, context, fd, condition, __LINE__)
 enum io_notify_result io_add_notify(const char *path, io_callback_t *callback,
 				    void *context, struct io **io_r);
 #ifdef CONTEXT_TYPE_SAFETY
@@ -68,11 +69,11 @@
 void io_remove_closed(struct io **io);
 
 /* Timeout handlers */
-struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback,
-			    void *context);
+struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum,
+			    timeout_callback_t *callback, void *context);
 #define timeout_add(msecs, callback, context) \
 	CONTEXT_CALLBACK(timeout_add, timeout_callback_t, \
-			 callback, context, msecs)
+			 callback, context, msecs, __LINE__)
 /* Remove timeout handler, and set timeout pointer to NULL. */
 void timeout_remove(struct timeout **timeout);
 /* Reset timeout so it's next run after now+msecs. */


More information about the dovecot-cvs mailing list