Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3837)

Unified Diff: base/debug/stack_trace.cc

Issue 1915593003: Reland of Add function to trace stack using frame pointers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix ARM unwinding on GCC Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/stack_trace.cc
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
index 2250c8fb14cc43b76c9a1236f59722b8317a74a2..1c96a569d9795544231714f0d0b1f9b0da036355 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -39,5 +39,54 @@ std::string StackTrace::ToString() const {
return stream.str();
}
+#if HAVE_TRACE_STACK_FRAME_POINTERS
+
+size_t TraceStackFramePointers(const void** out_trace,
+ size_t max_depth,
+ size_t skip_initial) {
+ // Usage of __builtin_frame_address() enables frame pointers in this
+ // function even if they are not enabled globally. So 'sp' will always
+ // be valid.
+ uintptr_t sp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
+
+ size_t depth = 0;
+ while (depth < max_depth) {
+#if defined(__arm__) && defined(__GNUC__) && !defined(__clang__)
+ // GCC and LLVM generate slightly different frames on ARM, see
+ // https://llvm.org/bugs/show_bug.cgi?id=18505 - LLVM generates
+ // x86-compatible frame, while GCC needs adjustment.
+ sp -= sizeof(uintptr_t);
+#endif
+
+ if (skip_initial != 0) {
+ skip_initial--;
+ } else {
+ out_trace[depth++] = reinterpret_cast<const void**>(sp)[1];
+ }
+
+ // Find out next frame pointer
+ // (heuristics are from TCMalloc's stacktrace functions)
+ {
+ uintptr_t next_sp = reinterpret_cast<const uintptr_t*>(sp)[0];
+
+ // With the stack growing downwards, older stack frame must be
+ // at a greater address that the current one.
+ if (next_sp <= sp) break;
+
+ // Assume stack frames larger than 100,000 bytes are bogus.
+ if (next_sp - sp > 100000) break;
+
+ // Check alignment.
+ if (sp & (sizeof(void*) - 1)) break;
+
+ sp = next_sp;
+ }
+ }
+
+ return depth;
+}
+
+#endif // HAVE_TRACE_STACK_FRAME_POINTERS
+
} // namespace debug
} // namespace base
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698