aboutsummaryrefslogtreecommitdiffstats
path: root/Source/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'Source/lib/utils')
-rw-r--r--Source/lib/utils/leak_detective.c79
-rw-r--r--Source/lib/utils/logger.c2
-rw-r--r--Source/lib/utils/logger_manager.h4
3 files changed, 70 insertions, 15 deletions
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 <stddef.h>
-#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
@@ -31,6 +30,9 @@
#include <arpa/inet.h>
#include <dlfcn.h>
#include <unistd.h>
+#include <syslog.h>
+#define __USE_GNU
+#include <pthread.h>
#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 */
diff --git a/Source/lib/utils/logger.c b/Source/lib/utils/logger.c
index 546de226b..4e6832243 100644
--- a/Source/lib/utils/logger.c
+++ b/Source/lib/utils/logger.c
@@ -352,7 +352,7 @@ logger_t *logger_create(char *logger_name, log_level_t log_level, bool log_threa
if (output == NULL)
{
- openlog(DAEMON_NAME, 0, LOG_DAEMON);
+ //openlog(DAEMON_NAME, 0, LOG_DAEMON);
}
return (logger_t*)this;
diff --git a/Source/lib/utils/logger_manager.h b/Source/lib/utils/logger_manager.h
index 24806b80f..074dd744a 100644
--- a/Source/lib/utils/logger_manager.h
+++ b/Source/lib/utils/logger_manager.h
@@ -27,7 +27,7 @@
#include <utils/logger.h>
-#define INITIAL_LOG_OUTPUT stderr
+#define INITIAL_LOG_OUTPUT stdout
typedef enum logger_context_t logger_context_t;
@@ -77,7 +77,7 @@ typedef struct logger_manager_t logger_manager_t;
* library start and destroyed at exit.
*
* @b Constructors:
- * - none, logger_manager is an instance
+ * - none, logger_manager is the single instance
*
* @see logger_t
*