changeset 22512:bcc3a15c18a6

lib: When logging I/O or timeout leak, log also raw backtrace This can be useful when trying to figure out where the io_loop_destroy() was called from.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 08 Aug 2017 20:07:18 +0300
parents f0694e6eda8d
children 59b0c5ee8adf
files src/lib/ioloop.c
diffstat 1 files changed, 12 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/ioloop.c	Tue May 23 14:05:02 2017 +0200
+++ b/src/lib/ioloop.c	Tue Aug 08 20:07:18 2017 +0300
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "backtrace-string.h"
 #include "llist.h"
 #include "time-util.h"
 #include "istream-private.h"
@@ -703,6 +704,7 @@
 	struct ioloop *ioloop = *_ioloop;
 	struct timeout *const *to_idx;
 	struct priorityq_item *item;
+	bool leaks = FALSE;
 
 	*_ioloop = NULL;
 
@@ -722,6 +724,7 @@
 			  io->io.source_filename,
 			  io->io.source_linenum, io->fd);
 		io_remove(&_io);
+		leaks = TRUE;
 	}
 	i_assert(ioloop->io_pending_count == 0);
 
@@ -732,6 +735,7 @@
 			  to->source_filename,
 			  to->source_linenum);
 		timeout_free(to);
+		leaks = TRUE;
 	}
 	array_free(&ioloop->timeouts_new);
 
@@ -742,6 +746,7 @@
 			  to->source_filename,
 			  to->source_linenum);
 		timeout_free(to);
+		leaks = TRUE;
 	}
 	priorityq_deinit(&ioloop->timeouts);
 
@@ -752,6 +757,13 @@
 			  timer->source_filename,
 			  timer->source_linenum);
 		io_wait_timer_remove(&timer);
+		leaks = TRUE;
+	}
+
+	if (leaks) {
+		const char *backtrace;
+		if (backtrace_get(&backtrace) == 0)
+			i_warning("Raw backtrace for leaks: %s", backtrace);
 	}
 
 	if (ioloop->handler_context != NULL)