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. |