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