From eb031d4013d36f6aef4aba45840762ae8635cc13 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 19 Aug 2009 15:42:34 -0400 Subject: [PATCH] linux: hand-roll a backtrace printer instead of using backtrace_symbols Why? Because backtrace_symbols calls malloc, which you can't do from a signal handler. Face? Palm. --- os/backtrace.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/os/backtrace.c b/os/backtrace.c index 3cfae3e16..a8866882b 100644 --- a/os/backtrace.c +++ b/os/backtrace.c @@ -29,19 +29,28 @@ #include "misc.h" #ifdef HAVE_BACKTRACE +#define _GNU_SOURCE +#include #include void xorg_backtrace(void) { - void *array[32]; /* deeper nesting than this means something's wrong */ + void *array[64]; + char *mod; int size, i; - char **strings; + Dl_info info; ErrorF("\nBacktrace:\n"); - size = backtrace(array, 32); - strings = backtrace_symbols(array, size); - for (i = 0; i < size; i++) - ErrorF("%d: %s\n", i, strings[i]); - free(strings); + size = backtrace(array, 64); + for (i = 0; i < size; i++) { + dladdr(array[i], &info); + mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; + if (info.dli_saddr) + ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod, + info.dli_sname, array[i] - info.dli_saddr, array[i]); + else + ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod, + info.dli_fbase, array[i] - info.dli_fbase, array[i]); + } } #else /* not glibc or glibc < 2.1 */