From 9dd130afb6085e90cb3933a112e04a1867183421 Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Fri, 5 Sep 2014 15:29:32 -0700 Subject: [PATCH] - forget about backtrace_symbols() -- always use 'dladdr'. (The former is non-standard either and AFAIK always based on the latter.) Always using dladdr allows us to precisely control the printout formatting and keep it consistent. --- src/libCom/osi/execinfoStackTrace.c | 83 +++++------------------------ 1 file changed, 12 insertions(+), 71 deletions(-) diff --git a/src/libCom/osi/execinfoStackTrace.c b/src/libCom/osi/execinfoStackTrace.c index 0c8145465..c46e2925a 100644 --- a/src/libCom/osi/execinfoStackTrace.c +++ b/src/libCom/osi/execinfoStackTrace.c @@ -7,7 +7,11 @@ * Author: Till Straumann , 2011, 2014 */ +/* Make sure dladdr() is visible on linux/freebsd/darwin */ #define _GNU_SOURCE +/* Some freebsd versions seem to export dladdr() only if __BSD_VISIBLE */ +#define _BSD_VISIBLE +#define _DARWIN_C_SOURCE #include "epicsStackTrace.h" #include "epicsThread.h" @@ -19,28 +23,22 @@ #include #include +/* How many stack frames to capture */ #define MAXDEPTH 100 +/* How many chars to reserve for a line of output */ +#define MAXSYMLEN 500 + #define STACKTRACE_DEBUG 0 -/* Darwin and GNU have dladdr() but Darwin's backtrace_symbols() - * already prints local symbols, too, whereas linux' does not. +/* Darwin and GNU have dladdr() and Darwin's already finds local + * symbols, too, whereas linux' does not. * Hence, on linux we want to use dladdr() and lookup static * symbols in the ELF symbol table. */ -#ifdef freebsd -/* Some freebsd versions seem to export dladdr() only if __BSD_VISIBLE */ -#define __BSD_VISIBLE 1 -#endif - #include -/* Check if we actually have the gnu/darwin extensions */ -#ifdef RTLD_DEFAULT - -#define USE_DLADDR - #if defined(__linux__) || defined(linux) #define USE_ELF #define USE_MMAP @@ -54,19 +52,12 @@ #include #include -/* How many chars to reserve (on avg) for a line of output */ -#define MAXSYMLEN 500 - #ifdef USE_MMAP #include #endif /* USE_MMAP */ #endif /* USE_ELF */ -#else /* RTLD_DEFAULT */ -#undef USE_ELF -#endif /* RTLD_DEFAULT */ - /* Forward Declaration */ #define NO_OFF ((unsigned long)-1L) @@ -505,8 +496,6 @@ ESyms es; } #endif /* USE_ELF */ -#ifdef USE_DLADDR - static ssize_t elfLookupAddr(void *addr, char *buf, size_t buf_sz) { @@ -640,8 +629,6 @@ size_t idx; return rval; } -#endif /* USE_DLADDR */ - static epicsThreadOnceId stackTraceInitId = EPICS_THREAD_ONCE_INIT; static epicsMutexId stackTraceMtx; @@ -706,12 +693,7 @@ size_t rval = 0; epicsShareFunc void epicsStackTrace(void) { -void **buf; -#ifndef USE_DLADDR -char **bts; -ssize_t pos, siz; -char *ptr; -#endif +void **buf; char *btsl = 0; size_t btsl_sz = sizeof(*btsl)*MAXSYMLEN; int i,n; @@ -732,11 +714,6 @@ int i,n; errlogFlush(); - /* backtrace_symbols() only works for global symbols on linux. - * If we have dladdr() and then we can actually lookup local - * symbols, too. - */ -#ifdef USE_DLADDR for ( i=0; i 0 ) - btsl[--pos] = 0; - siz -= pos; - if ( siz >= 3 ) { - strcat(btsl, ": "); - pos += 2; - siz -= 2; - } - strncat(btsl + pos, bts[i], siz); - /* wipe out the trailing address */ - if ( (ptr = strrchr(btsl, '[')) ) - *ptr = 0; - errlogPrintf("%s\n", btsl); - } - free(bts); - } else { - /* failed to create symbolic information; just print addresses */ - for ( i=0; i