Index: base/debug/stack_trace.cc |
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc |
index 94ff7d0755ab50a650ebcee9dfbe05ab287972b2..af4a6efc3ed2f60f3b7a04b2f592e9e886726dfc 100644 |
--- a/base/debug/stack_trace.cc |
+++ b/base/debug/stack_trace.cc |
@@ -20,6 +20,10 @@ |
#include "base/threading/platform_thread.h" |
#endif |
+#if defined(OS_MACOSX) |
+#include <pthread.h> |
+#endif |
+ |
#if defined(OS_LINUX) && defined(__GLIBC__) |
extern "C" void* __libc_stack_end; |
#endif |
@@ -42,56 +46,6 @@ constexpr size_t kStackFrameAdjustment = sizeof(uintptr_t); |
constexpr size_t kStackFrameAdjustment = 0; |
#endif |
-// Returns end of the stack, or 0 if we couldn't get it. |
-uintptr_t GetStackEnd() { |
-#if defined(OS_ANDROID) |
- // Bionic reads proc/maps on every call to pthread_getattr_np() when called |
- // from the main thread. So we need to cache end of stack in that case to get |
- // acceptable performance. |
- // For all other threads pthread_getattr_np() is fast enough as it just reads |
- // values from its pthread_t argument. |
- static uintptr_t main_stack_end = 0; |
- |
- bool is_main_thread = GetCurrentProcId() == PlatformThread::CurrentId(); |
- if (is_main_thread && main_stack_end) { |
- return main_stack_end; |
- } |
- |
- uintptr_t stack_begin = 0; |
- size_t stack_size = 0; |
- pthread_attr_t attributes; |
- int error = pthread_getattr_np(pthread_self(), &attributes); |
- if (!error) { |
- error = pthread_attr_getstack( |
- &attributes, |
- reinterpret_cast<void**>(&stack_begin), |
- &stack_size); |
- pthread_attr_destroy(&attributes); |
- } |
- DCHECK(!error); |
- |
- uintptr_t stack_end = stack_begin + stack_size; |
- if (is_main_thread) { |
- main_stack_end = stack_end; |
- } |
- return stack_end; // 0 in case of error |
- |
-#elif defined(OS_LINUX) && defined(__GLIBC__) |
- |
- if (GetCurrentProcId() == PlatformThread::CurrentId()) { |
- // For the main thread we have a shortcut. |
- return reinterpret_cast<uintptr_t>(__libc_stack_end); |
- } |
- |
- // No easy way to get end of the stack for non-main threads, |
- // see crbug.com/617730. |
- |
-#endif |
- |
- // Don't know how to get end of the stack. |
- return 0; |
-} |
- |
uintptr_t GetNextStackFrame(uintptr_t fp) { |
return reinterpret_cast<const uintptr_t*>(fp)[0] - kStackFrameAdjustment; |
} |
@@ -192,6 +146,56 @@ void* LinkStackFrames(void* fpp, void* parent_fp) { |
} // namespace |
+#if HAVE_TRACE_STACK_FRAME_POINTERS |
+uintptr_t GetStackEnd() { |
+#if defined(OS_ANDROID) |
+ // Bionic reads proc/maps on every call to pthread_getattr_np() when called |
+ // from the main thread. So we need to cache end of stack in that case to get |
+ // acceptable performance. |
+ // For all other threads pthread_getattr_np() is fast enough as it just reads |
+ // values from its pthread_t argument. |
+ static uintptr_t main_stack_end = 0; |
+ |
+ bool is_main_thread = GetCurrentProcId() == PlatformThread::CurrentId(); |
+ if (is_main_thread && main_stack_end) { |
+ return main_stack_end; |
+ } |
+ |
+ uintptr_t stack_begin = 0; |
+ size_t stack_size = 0; |
+ pthread_attr_t attributes; |
+ int error = pthread_getattr_np(pthread_self(), &attributes); |
+ if (!error) { |
+ error = pthread_attr_getstack( |
+ &attributes, reinterpret_cast<void**>(&stack_begin), &stack_size); |
+ pthread_attr_destroy(&attributes); |
+ } |
+ DCHECK(!error); |
+ |
+ uintptr_t stack_end = stack_begin + stack_size; |
+ if (is_main_thread) { |
+ main_stack_end = stack_end; |
+ } |
+ return stack_end; // 0 in case of error |
+ |
+#elif defined(OS_LINUX) && defined(__GLIBC__) |
+ |
+ if (GetCurrentProcId() == PlatformThread::CurrentId()) { |
+ // For the main thread we have a shortcut. |
+ return reinterpret_cast<uintptr_t>(__libc_stack_end); |
+ } |
+ |
+// No easy way to get end of the stack for non-main threads, |
+// see crbug.com/617730. |
+#elif defined(OS_MACOSX) |
+ return reinterpret_cast<uintptr_t>(pthread_get_stackaddr_np(pthread_self())); |
+#endif |
+ |
+ // Don't know how to get end of the stack. |
+ return 0; |
+} |
+#endif // HAVE_TRACE_STACK_FRAME_POINTERS |
+ |
StackTrace::StackTrace() : StackTrace(arraysize(trace_)) {} |
StackTrace::StackTrace(const void* const* trace, size_t count) { |