| Index: base/debug/stack_trace.cc
|
| diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
|
| index ac0ead76be2b1cf62339e55fa20b59f6488acbe9..775e54f7cd5118941d46b7c3c40b6a4d1c8bd1e9 100644
|
| --- a/base/debug/stack_trace.cc
|
| +++ b/base/debug/stack_trace.cc
|
| @@ -7,16 +7,25 @@
|
| #include <string.h>
|
|
|
| #include <algorithm>
|
| +#include <limits>
|
| #include <sstream>
|
|
|
| #include "base/macros.h"
|
|
|
| -#if HAVE_TRACE_STACK_FRAME_POINTERS && defined(OS_ANDROID)
|
| +#if HAVE_TRACE_STACK_FRAME_POINTERS
|
| +
|
| +#if defined(OS_LINUX) || defined(OS_ANDROID)
|
| #include <pthread.h>
|
| #include "base/process/process_handle.h"
|
| #include "base/threading/platform_thread.h"
|
| #endif
|
|
|
| +#if defined(OS_LINUX) && defined(__GLIBC__)
|
| +extern "C" void* __libc_stack_end;
|
| +#endif
|
| +
|
| +#endif // HAVE_TRACE_STACK_FRAME_POINTERS
|
| +
|
| namespace base {
|
| namespace debug {
|
|
|
| @@ -47,9 +56,8 @@ std::string StackTrace::ToString() const {
|
|
|
| #if HAVE_TRACE_STACK_FRAME_POINTERS
|
|
|
| -#if defined(OS_ANDROID)
|
| -
|
| static 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.
|
| @@ -58,7 +66,6 @@ static uintptr_t GetStackEnd() {
|
| 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;
|
| }
|
| @@ -81,9 +88,25 @@ static uintptr_t GetStackEnd() {
|
| main_stack_end = stack_end;
|
| }
|
| return stack_end;
|
| -}
|
|
|
| -#endif // defined(OS_ANDROID)
|
| +#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 stack end for non-main threads, see crbug.com/617730.
|
| +
|
| +#else
|
| +
|
| + // TODO(dskiba): support Windows, macOS
|
| +
|
| +#endif
|
| +
|
| + // Couldn't get end of stack address.
|
| + return std::numeric_limits<uintptr_t>::max();
|
| +}
|
|
|
| size_t TraceStackFramePointers(const void** out_trace,
|
| size_t max_depth,
|
| @@ -93,9 +116,7 @@ size_t TraceStackFramePointers(const void** out_trace,
|
| // be valid.
|
| uintptr_t sp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
|
|
|
| -#if defined(OS_ANDROID)
|
| uintptr_t stack_end = GetStackEnd();
|
| -#endif
|
|
|
| size_t depth = 0;
|
| while (depth < max_depth) {
|
| @@ -106,12 +127,10 @@ size_t TraceStackFramePointers(const void** out_trace,
|
| sp -= sizeof(uintptr_t);
|
| #endif
|
|
|
| -#if defined(OS_ANDROID)
|
| // Both sp[0] and s[1] must be valid.
|
| if (sp + 2 * sizeof(uintptr_t) > stack_end) {
|
| break;
|
| }
|
| -#endif
|
|
|
| if (skip_initial != 0) {
|
| skip_initial--;
|
|
|