diff options
author | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 16:36:43 +0000 |
---|---|---|
committer | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 16:36:43 +0000 |
commit | 92b821ad9551602cab1864263c9aee449f6da8fe (patch) | |
tree | 85c5594cefae66388f0e0d9f07f3d1ff0c295229 /base | |
parent | 4d8532f9b7db6405ab525f411eeaede1a334afc0 (diff) | |
download | chromium_src-92b821ad9551602cab1864263c9aee449f6da8fe.zip chromium_src-92b821ad9551602cab1864263c9aee449f6da8fe.tar.gz chromium_src-92b821ad9551602cab1864263c9aee449f6da8fe.tar.bz2 |
Get a backtrace in Chrome for Android.
BUG=229352
R=digit@chromium.org, digit@google.com, willchan@chromium.org
Review URL: https://codereview.chromium.org/14646012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198128 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/debug/stack_trace_android.cc | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/base/debug/stack_trace_android.cc b/base/debug/stack_trace_android.cc index d71d246..050a2d8 100644 --- a/base/debug/stack_trace_android.cc +++ b/base/debug/stack_trace_android.cc @@ -7,6 +7,7 @@ #include <signal.h> #include <sys/types.h> #include <unistd.h> +#include <unwind.h> // TODO(dmikurube): Remove. See http://crbug.com/236855. #include "base/logging.h" @@ -15,6 +16,59 @@ #define SIGSTKFLT SIGSEGV #endif +// TODO(dmikurube): Remove when Bionic's get_backtrace() gets popular. +// See http://crbug.com/236855. +namespace { + +/* depends how the system includes define this */ +#ifdef HAVE_UNWIND_CONTEXT_STRUCT +typedef struct _Unwind_Context __unwind_context; +#else +typedef _Unwind_Context __unwind_context; +#endif + +struct stack_crawl_state_t { + uintptr_t* frames; + size_t frame_count; + size_t max_depth; + bool have_skipped_self; + + stack_crawl_state_t(uintptr_t* frames, size_t max_depth) + : frames(frames), + frame_count(0), + max_depth(max_depth), + have_skipped_self(false) { + } +}; + +static _Unwind_Reason_Code tracer(__unwind_context* context, void* arg) { + stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg); + +#if defined(__clang__) + // Vanilla Clang's unwind.h doesn't have _Unwind_GetIP for ARM. + // See http://crbug.com/236855, too. + uintptr_t ip = 0; + _Unwind_VRS_Get(context, _UVRSC_CORE, 15, _UVRSD_UINT32, &ip); + ip &= ~(uintptr_t)0x1; // remove thumb mode bit +#else + uintptr_t ip = _Unwind_GetIP(context); +#endif + + // The first stack frame is this function itself. Skip it. + if (ip != 0 && !state->have_skipped_self) { + state->have_skipped_self = true; + return _URC_NO_REASON; + } + + state->frames[state->frame_count++] = ip; + if (state->frame_count >= state->max_depth) + return _URC_END_OF_STACK; + else + return _URC_NO_REASON; +} + +} // namespace + namespace base { namespace debug { @@ -31,6 +85,12 @@ bool EnableInProcessStackDumping() { } StackTrace::StackTrace() { + // TODO(dmikurube): Replace it with Bionic's get_backtrace(). + // See http://crbug.com/236855. + stack_crawl_state_t state(reinterpret_cast<uintptr_t*>(trace_), kMaxTraces); + _Unwind_Backtrace(tracer, &state); + count_ = state.frame_count; + // TODO(dmikurube): Symbolize in Chrome. } // Sends fake SIGSTKFLT signals to let the Android linker and debuggerd dump |