summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2014-01-22 22:45:44 -0800
committerRuss Allbery <rra@stanford.edu>2014-01-22 23:11:53 -0800
commit90e43d44cc3849075d2d95d02c4340bbea1c82b4 (patch)
treea9f460be7d02535e0030222d269fbe7d1c49fab9 /util
parent29898b9484a0e90d65cbdf38629f186fc68f7c9c (diff)
Free our message handlers on exit with an atexit function
When setting custom message handlers, we allocate memory and stash it in a static variable. For easier valgrind analysis, free that memory on process exit with an atexit function. Change-Id: I0a49ebce5a955a7395697e00a53fadafaf1f8293 Reviewed-on: https://gerrit.stanford.edu/1403 Reviewed-by: Russ Allbery <rra@stanford.edu> Tested-by: Russ Allbery <rra@stanford.edu>
Diffstat (limited to 'util')
-rw-r--r--util/messages.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/util/messages.c b/util/messages.c
index 769166f..c08e222 100644
--- a/util/messages.c
+++ b/util/messages.c
@@ -113,6 +113,9 @@ static message_handler_func *notice_handlers = stdout_handlers;
static message_handler_func *warn_handlers = stderr_handlers;
static message_handler_func *die_handlers = stderr_handlers;
+/* Whether our atexit handler to free the logging functions is registered. */
+static bool free_handlers_registered = false;
+
/* If non-NULL, called before exit and its return value passed to exit. */
int (*message_fatal_cleanup)(void) = NULL;
@@ -121,6 +124,31 @@ const char *message_program_name = NULL;
/*
+ * Free all of the handlers and set them back to the defaults. Normally, this
+ * is only called on exit. Doing that isn't necessary, but it frees reachable
+ * memory and allows for comprehensive memory allocation analysis.
+ */
+static void
+message_handlers_free(void)
+{
+ free(debug_handlers);
+ debug_handlers = NULL;
+ if (notice_handlers != stdout_handlers) {
+ free(notice_handlers);
+ notice_handlers = stdout_handlers;
+ }
+ if (warn_handlers != stderr_handlers) {
+ free(warn_handlers);
+ warn_handlers = stderr_handlers;
+ }
+ if (die_handlers != stderr_handlers) {
+ free(die_handlers);
+ die_handlers = stderr_handlers;
+ }
+}
+
+
+/*
* Set the handlers for a particular message function. Takes a pointer to the
* handler list, the count of handlers, and the argument list.
*/
@@ -135,6 +163,10 @@ message_handlers(message_handler_func **list, unsigned int count, va_list args)
for (i = 0; i < count; i++)
(*list)[i] = (message_handler_func) va_arg(args, message_handler_func);
(*list)[count] = NULL;
+ if (!free_handlers_registered) {
+ atexit(message_handlers_free);
+ free_handlers_registered = true;
+ }
}