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..6ddef62a25219bd3dd1f61c39fd1423cabc41da5 100644 |
--- a/base/debug/stack_trace_posix.cc |
+++ b/base/debug/stack_trace_posix.cc |
@@ -743,6 +743,45 @@ 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_initial) { |
+ uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)); |
Nico
2016/04/18 19:42:05
nit: call this sp
Dmitry Skiba
2016/04/20 16:32:56
Done.
|
+ |
+ size_t depth = 0; |
+ while (fp && depth < max_depth) { |
+ if (skip_initial != 0) { |
+ skip_initial--; |
+ } else { |
+ out_trace[depth++] = reinterpret_cast<const void**>(fp)[1]; |
Nico
2016/04/18 19:42:05
you treat fp as void** almost everywhere, consider
Primiano Tucci (use gerrit)
2016/04/18 20:18:07
the frame pointer can be invalid even at this stag
Dmitry Skiba
2016/04/20 16:32:56
Hmm, since I don't have next_fp at that point, I c
Dmitry Skiba
2016/04/20 16:32:56
So we have these casts:
reinterpret_cast<uintptr_
|
+ } |
+ |
+ // Find out next frame pointer |
+ // (heuristics are from TCMalloc's stacktrace functions) |
+ { |
Primiano Tucci (use gerrit)
2016/04/18 20:18:08
why this is inside a scope? Is there an if missing
Dmitry Skiba
2016/04/20 16:32:56
Done.
|
+ 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; |
Primiano Tucci (use gerrit)
2016/04/18 20:18:08
I think these checks should happen before you dere
Dmitry Skiba
2016/04/20 16:32:56
But this also dereferences fp, next_fp is fp[1].
|
+ |
+ // 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; |
+ |
+ fp = next_fp; |
+ } |
+ } |
+ |
+ return depth; |
+} |
+ |
+#endif // HAVE_TRACE_STACK_FRAME_POINTERS |
+ |
namespace internal { |
// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. |