• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/debug/stack_trace.h"
6 
7 #include <stddef.h>
8 
9 #include <limits>
10 #include <sstream>
11 #include <string>
12 
13 #include "base/allocator/buildflags.h"
14 #include "base/containers/span.h"
15 #include "base/debug/debugging_buildflags.h"
16 #include "base/immediate_crash.h"
17 #include "base/logging.h"
18 #include "base/process/kill.h"
19 #include "base/process/process_handle.h"
20 #include "base/profiler/stack_buffer.h"
21 #include "base/profiler/stack_copier.h"
22 #include "base/strings/cstring_view.h"
23 #include "base/test/test_timeouts.h"
24 #include "build/build_config.h"
25 #include "partition_alloc/partition_alloc.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "testing/multiprocess_func_list.h"
28 #if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
29 #include "partition_alloc/shim/allocator_shim.h"
30 #endif
31 
32 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
33 #include "base/test/multiprocess_test.h"
34 #endif
35 
36 namespace base {
37 namespace debug {
38 
39 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
40 typedef MultiProcessTest StackTraceTest;
41 #else
42 typedef testing::Test StackTraceTest;
43 #endif
44 typedef testing::Test StackTraceDeathTest;
45 
46 #if !defined(__UCLIBC__) && !defined(_AIX)
47 // StackTrace::OutputToStream() is not implemented under uclibc, nor AIX.
48 // See https://crbug.com/706728
49 
TEST_F(StackTraceTest,OutputToStream)50 TEST_F(StackTraceTest, OutputToStream) {
51   StackTrace trace;
52 
53   // Dump the trace into a string.
54   std::ostringstream os;
55   trace.OutputToStream(&os);
56   std::string backtrace_message = os.str();
57 
58   // ToString() should produce the same output.
59   EXPECT_EQ(backtrace_message, trace.ToString());
60 
61   span<const void* const> addresses = trace.addresses();
62 
63 #if defined(OFFICIAL_BUILD) && \
64     ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) || BUILDFLAG(IS_FUCHSIA))
65   // Stack traces require an extra data table that bloats our binaries,
66   // so they're turned off for official builds. Stop the test here, so
67   // it at least verifies that StackTrace calls don't crash.
68   return;
69 #endif  // defined(OFFICIAL_BUILD) &&
70         // ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) ||
71         // BUILDFLAG(IS_FUCHSIA))
72 
73   ASSERT_GT(addresses.size(), 5u) << "Too few frames found.";
74   ASSERT_NE(nullptr, addresses[0]);
75 
76   if (!StackTrace::WillSymbolizeToStreamForTesting())
77     return;
78 
79   // Check if the output has symbol initialization warning.  If it does, fail.
80   ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
81             std::string::npos)
82       << "Unable to resolve symbols.";
83 
84   // Expect a demangled symbol.
85   // Note that Windows Release builds omit the function parameters from the
86   // demangled stack output, otherwise this could be "testing::UnitTest::Run()".
87   EXPECT_TRUE(backtrace_message.find("testing::UnitTest::Run") !=
88               std::string::npos)
89       << "Expected a demangled symbol in backtrace:\n"
90       << backtrace_message;
91 
92   // Expect to at least find main.
93   EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
94       << "Expected to find main in backtrace:\n"
95       << backtrace_message;
96 
97   // Expect to find this function as well.
98   // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
99   EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
100       << "Expected to find " << __func__ << " in backtrace:\n"
101       << backtrace_message;
102 }
103 
104 #if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
105 // Disabled in Official builds, where Link-Time Optimization can result in two
106 // or fewer stack frames being available, causing the test to fail.
TEST_F(StackTraceTest,TruncatedTrace)107 TEST_F(StackTraceTest, TruncatedTrace) {
108   StackTrace trace;
109 
110   ASSERT_LT(2u, trace.addresses().size());
111 
112   StackTrace truncated(2);
113   EXPECT_EQ(2u, truncated.addresses().size());
114 }
115 #endif  // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
116 
117 // The test is used for manual testing, e.g., to see the raw output.
TEST_F(StackTraceTest,DebugOutputToStream)118 TEST_F(StackTraceTest, DebugOutputToStream) {
119   StackTrace trace;
120   std::ostringstream os;
121   trace.OutputToStream(&os);
122   VLOG(1) << os.str();
123 }
124 
125 // The test is used for manual testing, e.g., to see the raw output.
TEST_F(StackTraceTest,DebugPrintBacktrace)126 TEST_F(StackTraceTest, DebugPrintBacktrace) {
127   StackTrace().Print();
128 }
129 
130 // The test is used for manual testing, e.g., to see the raw output.
TEST_F(StackTraceTest,DebugPrintWithPrefixBacktrace)131 TEST_F(StackTraceTest, DebugPrintWithPrefixBacktrace) {
132   StackTrace().PrintWithPrefix("[test]");
133 }
134 
135 // Make sure nullptr prefix doesn't crash. Output not examined, much
136 // like the DebugPrintBacktrace test above.
TEST_F(StackTraceTest,DebugPrintWithNullPrefixBacktrace)137 TEST_F(StackTraceTest, DebugPrintWithNullPrefixBacktrace) {
138   StackTrace().PrintWithPrefix({});
139 }
140 
141 // Test OutputToStreamWithPrefix, mainly to make sure it doesn't
142 // crash. Any "real" stack trace testing happens above.
TEST_F(StackTraceTest,DebugOutputToStreamWithPrefix)143 TEST_F(StackTraceTest, DebugOutputToStreamWithPrefix) {
144   StackTrace trace;
145   cstring_view prefix_string = "[test]";
146   std::ostringstream os;
147   trace.OutputToStreamWithPrefix(&os, prefix_string);
148   std::string backtrace_message = os.str();
149 
150   // ToStringWithPrefix() should produce the same output.
151   EXPECT_EQ(backtrace_message, trace.ToStringWithPrefix(prefix_string));
152 }
153 
154 // Make sure nullptr prefix doesn't crash. Output not examined, much
155 // like the DebugPrintBacktrace test above.
TEST_F(StackTraceTest,DebugOutputToStreamWithNullPrefix)156 TEST_F(StackTraceTest, DebugOutputToStreamWithNullPrefix) {
157   StackTrace trace;
158   std::ostringstream os;
159   trace.OutputToStreamWithPrefix(&os, {});
160   trace.ToStringWithPrefix({});
161 }
162 
163 #endif  // !defined(__UCLIBC__) && !defined(_AIX)
164 
165 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
166 // Since Mac's base::debug::StackTrace().Print() is not malloc-free, skip
167 // StackDumpSignalHandlerIsMallocFree if BUILDFLAG(IS_MAC).
168 #if PA_BUILDFLAG(USE_ALLOCATOR_SHIM) && !BUILDFLAG(IS_MAC)
169 
170 namespace {
171 
172 // ImmediateCrash if a signal handler incorrectly uses malloc().
173 // In an actual implementation, this could cause infinite recursion into the
174 // signal handler or other problems. Because malloc() is not guaranteed to be
175 // async signal safe.
BadMalloc(size_t,void *)176 void* BadMalloc(size_t, void*) {
177   base::ImmediateCrash();
178 }
179 
BadCalloc(size_t,size_t,void * context)180 void* BadCalloc(size_t, size_t, void* context) {
181   base::ImmediateCrash();
182 }
183 
BadAlignedAlloc(size_t,size_t,void *)184 void* BadAlignedAlloc(size_t, size_t, void*) {
185   base::ImmediateCrash();
186 }
187 
BadAlignedRealloc(void *,size_t,size_t,void *)188 void* BadAlignedRealloc(void*, size_t, size_t, void*) {
189   base::ImmediateCrash();
190 }
191 
BadRealloc(void *,size_t,void *)192 void* BadRealloc(void*, size_t, void*) {
193   base::ImmediateCrash();
194 }
195 
BadFree(void *,void *)196 void BadFree(void*, void*) {
197   base::ImmediateCrash();
198 }
199 
200 allocator_shim::AllocatorDispatch g_bad_malloc_dispatch = {
201     &BadMalloc,         /* alloc_function */
202     &BadMalloc,         /* alloc_unchecked_function */
203     &BadCalloc,         /* alloc_zero_initialized_function */
204     &BadAlignedAlloc,   /* alloc_aligned_function */
205     &BadRealloc,        /* realloc_function */
206     &BadRealloc,        /* realloc_unchecked_function */
207     &BadFree,           /* free_function */
208     nullptr,            /* get_size_estimate_function */
209     nullptr,            /* good_size_function */
210     nullptr,            /* claimed_address_function */
211     nullptr,            /* batch_malloc_function */
212     nullptr,            /* batch_free_function */
213     nullptr,            /* free_definite_size_function */
214     nullptr,            /* try_free_default_function */
215     &BadAlignedAlloc,   /* aligned_malloc_function */
216     &BadAlignedAlloc,   /* aligned_malloc_unchecked_function */
217     &BadAlignedRealloc, /* aligned_realloc_function */
218     &BadAlignedRealloc, /* aligned_realloc_unchecked_function */
219     &BadFree,           /* aligned_free_function */
220     nullptr,            /* next */
221 };
222 
223 }  // namespace
224 
225 // Regression test for StackDumpSignalHandler async-signal unsafety.
226 // Since malloc() is not guaranteed to be async signal safe, it is not allowed
227 // to use malloc() inside StackDumpSignalHandler().
TEST_F(StackTraceDeathTest,StackDumpSignalHandlerIsMallocFree)228 TEST_F(StackTraceDeathTest, StackDumpSignalHandlerIsMallocFree) {
229   EXPECT_DEATH_IF_SUPPORTED(
230       [] {
231         // On Android, base::debug::EnableInProcessStackDumping() does not
232         // change any actions taken by signals to be StackDumpSignalHandler. So
233         // the StackDumpSignalHandlerIsMallocFree test doesn't work on Android.
234         EnableInProcessStackDumping();
235         allocator_shim::InsertAllocatorDispatch(&g_bad_malloc_dispatch);
236         // Raise SIGSEGV to invoke StackDumpSignalHandler().
237         kill(getpid(), SIGSEGV);
238       }(),
239       "\\[end of stack trace\\]\n");
240 }
241 #endif  // PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
242 
243 namespace {
244 
itoa_r_wrapper(intptr_t i,size_t sz,int base,size_t padding)245 std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
246   std::array<char, 1024> buffer;
247   internal::itoa_r(i, base, padding, base::span(buffer).first(sz));
248   EXPECT_NE(buffer[0], '\0');
249   for (char c : buffer) {
250     if (c == '\0') {
251       return std::string(buffer.data());
252     }
253   }
254   ADD_FAILURE() << "buffer is not NUL terminated";
255   return std::string("");
256 }
257 
258 }  // namespace
259 
TEST_F(StackTraceTest,itoa_r)260 TEST_F(StackTraceTest, itoa_r) {
261   EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
262   EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
263 
264   // Test edge cases.
265   if (sizeof(intptr_t) == 4) {
266     EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
267     EXPECT_EQ("-2147483648",
268               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
269     EXPECT_EQ("2147483647",
270               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
271 
272     EXPECT_EQ("80000000",
273               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
274     EXPECT_EQ("7fffffff",
275               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
276   } else if (sizeof(intptr_t) == 8) {
277     EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
278     EXPECT_EQ("-9223372036854775808",
279               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
280     EXPECT_EQ("9223372036854775807",
281               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
282 
283     EXPECT_EQ("8000000000000000",
284               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
285     EXPECT_EQ("7fffffffffffffff",
286               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
287   } else {
288     ADD_FAILURE() << "Missing test case for your size of intptr_t ("
289                   << sizeof(intptr_t) << ")";
290   }
291 
292   // Test hex output.
293   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
294   EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
295 
296   // Check that itoa_r respects passed buffer size limit.
297   std::array<char, 1024> buffer;
298   internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(10u));
299   EXPECT_NE(buffer[0u], '\0');
300   internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(9u));
301   EXPECT_NE(buffer[0u], '\0');
302   internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(8u));
303   EXPECT_EQ(buffer[0u], '\0');
304   internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(7u));
305   EXPECT_EQ(buffer[0u], '\0');
306   internal::itoa_r(0xbeef, 16, 4, base::span(buffer).first(5u));
307   EXPECT_NE(buffer[0u], '\0');
308   internal::itoa_r(0xbeef, 16, 5, base::span(buffer).first(5u));
309   EXPECT_EQ(buffer[0u], '\0');
310   internal::itoa_r(0xbeef, 16, 6, base::span(buffer).first(5u));
311   EXPECT_EQ(buffer[0u], '\0');
312 
313   // Test padding.
314   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
315   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
316   EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
317   EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
318   EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
319   EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
320   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
321   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
322   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
323   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
324   EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
325   EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
326 }
327 #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
328 
329 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
330 
331 class CopyFunction : public StackCopier {
332  public:
333   using StackCopier::CopyStackContentsAndRewritePointers;
334 };
335 
336 template <size_t Depth>
ExpectStackFramePointers(span<const void * > frames)337 NOINLINE NOOPT void ExpectStackFramePointers(span<const void*> frames) {
338 code_start:
339   // Calling __builtin_frame_address() forces compiler to emit
340   // frame pointers, even if they are not enabled.
341   EXPECT_NE(nullptr, __builtin_frame_address(0));
342   ExpectStackFramePointers<Depth - 1>(frames);
343 
344   constexpr size_t frame_index = Depth - 1;
345   const void* frame = frames[frame_index];
346   EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index;
347   EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index;
348 code_end:
349   return;
350 }
351 
352 template <>
ExpectStackFramePointers(span<const void * > frames)353 NOINLINE NOOPT void ExpectStackFramePointers<1>(span<const void*> frames) {
354 code_start:
355   // Calling __builtin_frame_address() forces compiler to emit
356   // frame pointers, even if they are not enabled.
357   EXPECT_NE(nullptr, __builtin_frame_address(0));
358   size_t count = TraceStackFramePointers(frames, 0u);
359   ASSERT_EQ(frames.size(), count);
360 
361   const void* frame = frames[0];
362   EXPECT_GE(frame, &&code_start) << "For the top frame";
363   EXPECT_LE(frame, &&code_end) << "For the top frame";
364 code_end:
365   return;
366 }
367 
368 #if defined(MEMORY_SANITIZER)
369 // The test triggers use-of-uninitialized-value errors on MSan bots.
370 // This is expected because we're walking and reading the stack, and
371 // sometimes we read fp / pc from the place that previously held
372 // uninitialized value.
373 #define MAYBE_TraceStackFramePointers DISABLED_TraceStackFramePointers
374 #else
375 #define MAYBE_TraceStackFramePointers TraceStackFramePointers
376 #endif
TEST_F(StackTraceTest,MAYBE_TraceStackFramePointers)377 TEST_F(StackTraceTest, MAYBE_TraceStackFramePointers) {
378   constexpr size_t kDepth = 5;
379   const void* frames[kDepth];
380   ExpectStackFramePointers<kDepth>(frames);
381 }
382 
383 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
384 #define MAYBE_StackEnd StackEnd
385 #else
386 #define MAYBE_StackEnd DISABLED_StackEnd
387 #endif
388 
TEST_F(StackTraceTest,MAYBE_StackEnd)389 TEST_F(StackTraceTest, MAYBE_StackEnd) {
390   EXPECT_NE(0u, GetStackEnd());
391 }
392 
393 #endif  // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
394 
395 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
396 
397 #if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
398 
399 #if !defined(ARCH_CPU_ARM_FAMILY)
400 // On Arm architecture invalid math operations such as division by zero are not
401 // trapped and do not trigger a SIGFPE.
402 // Hence disable the test for Arm platforms.
TEST(CheckExitCodeAfterSignalHandlerDeathTest,CheckSIGFPE)403 TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGFPE) {
404   // Values are volatile to prevent reordering of instructions, i.e. for
405   // optimization. Reordering may lead to tests erroneously failing due to
406   // SIGFPE being raised outside of EXPECT_EXIT.
407   volatile int const nominator = 23;
408   volatile int const denominator = 0;
409   [[maybe_unused]] volatile int result;
410 
411   EXPECT_EXIT(result = nominator / denominator,
412               ::testing::KilledBySignal(SIGFPE), "");
413 }
414 #endif  // !defined(ARCH_CPU_ARM_FAMILY)
415 
TEST(CheckExitCodeAfterSignalHandlerDeathTest,CheckSIGSEGV)416 TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGSEGV) {
417   // Pointee and pointer are volatile to prevent reordering of instructions,
418   // i.e. for optimization. Reordering may lead to tests erroneously failing due
419   // to SIGSEGV being raised outside of EXPECT_EXIT.
420   volatile int* const volatile p_int = nullptr;
421 
422   EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "");
423 }
424 
425 #if defined(ARCH_CPU_X86_64)
TEST(CheckExitCodeAfterSignalHandlerDeathTest,CheckSIGSEGVNonCanonicalAddress)426 TEST(CheckExitCodeAfterSignalHandlerDeathTest,
427      CheckSIGSEGVNonCanonicalAddress) {
428   // Pointee and pointer are volatile to prevent reordering of instructions,
429   // i.e. for optimization. Reordering may lead to tests erroneously failing due
430   // to SIGSEGV being raised outside of EXPECT_EXIT.
431   //
432   // On Linux, the upper half of the address space is reserved by the kernel, so
433   // all upper bits must be 0 for canonical addresses.
434   volatile int* const volatile p_int =
435       reinterpret_cast<int*>(0xabcdabcdabcdabcdULL);
436 
437   EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "SI_KERNEL");
438 }
439 #endif
440 
441 #endif  // #if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
442 
TEST(CheckExitCodeAfterSignalHandlerDeathTest,CheckSIGILL)443 TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGILL) {
444   auto const raise_sigill = [] {
445 #if defined(ARCH_CPU_X86_FAMILY)
446     asm("ud2");
447 #elif defined(ARCH_CPU_ARM_FAMILY)
448     asm("udf 0");
449 #else
450 #error Unsupported platform!
451 #endif
452   };
453 
454   EXPECT_EXIT(raise_sigill(), ::testing::KilledBySignal(SIGILL), "");
455 }
456 
457 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
458 
459 }  // namespace debug
460 }  // namespace base
461