Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: third_party/tcmalloc/chromium/src/stacktrace_android-inl.h

Issue 14321006: Adds TCMalloc support for Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Always use phtread_once Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/tcmalloc/chromium/src/stacktrace_android-inl.h
diff --git a/third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_android-inl.h
similarity index 54%
copy from third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h
copy to third_party/tcmalloc/chromium/src/stacktrace_android-inl.h
index 82b0cfeb7aee7db0a2d7c96ce7c6769b23c32f3e..1f04bc9de27b31ea5b697f79de3743b86bae733f 100644
--- a/third_party/tcmalloc/chromium/src/stacktrace_libunwind-inl.h
+++ b/third_party/tcmalloc/chromium/src/stacktrace_android-inl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2005, Google Inc.
+// Copyright (c) 2013, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -28,36 +28,76 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
-// Author: Arun Sharma
+// Author: Marcus Bulach
+// This is inspired by Doug Kwan's ARM's stacktrace code and Dai Mikurube's
+// stack trace for chromium on android.
//
-// Produce stack trace using libunwind
-#ifndef BASE_STACKTRACE_LIBINWIND_INL_H_
-#define BASE_STACKTRACE_LIBINWIND_INL_H_
+#ifndef BASE_STACKTRACE_ANDROID_INL_H_
+#define BASE_STACKTRACE_ANDROID_INL_H_
// Note: this file is included into stacktrace.cc more than once.
// Anything that should only be defined once should be here:
-// We only need local unwinder.
-#define UNW_LOCAL_ONLY
+#include <stdint.h> // for uintptr_t
+// See http://crbug.com/236855, would be better to use Bionic's
+// new get_backtrace().
+#include <unwind.h>
-extern "C" {
-#include <assert.h>
-#include <string.h> // for memset()
-#include <libunwind.h>
-}
-#include "gperftools/stacktrace.h"
-#include "base/logging.h"
+/* Depends on the system definition for _Unwind_Context */
+#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;
+ int max_depth;
+ int skip_count;
+ bool have_skipped_self;
+
+ stack_crawl_state_t(uintptr_t* frames, int max_depth, int skip_count)
+ : frames(frames),
+ frame_count(0),
+ max_depth(max_depth),
+ skip_count(skip_count),
+ 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;
+ }
+
+ if (state->skip_count) {
+ --state->skip_count;
+ return _URC_NO_REASON;
+ }
-// Sometimes, we can try to get a stack trace from within a stack
-// trace, because libunwind can call mmap (maybe indirectly via an
-// internal mmap based memory allocator), and that mmap gets trapped
-// and causes a stack-trace request. If were to try to honor that
-// recursive request, we'd end up with infinite recursion or deadlock.
-// Luckily, it's safe to ignore those subsequent traces. In such
-// cases, we return 0 to indicate the situation.
-static __thread int recursive;
+ state->frames[state->frame_count++] = ip;
+ if (state->frame_count >= state->max_depth)
+ return _URC_END_OF_STACK;
+ else
+ return _URC_NO_REASON;
+}
-#endif // BASE_STACKTRACE_LIBINWIND_INL_H_
+#endif // BASE_STACKTRACE_ANDROID_INL_H_
// Note: this part of the file is included several times.
// Do not put globals below.
@@ -74,55 +114,8 @@ static __thread int recursive;
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
int GET_STACK_TRACE_OR_FRAMES {
- void *ip;
- int n = 0;
- unw_cursor_t cursor;
- unw_context_t uc;
-#if IS_STACK_FRAMES
- unw_word_t sp = 0, next_sp = 0;
-#endif
-
- if (recursive) {
- return 0;
- }
- ++recursive;
-
- unw_getcontext(&uc);
- int ret = unw_init_local(&cursor, &uc);
- assert(ret >= 0);
- skip_count++; // Do not include current frame
-
- while (skip_count--) {
- if (unw_step(&cursor) <= 0) {
- goto out;
- }
-#if IS_STACK_FRAMES
- if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {
- goto out;
- }
-#endif
- }
-
- while (n < max_depth) {
- if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {
- break;
- }
-#if IS_STACK_FRAMES
- sizes[n] = 0;
-#endif
- result[n++] = ip;
- if (unw_step(&cursor) <= 0) {
- break;
- }
-#if IS_STACK_FRAMES
- sp = next_sp;
- if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp) , 0) {
- break;
- }
- sizes[n - 1] = next_sp - sp;
-#endif
- }
-out:
- --recursive;
- return n;
+ stack_crawl_state_t state(
+ reinterpret_cast<uintptr_t*>(result), max_depth, skip_count);
+ _Unwind_Backtrace(tracer, &state);
+ return state.frame_count;
}
« no previous file with comments | « third_party/tcmalloc/chromium/src/profiler.cc ('k') | third_party/tcmalloc/chromium/src/stacktrace_config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698