From 39e99da8fc2c49fe989ef50b040866f735fefd5b Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 27 Apr 2014 10:48:43 +0300 Subject: [PATCH] Use backtrace() in stack tracing for prettier output This commit takes the backtrace() call in use to produce stack trace outputs, plus it gives us x86-64 support for stack trace. --- lib/silcutil/Makefile.ad | 2 -- lib/silcutil/silcmemory.h | 4 --- lib/silcutil/stacktrace.c | 58 +++++++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/lib/silcutil/Makefile.ad b/lib/silcutil/Makefile.ad index b685a75f..a01f94bc 100644 --- a/lib/silcutil/Makefile.ad +++ b/lib/silcutil/Makefile.ad @@ -39,10 +39,8 @@ DIST_SUBDIRS=unix #endif SILC_DIST_CLIENT #endif SILC_DIST_TOOLKIT -#ifdef SILC_DIST_TOOLKIT SILC_DIST_SOURCE = stacktrace.c SILC_DIST_HEADER = stacktrace.h -#endif SILC_DIST_TOOLKIT noinst_LTLIBRARIES = libsilcutil.la diff --git a/lib/silcutil/silcmemory.h b/lib/silcutil/silcmemory.h index 63fc1fc1..9064ed30 100644 --- a/lib/silcutil/silcmemory.h +++ b/lib/silcutil/silcmemory.h @@ -119,10 +119,6 @@ void silc_free(void *ptr); void *silc_memdup(const void *ptr, size_t size); #else -#ifndef SILC_DIST_TOOLKIT -#error "The stack trace is not supported in this distribution" -#endif /* SILC_DIST_TOOLKIT */ - #include "stacktrace.h" #endif /* SILC_STACKTRACE */ diff --git a/lib/silcutil/stacktrace.c b/lib/silcutil/stacktrace.c index 85e5417f..1d244887 100644 --- a/lib/silcutil/stacktrace.c +++ b/lib/silcutil/stacktrace.c @@ -70,9 +70,15 @@ #include "silc.h" #ifdef SILC_STACKTRACE +#if defined(HAVE_BACKTRACE) #include +#endif /* HAVE_BACKTRACE */ #include +#if !defined(__APPLE__) #include +#else +#include +#endif #include static void *st_blocks = NULL; @@ -128,6 +134,46 @@ typedef struct SilcStBlockStruct { #define silc_hexdump(ptr, size, file) \ silc_log_output_hexdump("", "", 0, ptr, size, "") +int silc_st_backtrace(void **stack) +{ +#if defined(HAVE_BACKTRACE) + return backtrace(stack, SILC_ST_DEPTH); +#else + void *fp; + int depth; + asm volatile ("movl %%ebp, %0" : "=r" (fp)); + for (depth = 0; fp; depth++) { + if (depth == SILC_ST_DEPTH) + break; + + /* Get program pointer and frame pointer from this frame */ + stack[depth] = *((void **)(((unsigned char *)fp) + 4)); + fp = *((void **)fp); + } + return depth; +#endif /* HAVE_BACKTRACE */ +} + +char **silc_st_backtrace_symbols(void **stack, int depth) +{ +#if defined(HAVE_BACKTRACE) + return backtrace_symbols(stack, depth); +#else + return NULL; +#endif /* HAVE_BACKTRACE */ +} + +void silc_st_backtrace_symbols_stderr(void **stack, int depth) +{ +#if defined(HAVE_BACKTRACE) + backtrace_symbols_fd(stack, depth, 2); +#else + int i; + for (i = 0; i < depth; i++) + fprintf(stderr, "? [%p]\n", stack[i]); +#endif /* HAVE_BACKTRACE */ +} + void silc_st_abort(SilcStBlock stack, const char *file, int line, char *fmt, ...) { @@ -141,8 +187,8 @@ void silc_st_abort(SilcStBlock stack, const char *file, int line, va_end(va); fprintf(stderr, "----- BACKTRACE -----\n%s:%d:\n", file, line); - btc = backtrace(bt, SILC_ST_DEPTH); - backtrace_symbols_fd(bt, btc, 2); + btc = silc_st_backtrace(bt); + silc_st_backtrace_symbols_stderr(bt, btc); if (stack) { fprintf(stderr, "----- MEMORY TRACE -----\n"); @@ -151,7 +197,7 @@ void silc_st_abort(SilcStBlock stack, const char *file, int line, stack->free_line); fprintf(stderr, "Originally allocated at:\n"); fprintf(stderr, "%s:%d:\n", stack->file, stack->line); - backtrace_symbols_fd(stack->stack, stack->depth, 2); + silc_st_backtrace_symbols(stack->stack, stack->depth); fflush(stderr); if (dump_mem) { @@ -259,8 +305,10 @@ void *silc_st_malloc(size_t size, const char *file, int line) if (pg) { unsigned char *ptr; +#if defined(HAVE_POSIX_MEMALIGN) if (posix_memalign((void *)&ptr, pg, SILC_ST_GET_SIZE_ALIGN(size, pg) + pg)) +#endif /* HAVE_POSIX_MEMALIGN */ return NULL; /* The inaccessible page too will include the allocation information @@ -290,7 +338,7 @@ void *silc_st_malloc(size_t size, const char *file, int line) stack->line = line; stack->size = size; stack->bound = SILC_ST_TOP_BOUND; - stack->depth = backtrace(stack->stack, SILC_ST_DEPTH); + stack->depth = silc_st_backtrace(stack->stack); silc_mutex_lock(lock); @@ -459,7 +507,7 @@ void silc_st_dump(void) } /* Get symbol names */ - syms = backtrace_symbols(stack->stack, stack->depth); + syms = silc_st_backtrace_symbols(stack->stack, stack->depth); /* Find number of leaks and bytes leaked for this leak */ for (s = stack; s; s = s->next) { -- 2.24.0