diff options
Diffstat (limited to 'libcorkscrew/backtrace.c')
-rw-r--r-- | libcorkscrew/backtrace.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/libcorkscrew/backtrace.c b/libcorkscrew/backtrace.c index e57f428..03dbd53 100644 --- a/libcorkscrew/backtrace.c +++ b/libcorkscrew/backtrace.c @@ -27,14 +27,37 @@ #include <unistd.h> #include <signal.h> +#include <stdlib.h> +#include <string.h> #include <pthread.h> #include <unwind.h> -#include <sys/exec_elf.h> #include <cutils/log.h> #include <cutils/atomic.h> +#include <elf.h> -#if HAVE_DLADDR +#define __USE_GNU // For dladdr(3) in glibc. #include <dlfcn.h> + +#if defined(__BIONIC__) + +// Bionic implements and exports gettid but only implements tgkill. +extern int tgkill(int tgid, int tid, int sig); + +#else + +// glibc doesn't implement or export either gettid or tgkill. + +#include <unistd.h> +#include <sys/syscall.h> + +static pid_t gettid() { + return syscall(__NR_gettid); +} + +static int tgkill(int tgid, int tid, int sig) { + return syscall(__NR_tgkill, tgid, tid, sig); +} + #endif typedef struct { @@ -115,8 +138,6 @@ static void unwind_backtrace_thread_signal_handler(int n __attribute__((unused)) } #endif -extern int tgkill(int tgid, int tid, int sig); - ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { if (tid == gettid()) { @@ -233,7 +254,6 @@ void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames, if (mi->name[0]) { symbol->map_name = strdup(mi->name); } -#if HAVE_DLADDR Dl_info info; if (dladdr((const void*)frame->absolute_pc, &info) && info.dli_sname) { symbol->relative_symbol_addr = (uintptr_t)info.dli_saddr @@ -241,7 +261,6 @@ void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames, symbol->symbol_name = strdup(info.dli_sname); symbol->demangled_name = demangle_symbol_name(symbol->symbol_name); } -#endif } } release_my_map_info_list(milist); |