Index: base/debug/stack_trace_unittest.cc |
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc |
index 9abedba6bafd91160989fb718cebc78b4fafbdf6..b68fd589b0960519552b42006fd57bc6bef8cc94 100644 |
--- a/base/debug/stack_trace_unittest.cc |
+++ b/base/debug/stack_trace_unittest.cc |
@@ -238,5 +238,47 @@ TEST_F(StackTraceTest, itoa_r) { |
} |
#endif // defined(OS_POSIX) && !defined(OS_ANDROID) |
+#if HAVE_TRACE_STACK_FRAME_POINTERS |
+ |
+template <size_t Depth> |
+void NOINLINE ExpectStackFramePointers(const void** frames, |
+ size_t max_depth) { |
+ code_start: |
+ // Calling __builtin_frame_address() forces compiler to emit |
+ // frame pointers, even if they are not enabled. |
+ EXPECT_NE(nullptr, __builtin_frame_address(0)); |
+ ExpectStackFramePointers<Depth - 1>(frames, max_depth); |
+ |
+ constexpr size_t frame_index = Depth - 1; |
+ const void* frame = frames[frame_index]; |
+ EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index; |
+ EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index; |
+ code_end: return; |
+} |
+ |
+template <> |
+void NOINLINE ExpectStackFramePointers<1>(const void** frames, |
+ size_t max_depth) { |
+ code_start: |
+ // Calling __builtin_frame_address() forces compiler to emit |
+ // frame pointers, even if they are not enabled. |
+ EXPECT_NE(nullptr, __builtin_frame_address(0)); |
+ size_t count = TraceStackFramePointers(frames, max_depth, 0); |
+ ASSERT_EQ(max_depth, count); |
+ |
+ const void* frame = frames[0]; |
+ EXPECT_GE(frame, &&code_start) << "For the top frame"; |
+ EXPECT_LE(frame, &&code_end) << "For the top frame"; |
+ code_end: return; |
+} |
+ |
+TEST_F(StackTraceTest, TraceStackFramePointers) { |
+ constexpr size_t kDepth = 5; |
+ const void* frames[kDepth]; |
+ ExpectStackFramePointers<kDepth>(frames, kDepth); |
+} |
+ |
+#endif // HAVE_TRACE_STACK_FRAME_POINTERS |
+ |
} // namespace debug |
} // namespace base |