From 8bc96e08cb0c613edc35bcc6c3e8028b4db9e0aa Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 20 Apr 2006 07:06:39 +0000 Subject: - fixed log-to-syslog behavior - added patch against strongswan-2.6.4 --- Source/lib/utils/leak_detective.c | 79 +++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'Source/lib/utils/leak_detective.c') diff --git a/Source/lib/utils/leak_detective.c b/Source/lib/utils/leak_detective.c index 0d90820ee..319f80513 100644 --- a/Source/lib/utils/leak_detective.c +++ b/Source/lib/utils/leak_detective.c @@ -20,7 +20,6 @@ */ #include -#include #include #include #include @@ -31,6 +30,9 @@ #include #include #include +#include +#define __USE_GNU +#include #include "leak_detective.h" @@ -108,13 +110,22 @@ memory_header_t first_header = { * standard hooks, used to temparily remove hooking */ void *old_malloc_hook, *old_realloc_hook, *old_free_hook; +static bool installed = FALSE; /** * Mutex to exclusivly uninstall hooks, access heap list */ -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -void (*__malloc_initialize_hook) (void) = install_hooks; +/** + * Setup leak detective at malloc initialization + */ +void setup_leak_detective() +{ + logger = logger_manager->get_logger(logger_manager, LEAK_DETECT); + install_hooks(); +} +void (*__malloc_initialize_hook) (void) = setup_leak_detective; /** * log stack frames queried by backtrace() @@ -141,13 +152,16 @@ void log_stack_frames(void **stack_frames, int stack_frame_count) */ void install_hooks() { - logger = logger_manager->get_logger(logger_manager, LEAK_DETECT); - old_malloc_hook = __malloc_hook; - old_realloc_hook = __realloc_hook; - old_free_hook = __free_hook; - __malloc_hook = malloc_hook; - __realloc_hook = realloc_hook; - __free_hook = free_hook; + if (!installed) + { + old_malloc_hook = __malloc_hook; + old_realloc_hook = __realloc_hook; + old_free_hook = __free_hook; + __malloc_hook = malloc_hook; + __realloc_hook = realloc_hook; + __free_hook = free_hook; + installed = TRUE; + } } /** @@ -155,8 +169,13 @@ void install_hooks() */ void uninstall_hooks() { - __malloc_hook = old_malloc_hook; - __free_hook = old_free_hook; + if (installed) + { + __malloc_hook = old_malloc_hook; + __free_hook = old_free_hook; + __realloc_hook = old_realloc_hook; + installed = FALSE; + } } /** @@ -270,12 +289,17 @@ void __attribute__ ((destructor)) report_leaks() memory_header_t *hdr; int leaks = 0; + /* reaquire a logger is necessary, this will force ((destructor)) + * order to work correctly */ + logger = logger_manager->get_logger(logger_manager, LEAK_DETECT); + for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) { logger->log(logger, ERROR, "Leak (%d bytes at %p)", hdr->bytes, hdr + 1); log_stack_frames(hdr->stack_frames, hdr->stack_frame_count); leaks++; } + switch (leaks) { case 0: @@ -402,4 +426,35 @@ time_t mktime(struct tm *tm) return result; } +void vsyslog (int __pri, __const char *__fmt, __gnuc_va_list __ap) +{ + void (*_vsyslog) (int __pri, __const char *__fmt, __gnuc_va_list __ap); + void *handle; + + pthread_mutex_lock(&mutex); + uninstall_hooks(); + + handle = dlopen("libc.so.6", RTLD_LAZY); + if (handle == NULL) + { + install_hooks(); + pthread_mutex_unlock(&mutex); + kill(getpid(), SIGSEGV); + } + _vsyslog = dlsym(handle, "vsyslog"); + + if (_vsyslog == NULL) + { + dlclose(handle); + install_hooks(); + pthread_mutex_unlock(&mutex); + kill(getpid(), SIGSEGV); + } + _vsyslog(__pri, __fmt, __ap); + dlclose(handle); + install_hooks(); + pthread_mutex_unlock(&mutex); + return; +} + #endif /* LEAK_DETECTION */ -- cgit v1.2.3