diff options
author | Russ Allbery <eagle@eyrie.org> | 2014-01-22 22:45:44 -0800 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2014-01-22 23:11:53 -0800 |
commit | 90e43d44cc3849075d2d95d02c4340bbea1c82b4 (patch) | |
tree | a9f460be7d02535e0030222d269fbe7d1c49fab9 /util | |
parent | 29898b9484a0e90d65cbdf38629f186fc68f7c9c (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.c | 32 |
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; + } } |