Chromium Code Reviews| Index: base/debug/stack_trace_posix.cc |
| diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc |
| index fc3ee14c7b9d60958ad6d6000d94cbc616b6c7df..06edf0a4cb126319e6f02455b9d05a5fb1626841 100644 |
| --- a/base/debug/stack_trace_posix.cc |
| +++ b/base/debug/stack_trace_posix.cc |
| @@ -743,6 +743,52 @@ void StackTrace::OutputToStream(std::ostream* os) const { |
| } |
| #endif |
| +#if HAVE_TRACE_STACK_FRAME_POINTERS |
| + |
| +size_t TraceStackFramePointers(const void** out_trace, |
| + size_t max_depth, |
| + size_t skip_count) { |
| + uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)); |
| + |
| + size_t depth = 0; |
| + while (fp && depth < max_depth) { |
| + if (skip_count != 0) { |
| + skip_count--; |
| + } else { |
| + out_trace[depth++] = reinterpret_cast<const void**>(fp)[1]; |
| + } |
| + |
| + // Find out next frame pointer |
| + // (heuristics are from TCMalloc's stacktrace functions) |
| + { |
| + uintptr_t next_fp = reinterpret_cast<const uintptr_t*>(fp)[0]; |
| + |
| + // With the stack growing downwards, older stack frame must be |
| + // at a greater address that the current one. |
| + if (next_fp <= fp) break; |
| + |
| + // Assume stack frames larger than 100,000 bytes are bogus. |
| + if (next_fp - fp > 100000) break; |
| + |
| + // Check alignment. |
| + if (next_fp & (sizeof(void*) - 1)) break; |
| + |
| +#ifdef __i386__ |
| + // On 64-bit machines, the stack pointer can be very close to |
|
bcwhite
2016/04/13 12:36:24
You say 64-bit but have 32-bit numbers.
Dmitry Skiba
2016/04/15 07:31:56
This code came from TCMalloc's stacktrace_x86-inl.
|
| + // 0xffffffff, so we explicitly check for a pointer into the |
| + // last two pages in the address fpace |
|
bcwhite
2016/04/13 12:36:24
What is special about the last two pages? Should
|
| + if (next_fp >= 0xffffe000) break; |
| +#endif |
| + |
| + fp = next_fp; |
| + } |
| + } |
| + |
| + return depth; |
| +} |
| + |
| +#endif // HAVE_TRACE_STACK_FRAME_POINTERS |
| + |
| namespace internal { |
| // NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. |