diff options
Diffstat (limited to 'libc/bionic/debug_stacktrace.cpp')
-rw-r--r-- | libc/bionic/debug_stacktrace.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/libc/bionic/debug_stacktrace.cpp b/libc/bionic/debug_stacktrace.cpp index fb933e6..5ddc00c 100644 --- a/libc/bionic/debug_stacktrace.cpp +++ b/libc/bionic/debug_stacktrace.cpp @@ -29,12 +29,13 @@ #include "debug_stacktrace.h" #include <dlfcn.h> +#include <inttypes.h> #include <unistd.h> #include <unwind.h> #include <sys/types.h> #include "debug_mapinfo.h" -#include "libc_logging.h" +#include "private/libc_logging.h" /* depends how the system includes define this */ #ifdef HAVE_UNWIND_CONTEXT_STRUCT @@ -80,6 +81,18 @@ struct stack_crawl_state_t { } }; +#if defined(__arm__) && !defined(_Unwind_GetIP) +// Older versions of Clang don't provide a definition of _Unwind_GetIP(), so +// we include an appropriate version of our own. Once we have updated to +// Clang 3.4, this code can be removed. +static __inline__ +uintptr_t _Unwind_GetIP(struct _Unwind_Context *__context) { + uintptr_t __ip = 0; + _Unwind_VRS_Get(__context, _UVRSC_CORE, 15, _UVRSD_UINT32, &__ip); + return __ip & ~0x1; +} +#endif + static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) { stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg); @@ -130,12 +143,12 @@ __LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) { "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); for (size_t i = 0 ; i < frame_count; ++i) { - void* offset = 0; + uintptr_t offset = 0; const char* symbol = NULL; Dl_info info; if (dladdr((void*) frames[i], &info) != 0) { - offset = info.dli_saddr; + offset = reinterpret_cast<uintptr_t>(info.dli_saddr); symbol = info.dli_sname; } @@ -150,13 +163,20 @@ __LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) { char* demangled_symbol = demangle(symbol); const char* best_name = (demangled_symbol != NULL) ? demangled_symbol : symbol; - __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02d pc %08x %s (%s+0x%x)", - i, rel_pc, soname, best_name, frames[i] - (uintptr_t) offset); + __libc_format_log(ANDROID_LOG_ERROR, "libc", + " #%02zd pc %0*" PRIxPTR " %s (%s+%" PRIuPTR ")", + i, + static_cast<int>(2 * sizeof(void*)), rel_pc, + soname, + best_name, frames[i] - offset); free(demangled_symbol); } else { - __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02d pc %08x %s", - i, rel_pc, soname); + __libc_format_log(ANDROID_LOG_ERROR, "libc", + " #%02zd pc %0*" PRIxPTR " %s", + i, + static_cast<int>(2 * sizeof(void*)), rel_pc, + soname); } } } |