Index: base/debug/stack_trace_android.cc |
diff --git a/base/debug/stack_trace_android.cc b/base/debug/stack_trace_android.cc |
index d71d246da63b68d5c74e910b55590e5ff1217fcb..0ba3be23c1c4f8d7eb5088d73a578e28d5da5745 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 when get_backtrace() is used. |
#include "base/logging.h" |
@@ -15,6 +16,51 @@ |
#define SIGSTKFLT SIGSEGV |
#endif |
+// TODO(dmikurube): Remove when Bionic's get_backtrace() gets popular. |
+// See Bionic's libc/bionic/debug_stacktrace.cpp. |
digit
2013/04/30 16:58:13
Maybe file a bug to track this and put a reference
Dai Mikurube (NOT FULLTIME)
2013/04/30 17:15:23
Done.
|
+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); |
+ |
+ uintptr_t ip = _Unwind_GetIP(context); |
+ |
+ // The first stack frame is get_backtrace itself. Skip it. |
digit
2013/04/30 16:58:13
I'd suggest replacing "get_backtrace" by "this fun
Dai Mikurube (NOT FULLTIME)
2013/04/30 17:15:23
Done.
|
+ 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 base { |
namespace debug { |
@@ -31,6 +77,12 @@ bool EnableInProcessStackDumping() { |
} |
StackTrace::StackTrace() { |
+ // TODO(dmikurube): Replace it with Bionic's get_backtrace(). |
+ // See Bionic's libc/bionic/debug_stacktrace.cpp. |
+ 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 |