Chromium Code Reviews| Index: base/debug/stack_trace.cc |
| diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc |
| index ac0ead76be2b1cf62339e55fa20b59f6488acbe9..e207417786842f50a502b77efb8436f4f1709c82 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); |
| + } else { |
| + // No easy way to get stack end for non-main threads, |
| + // see crbug.com/617730. |
| + return std::numeric_limits<uintptr_t>::max(); |
| + } |
| + |
| +#else |
|
Primiano Tucci (use gerrit)
2016/08/25 11:03:18
if you make this an #endif, you can have a unique
Dmitry Skiba
2016/08/26 19:14:07
Done.
|
| + |
| + // TODO(dskiba): support Windows, macOS |
| + return std::numeric_limits<uintptr_t>::max(); |
| + |
| +#endif |
| +} |
| 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--; |