xref: /aosp_15_r20/external/libchrome/base/debug/stack_trace_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <limits>
8*635a8641SAndroid Build Coastguard Worker #include <sstream>
9*635a8641SAndroid Build Coastguard Worker #include <string>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/debug/debugging_buildflags.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/process/kill.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/process/process_handle.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
17*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
18*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
19*635a8641SAndroid Build Coastguard Worker #include "testing/multiprocess_func_list.h"
20*635a8641SAndroid Build Coastguard Worker 
21*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
22*635a8641SAndroid Build Coastguard Worker #include "base/test/multiprocess_test.h"
23*635a8641SAndroid Build Coastguard Worker #endif
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker namespace base {
26*635a8641SAndroid Build Coastguard Worker namespace debug {
27*635a8641SAndroid Build Coastguard Worker 
28*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
29*635a8641SAndroid Build Coastguard Worker typedef MultiProcessTest StackTraceTest;
30*635a8641SAndroid Build Coastguard Worker #else
31*635a8641SAndroid Build Coastguard Worker typedef testing::Test StackTraceTest;
32*635a8641SAndroid Build Coastguard Worker #endif
33*635a8641SAndroid Build Coastguard Worker 
34*635a8641SAndroid Build Coastguard Worker // Note: On Linux, this test currently only fully works on Debug builds.
35*635a8641SAndroid Build Coastguard Worker // See comments in the #ifdef soup if you intend to change this.
36*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
37*635a8641SAndroid Build Coastguard Worker // Always fails on Windows: crbug.com/32070
38*635a8641SAndroid Build Coastguard Worker #define MAYBE_OutputToStream DISABLED_OutputToStream
39*635a8641SAndroid Build Coastguard Worker #else
40*635a8641SAndroid Build Coastguard Worker #define MAYBE_OutputToStream OutputToStream
41*635a8641SAndroid Build Coastguard Worker #endif
42*635a8641SAndroid Build Coastguard Worker #if !defined(__UCLIBC__) && !defined(_AIX)
TEST_F(StackTraceTest,MAYBE_OutputToStream)43*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, MAYBE_OutputToStream) {
44*635a8641SAndroid Build Coastguard Worker   StackTrace trace;
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker   // Dump the trace into a string.
47*635a8641SAndroid Build Coastguard Worker   std::ostringstream os;
48*635a8641SAndroid Build Coastguard Worker   trace.OutputToStream(&os);
49*635a8641SAndroid Build Coastguard Worker   std::string backtrace_message = os.str();
50*635a8641SAndroid Build Coastguard Worker 
51*635a8641SAndroid Build Coastguard Worker   // ToString() should produce the same output.
52*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(backtrace_message, trace.ToString());
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
55*635a8641SAndroid Build Coastguard Worker   // Stack traces require an extra data table that bloats our binaries,
56*635a8641SAndroid Build Coastguard Worker   // so they're turned off for release builds.  We stop the test here,
57*635a8641SAndroid Build Coastguard Worker   // at least letting us verify that the calls don't crash.
58*635a8641SAndroid Build Coastguard Worker   return;
59*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   size_t frames_found = 0;
62*635a8641SAndroid Build Coastguard Worker   trace.Addresses(&frames_found);
63*635a8641SAndroid Build Coastguard Worker   ASSERT_GE(frames_found, 5u) <<
64*635a8641SAndroid Build Coastguard Worker       "No stack frames found.  Skipping rest of test.";
65*635a8641SAndroid Build Coastguard Worker 
66*635a8641SAndroid Build Coastguard Worker   // Check if the output has symbol initialization warning.  If it does, fail.
67*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
68*635a8641SAndroid Build Coastguard Worker             std::string::npos) <<
69*635a8641SAndroid Build Coastguard Worker       "Unable to resolve symbols.  Skipping rest of test.";
70*635a8641SAndroid Build Coastguard Worker 
71*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
72*635a8641SAndroid Build Coastguard Worker #if 0
73*635a8641SAndroid Build Coastguard Worker   // Disabled due to -fvisibility=hidden in build config.
74*635a8641SAndroid Build Coastguard Worker 
75*635a8641SAndroid Build Coastguard Worker   // Symbol resolution via the backtrace_symbol function does not work well
76*635a8641SAndroid Build Coastguard Worker   // in OS X.
77*635a8641SAndroid Build Coastguard Worker   // See this thread:
78*635a8641SAndroid Build Coastguard Worker   //
79*635a8641SAndroid Build Coastguard Worker   //    http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html
80*635a8641SAndroid Build Coastguard Worker   //
81*635a8641SAndroid Build Coastguard Worker   // Just check instead that we find our way back to the "start" symbol
82*635a8641SAndroid Build Coastguard Worker   // which should be the first symbol in the trace.
83*635a8641SAndroid Build Coastguard Worker   //
84*635a8641SAndroid Build Coastguard Worker   // TODO(port): Find a more reliable way to resolve symbols.
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker   // Expect to at least find main.
87*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(backtrace_message.find("start") != std::string::npos)
88*635a8641SAndroid Build Coastguard Worker       << "Expected to find start in backtrace:\n"
89*635a8641SAndroid Build Coastguard Worker       << backtrace_message;
90*635a8641SAndroid Build Coastguard Worker 
91*635a8641SAndroid Build Coastguard Worker #endif
92*635a8641SAndroid Build Coastguard Worker #elif defined(USE_SYMBOLIZE)
93*635a8641SAndroid Build Coastguard Worker   // This branch is for gcc-compiled code, but not Mac due to the
94*635a8641SAndroid Build Coastguard Worker   // above #if.
95*635a8641SAndroid Build Coastguard Worker   // Expect a demangled symbol.
96*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") !=
97*635a8641SAndroid Build Coastguard Worker               std::string::npos)
98*635a8641SAndroid Build Coastguard Worker       << "Expected a demangled symbol in backtrace:\n"
99*635a8641SAndroid Build Coastguard Worker       << backtrace_message;
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker #elif 0
102*635a8641SAndroid Build Coastguard Worker   // This is the fall-through case; it used to cover Windows.
103*635a8641SAndroid Build Coastguard Worker   // But it's disabled because of varying buildbot configs;
104*635a8641SAndroid Build Coastguard Worker   // some lack symbols.
105*635a8641SAndroid Build Coastguard Worker 
106*635a8641SAndroid Build Coastguard Worker   // Expect to at least find main.
107*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
108*635a8641SAndroid Build Coastguard Worker       << "Expected to find main in backtrace:\n"
109*635a8641SAndroid Build Coastguard Worker       << backtrace_message;
110*635a8641SAndroid Build Coastguard Worker 
111*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
112*635a8641SAndroid Build Coastguard Worker // MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with
113*635a8641SAndroid Build Coastguard Worker // MSVC's __FUNCTION__ macro.
114*635a8641SAndroid Build Coastguard Worker #define __func__ __FUNCTION__
115*635a8641SAndroid Build Coastguard Worker #endif
116*635a8641SAndroid Build Coastguard Worker 
117*635a8641SAndroid Build Coastguard Worker   // Expect to find this function as well.
118*635a8641SAndroid Build Coastguard Worker   // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
119*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
120*635a8641SAndroid Build Coastguard Worker       << "Expected to find " << __func__ << " in backtrace:\n"
121*635a8641SAndroid Build Coastguard Worker       << backtrace_message;
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker #endif  // define(OS_MACOSX)
124*635a8641SAndroid Build Coastguard Worker }
125*635a8641SAndroid Build Coastguard Worker 
126*635a8641SAndroid Build Coastguard Worker #if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
127*635a8641SAndroid Build Coastguard Worker // Disabled in Official builds, where Link-Time Optimization can result in two
128*635a8641SAndroid Build Coastguard Worker // or fewer stack frames being available, causing the test to fail.
TEST_F(StackTraceTest,TruncatedTrace)129*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, TruncatedTrace) {
130*635a8641SAndroid Build Coastguard Worker   StackTrace trace;
131*635a8641SAndroid Build Coastguard Worker 
132*635a8641SAndroid Build Coastguard Worker   size_t count = 0;
133*635a8641SAndroid Build Coastguard Worker   trace.Addresses(&count);
134*635a8641SAndroid Build Coastguard Worker   ASSERT_LT(2u, count);
135*635a8641SAndroid Build Coastguard Worker 
136*635a8641SAndroid Build Coastguard Worker   StackTrace truncated(2);
137*635a8641SAndroid Build Coastguard Worker   truncated.Addresses(&count);
138*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(2u, count);
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OFFICIAL_BUILD)
141*635a8641SAndroid Build Coastguard Worker 
142*635a8641SAndroid Build Coastguard Worker // The test is used for manual testing, e.g., to see the raw output.
TEST_F(StackTraceTest,DebugOutputToStream)143*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, DebugOutputToStream) {
144*635a8641SAndroid Build Coastguard Worker   StackTrace trace;
145*635a8641SAndroid Build Coastguard Worker   std::ostringstream os;
146*635a8641SAndroid Build Coastguard Worker   trace.OutputToStream(&os);
147*635a8641SAndroid Build Coastguard Worker   VLOG(1) << os.str();
148*635a8641SAndroid Build Coastguard Worker }
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker // The test is used for manual testing, e.g., to see the raw output.
TEST_F(StackTraceTest,DebugPrintBacktrace)151*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, DebugPrintBacktrace) {
152*635a8641SAndroid Build Coastguard Worker   StackTrace().Print();
153*635a8641SAndroid Build Coastguard Worker }
154*635a8641SAndroid Build Coastguard Worker #endif  // !defined(__UCLIBC__)
155*635a8641SAndroid Build Coastguard Worker 
156*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_ANDROID)
157*635a8641SAndroid Build Coastguard Worker #if !defined(OS_IOS)
newArray()158*635a8641SAndroid Build Coastguard Worker static char* newArray() {
159*635a8641SAndroid Build Coastguard Worker   // Clang warns about the mismatched new[]/delete if they occur in the same
160*635a8641SAndroid Build Coastguard Worker   // function.
161*635a8641SAndroid Build Coastguard Worker   return new char[10];
162*635a8641SAndroid Build Coastguard Worker }
163*635a8641SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(MismatchedMallocChildProcess)164*635a8641SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(MismatchedMallocChildProcess) {
165*635a8641SAndroid Build Coastguard Worker   char* pointer = newArray();
166*635a8641SAndroid Build Coastguard Worker   delete pointer;
167*635a8641SAndroid Build Coastguard Worker   return 2;
168*635a8641SAndroid Build Coastguard Worker }
169*635a8641SAndroid Build Coastguard Worker 
170*635a8641SAndroid Build Coastguard Worker // Regression test for StackDumpingSignalHandler async-signal unsafety.
171*635a8641SAndroid Build Coastguard Worker // Combined with tcmalloc's debugallocation, that signal handler
172*635a8641SAndroid Build Coastguard Worker // and e.g. mismatched new[]/delete would cause a hang because
173*635a8641SAndroid Build Coastguard Worker // of re-entering malloc.
TEST_F(StackTraceTest,AsyncSignalUnsafeSignalHandlerHang)174*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, AsyncSignalUnsafeSignalHandlerHang) {
175*635a8641SAndroid Build Coastguard Worker   Process child = SpawnChild("MismatchedMallocChildProcess");
176*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(child.IsValid());
177*635a8641SAndroid Build Coastguard Worker   int exit_code;
178*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(
179*635a8641SAndroid Build Coastguard Worker       child.WaitForExitWithTimeout(TestTimeouts::action_timeout(), &exit_code));
180*635a8641SAndroid Build Coastguard Worker }
181*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_IOS)
182*635a8641SAndroid Build Coastguard Worker 
183*635a8641SAndroid Build Coastguard Worker namespace {
184*635a8641SAndroid Build Coastguard Worker 
itoa_r_wrapper(intptr_t i,size_t sz,int base,size_t padding)185*635a8641SAndroid Build Coastguard Worker std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
186*635a8641SAndroid Build Coastguard Worker   char buffer[1024];
187*635a8641SAndroid Build Coastguard Worker   CHECK_LE(sz, sizeof(buffer));
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   char* result = internal::itoa_r(i, buffer, sz, base, padding);
190*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(result);
191*635a8641SAndroid Build Coastguard Worker   return std::string(buffer);
192*635a8641SAndroid Build Coastguard Worker }
193*635a8641SAndroid Build Coastguard Worker 
194*635a8641SAndroid Build Coastguard Worker }  // namespace
195*635a8641SAndroid Build Coastguard Worker 
TEST_F(StackTraceTest,itoa_r)196*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, itoa_r) {
197*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
198*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
199*635a8641SAndroid Build Coastguard Worker 
200*635a8641SAndroid Build Coastguard Worker   // Test edge cases.
201*635a8641SAndroid Build Coastguard Worker   if (sizeof(intptr_t) == 4) {
202*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
203*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("-2147483648",
204*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
205*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("2147483647",
206*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
207*635a8641SAndroid Build Coastguard Worker 
208*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("80000000",
209*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
210*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("7fffffff",
211*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
212*635a8641SAndroid Build Coastguard Worker   } else if (sizeof(intptr_t) == 8) {
213*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
214*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("-9223372036854775808",
215*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
216*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("9223372036854775807",
217*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("8000000000000000",
220*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
221*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ("7fffffffffffffff",
222*635a8641SAndroid Build Coastguard Worker               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
223*635a8641SAndroid Build Coastguard Worker   } else {
224*635a8641SAndroid Build Coastguard Worker     ADD_FAILURE() << "Missing test case for your size of intptr_t ("
225*635a8641SAndroid Build Coastguard Worker                   << sizeof(intptr_t) << ")";
226*635a8641SAndroid Build Coastguard Worker   }
227*635a8641SAndroid Build Coastguard Worker 
228*635a8641SAndroid Build Coastguard Worker   // Test hex output.
229*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
230*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
231*635a8641SAndroid Build Coastguard Worker 
232*635a8641SAndroid Build Coastguard Worker   // Check that itoa_r respects passed buffer size limit.
233*635a8641SAndroid Build Coastguard Worker   char buffer[1024];
234*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 10, 16, 0));
235*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 9, 16, 0));
236*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 8, 16, 0));
237*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 7, 16, 0));
238*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(internal::itoa_r(0xbeef, buffer, 5, 16, 4));
239*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 5));
240*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 6));
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker   // Test padding.
243*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
244*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
245*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
246*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
247*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
248*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
249*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
250*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
251*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
252*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
253*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
254*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
255*635a8641SAndroid Build Coastguard Worker }
256*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) && !defined(OS_ANDROID)
257*635a8641SAndroid Build Coastguard Worker 
258*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
259*635a8641SAndroid Build Coastguard Worker 
260*635a8641SAndroid Build Coastguard Worker template <size_t Depth>
ExpectStackFramePointers(const void ** frames,size_t max_depth)261*635a8641SAndroid Build Coastguard Worker void NOINLINE ExpectStackFramePointers(const void** frames,
262*635a8641SAndroid Build Coastguard Worker                                        size_t max_depth) {
263*635a8641SAndroid Build Coastguard Worker   code_start:
264*635a8641SAndroid Build Coastguard Worker   // Calling __builtin_frame_address() forces compiler to emit
265*635a8641SAndroid Build Coastguard Worker   // frame pointers, even if they are not enabled.
266*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, __builtin_frame_address(0));
267*635a8641SAndroid Build Coastguard Worker   ExpectStackFramePointers<Depth - 1>(frames, max_depth);
268*635a8641SAndroid Build Coastguard Worker 
269*635a8641SAndroid Build Coastguard Worker   constexpr size_t frame_index = Depth - 1;
270*635a8641SAndroid Build Coastguard Worker   const void* frame = frames[frame_index];
271*635a8641SAndroid Build Coastguard Worker   EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index;
272*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index;
273*635a8641SAndroid Build Coastguard Worker   code_end: return;
274*635a8641SAndroid Build Coastguard Worker }
275*635a8641SAndroid Build Coastguard Worker 
276*635a8641SAndroid Build Coastguard Worker template <>
ExpectStackFramePointers(const void ** frames,size_t max_depth)277*635a8641SAndroid Build Coastguard Worker void NOINLINE ExpectStackFramePointers<1>(const void** frames,
278*635a8641SAndroid Build Coastguard Worker                                           size_t max_depth) {
279*635a8641SAndroid Build Coastguard Worker   code_start:
280*635a8641SAndroid Build Coastguard Worker   // Calling __builtin_frame_address() forces compiler to emit
281*635a8641SAndroid Build Coastguard Worker   // frame pointers, even if they are not enabled.
282*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, __builtin_frame_address(0));
283*635a8641SAndroid Build Coastguard Worker   size_t count = TraceStackFramePointers(frames, max_depth, 0);
284*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(max_depth, count);
285*635a8641SAndroid Build Coastguard Worker 
286*635a8641SAndroid Build Coastguard Worker   const void* frame = frames[0];
287*635a8641SAndroid Build Coastguard Worker   EXPECT_GE(frame, &&code_start) << "For the top frame";
288*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(frame, &&code_end) << "For the top frame";
289*635a8641SAndroid Build Coastguard Worker   code_end: return;
290*635a8641SAndroid Build Coastguard Worker }
291*635a8641SAndroid Build Coastguard Worker 
292*635a8641SAndroid Build Coastguard Worker #if defined(MEMORY_SANITIZER)
293*635a8641SAndroid Build Coastguard Worker // The test triggers use-of-uninitialized-value errors on MSan bots.
294*635a8641SAndroid Build Coastguard Worker // This is expected because we're walking and reading the stack, and
295*635a8641SAndroid Build Coastguard Worker // sometimes we read fp / pc from the place that previously held
296*635a8641SAndroid Build Coastguard Worker // uninitialized value.
297*635a8641SAndroid Build Coastguard Worker #define MAYBE_TraceStackFramePointers DISABLED_TraceStackFramePointers
298*635a8641SAndroid Build Coastguard Worker #else
299*635a8641SAndroid Build Coastguard Worker #define MAYBE_TraceStackFramePointers TraceStackFramePointers
300*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(StackTraceTest,MAYBE_TraceStackFramePointers)301*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, MAYBE_TraceStackFramePointers) {
302*635a8641SAndroid Build Coastguard Worker   constexpr size_t kDepth = 5;
303*635a8641SAndroid Build Coastguard Worker   const void* frames[kDepth];
304*635a8641SAndroid Build Coastguard Worker   ExpectStackFramePointers<kDepth>(frames, kDepth);
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker 
307*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) || defined(OS_MACOSX)
308*635a8641SAndroid Build Coastguard Worker #define MAYBE_StackEnd StackEnd
309*635a8641SAndroid Build Coastguard Worker #else
310*635a8641SAndroid Build Coastguard Worker #define MAYBE_StackEnd DISABLED_StackEnd
311*635a8641SAndroid Build Coastguard Worker #endif
312*635a8641SAndroid Build Coastguard Worker 
TEST_F(StackTraceTest,MAYBE_StackEnd)313*635a8641SAndroid Build Coastguard Worker TEST_F(StackTraceTest, MAYBE_StackEnd) {
314*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(0u, GetStackEnd());
315*635a8641SAndroid Build Coastguard Worker }
316*635a8641SAndroid Build Coastguard Worker 
317*635a8641SAndroid Build Coastguard Worker #endif  // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
318*635a8641SAndroid Build Coastguard Worker 
319*635a8641SAndroid Build Coastguard Worker }  // namespace debug
320*635a8641SAndroid Build Coastguard Worker }  // namespace base
321