From b4be616900ff4a10c6f37c66a4d1e9862d88db6f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Sep 2009 23:54:23 +0200 Subject: redirect backtrace() so that we don't enter an endless loop if the user calls backtrace() himself --- mutrace.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/mutrace.c b/mutrace.c index a5c521a..fb0b435 100644 --- a/mutrace.c +++ b/mutrace.c @@ -103,6 +103,9 @@ static int (*real_pthread_create)(pthread_t *newthread, const pthread_attr_t *at static void (*real_exit)(int status) __attribute__((noreturn)) = NULL; static void (*real__exit)(int status) __attribute__((noreturn)) = NULL; static void (*real__Exit)(int status) __attribute__((noreturn)) = NULL; +static int (*real_backtrace)(void **array, int size) = NULL; +static char **(*real_backtrace_symbols)(void *const *array, int size) = NULL; +static void (*real_backtrace_symbols_fd)(void *const *array, int size, int fd) = NULL; static struct mutex_info **alive_mutexes = NULL, **dead_mutexes = NULL; static pthread_mutex_t *mutexes_lock = NULL; @@ -211,6 +214,10 @@ static void load_functions(void) { LOAD_FUNC(_exit); LOAD_FUNC(_Exit); + LOAD_FUNC(backtrace); + LOAD_FUNC(backtrace_symbols); + LOAD_FUNC(backtrace_symbols_fd); + loaded = true; recursive = false; } @@ -587,10 +594,10 @@ static char* generate_stacktrace(void) { buffer = malloc(sizeof(void*) * frames_max); assert(buffer); - n = backtrace(buffer, frames_max); + n = real_backtrace(buffer, frames_max); assert(n >= 0); - strings = backtrace_symbols(buffer, n); + strings = real_backtrace_symbols(buffer, n); assert(strings); free(buffer); @@ -967,3 +974,39 @@ int pthread_create(pthread_t *newthread, return real_pthread_create(newthread, attr, start_routine, arg); } + +int backtrace(void **array, int size) { + int r; + + load_functions(); + + /* backtrace() internally uses a mutex. To avoid an endless + * loop we need to disable ourselves so that we don't try to + * call backtrace() ourselves when looking at that lock. */ + + recursive = true; + r = real_backtrace(array, size); + recursive = false; + + return r; +} + +char **backtrace_symbols(void *const *array, int size) { + char **r; + + load_functions(); + + recursive = true; + r = real_backtrace_symbols(array, size); + recursive = false; + + return r; +} + +void backtrace_symbols_fd(void *const *array, int size, int fd) { + load_functions(); + + recursive = true; + real_backtrace_symbols_fd(array, size, fd); + recursive = false; +} -- cgit