summaryrefslogtreecommitdiffstats
path: root/libcorkscrew/backtrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcorkscrew/backtrace.c')
-rw-r--r--libcorkscrew/backtrace.c31
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);