blob: e81d038ebeb1936a5bf64a287629d431ae0ce9ce [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2011 The Chromium Authors
[email protected]96fd0032009-04-24 00:13:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakje75c6c812024-07-26 20:37:475#include "base/debug/stack_trace.h"
danakj51d26a402024-04-25 14:23:566
aviebe805c2015-12-24 08:20:287#include <stddef.h>
8
[email protected]1e218b72012-11-14 19:32:239#include <limits>
[email protected]96fd0032009-04-24 00:13:0810#include <sstream>
11#include <string>
12
danakje75c6c812024-07-26 20:37:4713#include "base/allocator/buildflags.h"
Alex Gough0bbe87d2025-09-12 21:12:1114#include "base/containers/contains.h"
Scott Violet44165792018-02-22 02:08:0815#include "base/debug/debugging_buildflags.h"
Takashi Sakamotob9980552023-10-17 20:14:1116#include "base/immediate_crash.h"
[email protected]96fd0032009-04-24 00:13:0817#include "base/logging.h"
[email protected]dd4b51262013-07-25 21:38:2318#include "base/process/kill.h"
19#include "base/process/process_handle.h"
ssidc1d5a3d2020-09-11 05:20:3020#include "base/profiler/stack_buffer.h"
21#include "base/profiler/stack_copier.h"
Greg Thompson8b1b295b2024-04-10 07:44:1422#include "base/strings/cstring_view.h"
[email protected]1e218b72012-11-14 19:32:2323#include "base/test/test_timeouts.h"
aviebe805c2015-12-24 08:20:2824#include "build/build_config.h"
danakje75c6c812024-07-26 20:37:4725#include "partition_alloc/partition_alloc.h"
Alex Gough0bbe87d2025-09-12 21:12:1126#include "testing/gmock/include/gmock/gmock.h"
[email protected]96fd0032009-04-24 00:13:0827#include "testing/gtest/include/gtest/gtest.h"
[email protected]1e218b72012-11-14 19:32:2328#include "testing/multiprocess_func_list.h"
Arthur Sonzogni62e877a2024-04-30 16:09:4329#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino985ab91e2024-03-14 07:20:4630#include "partition_alloc/shim/allocator_shim.h"
Takashi Sakamotob9980552023-10-17 20:14:1131#endif
32
Xiaohan Wang131aa4d2022-01-15 19:39:4133#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
[email protected]1e218b72012-11-14 19:32:2334#include "base/test/multiprocess_test.h"
35#endif
[email protected]96fd0032009-04-24 00:13:0836
Peter Kasting811504a72025-01-09 03:18:5037namespace base::debug {
[email protected]58580352010-10-26 04:07:5038
Xiaohan Wang131aa4d2022-01-15 19:39:4139#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
[email protected]1e218b72012-11-14 19:32:2340typedef MultiProcessTest StackTraceTest;
41#else
42typedef testing::Test StackTraceTest;
43#endif
Takashi Sakamotob9980552023-10-17 20:14:1144typedef testing::Test StackTraceDeathTest;
[email protected]1e218b72012-11-14 19:32:2345
Mike West040aca72019-11-13 08:10:2146#if !defined(__UCLIBC__) && !defined(_AIX)
Wez7c0794d2019-11-14 18:30:4147// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX.
48// See https://crbug.com/706728
49
50TEST_F(StackTraceTest, OutputToStream) {
[email protected]96fd0032009-04-24 00:13:0851 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
[email protected]d4114ba2011-10-12 16:13:4058 // ToString() should produce the same output.
59 EXPECT_EQ(backtrace_message, trace.ToString());
60
Daniel Chenga0e290d2023-10-16 18:47:2461 span<const void* const> addresses = trace.addresses();
Wez7c0794d2019-11-14 18:30:4162
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5863#if defined(OFFICIAL_BUILD) && \
Xiaohan Wang131aa4d2022-01-15 19:39:4164 ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) || BUILDFLAG(IS_FUCHSIA))
Wez7c0794d2019-11-14 18:30:4165 // 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;
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5869#endif // defined(OFFICIAL_BUILD) &&
Xiaohan Wang131aa4d2022-01-15 19:39:4170 // ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) ||
71 // BUILDFLAG(IS_FUCHSIA))
Wezeaf15532019-11-15 22:00:3172
Daniel Chenga0e290d2023-10-16 18:47:2473 ASSERT_GT(addresses.size(), 5u) << "Too few frames found.";
Peter Kasting654bb6252024-11-16 02:29:0874 ASSERT_NE(nullptr, addresses[0]);
Wez7c0794d2019-11-14 18:30:4175
Peter Kasting134ef9af2024-12-28 02:30:0976 if (!StackTrace::WillSymbolizeToStreamForTesting()) {
Gabriel Charetteae1bb012021-05-06 19:31:2177 return;
Peter Kasting134ef9af2024-12-28 02:30:0978 }
[email protected]96fd0032009-04-24 00:13:0879
80 // Check if the output has symbol initialization warning. If it does, fail.
[email protected]de1b764f2009-08-24 15:36:4181 ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
Wez7c0794d2019-11-14 18:30:4182 std::string::npos)
83 << "Unable to resolve symbols.";
[email protected]96fd0032009-04-24 00:13:0884
[email protected]79b6fa62009-10-14 03:01:4485 // Expect a demangled symbol.
Wez7c0794d2019-11-14 18:30:4186 // Note that Windows Release builds omit the function parameters from the
Zequan Wu76eee5e92020-07-06 17:38:4087 // demangled stack output, otherwise this could be "testing::UnitTest::Run()".
88 EXPECT_TRUE(backtrace_message.find("testing::UnitTest::Run") !=
89 std::string::npos)
[email protected]79b6fa62009-10-14 03:01:4490 << "Expected a demangled symbol in backtrace:\n"
91 << backtrace_message;
[email protected]889da7e42009-12-31 02:28:0992
[email protected]96fd0032009-04-24 00:13:0893 // Expect to at least find main.
94 EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
95 << "Expected to find main in backtrace:\n"
96 << backtrace_message;
97
[email protected]96fd0032009-04-24 00:13:0898 // Expect to find this function as well.
99 // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
100 EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
101 << "Expected to find " << __func__ << " in backtrace:\n"
102 << backtrace_message;
[email protected]96fd0032009-04-24 00:13:08103}
[email protected]48c27f72010-01-26 06:26:26104
halliwell5e1e4fa2017-03-28 03:21:08105#if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
wezec97f912017-02-05 01:29:25106// Disabled in Official builds, where Link-Time Optimization can result in two
107// or fewer stack frames being available, causing the test to fail.
wez73f8d7e2017-01-29 06:18:13108TEST_F(StackTraceTest, TruncatedTrace) {
109 StackTrace trace;
110
Daniel Chenga0e290d2023-10-16 18:47:24111 ASSERT_LT(2u, trace.addresses().size());
wez73f8d7e2017-01-29 06:18:13112
113 StackTrace truncated(2);
Daniel Chenga0e290d2023-10-16 18:47:24114 EXPECT_EQ(2u, truncated.addresses().size());
wez73f8d7e2017-01-29 06:18:13115}
Wez7c0794d2019-11-14 18:30:41116#endif // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
wez73f8d7e2017-01-29 06:18:13117
[email protected]a15115f02010-05-25 20:07:12118// The test is used for manual testing, e.g., to see the raw output.
scottmgf063a7e2015-02-25 00:17:30119TEST_F(StackTraceTest, DebugOutputToStream) {
[email protected]48c27f72010-01-26 06:26:26120 StackTrace trace;
121 std::ostringstream os;
122 trace.OutputToStream(&os);
[email protected]b026e35d2010-10-19 02:31:03123 VLOG(1) << os.str();
[email protected]48c27f72010-01-26 06:26:26124}
125
[email protected]a15115f02010-05-25 20:07:12126// The test is used for manual testing, e.g., to see the raw output.
scottmgf063a7e2015-02-25 00:17:30127TEST_F(StackTraceTest, DebugPrintBacktrace) {
[email protected]5ddbf1c2013-08-29 01:59:38128 StackTrace().Print();
[email protected]48c27f72010-01-26 06:26:26129}
Mason Freedb9ef2b62018-09-10 17:17:27130
131// The test is used for manual testing, e.g., to see the raw output.
132TEST_F(StackTraceTest, DebugPrintWithPrefixBacktrace) {
133 StackTrace().PrintWithPrefix("[test]");
134}
135
136// Make sure nullptr prefix doesn't crash. Output not examined, much
137// like the DebugPrintBacktrace test above.
138TEST_F(StackTraceTest, DebugPrintWithNullPrefixBacktrace) {
Greg Thompson8b1b295b2024-04-10 07:44:14139 StackTrace().PrintWithPrefix({});
Mason Freedb9ef2b62018-09-10 17:17:27140}
141
142// Test OutputToStreamWithPrefix, mainly to make sure it doesn't
143// crash. Any "real" stack trace testing happens above.
144TEST_F(StackTraceTest, DebugOutputToStreamWithPrefix) {
145 StackTrace trace;
Greg Thompson8b1b295b2024-04-10 07:44:14146 cstring_view prefix_string = "[test]";
Mason Freedb9ef2b62018-09-10 17:17:27147 std::ostringstream os;
148 trace.OutputToStreamWithPrefix(&os, prefix_string);
149 std::string backtrace_message = os.str();
150
151 // ToStringWithPrefix() should produce the same output.
152 EXPECT_EQ(backtrace_message, trace.ToStringWithPrefix(prefix_string));
153}
154
155// Make sure nullptr prefix doesn't crash. Output not examined, much
156// like the DebugPrintBacktrace test above.
157TEST_F(StackTraceTest, DebugOutputToStreamWithNullPrefix) {
158 StackTrace trace;
159 std::ostringstream os;
Greg Thompson8b1b295b2024-04-10 07:44:14160 trace.OutputToStreamWithPrefix(&os, {});
161 trace.ToStringWithPrefix({});
Mason Freedb9ef2b62018-09-10 17:17:27162}
163
Wez7c0794d2019-11-14 18:30:41164#endif // !defined(__UCLIBC__) && !defined(_AIX)
[email protected]58580352010-10-26 04:07:50165
Xiaohan Wang131aa4d2022-01-15 19:39:41166#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
Takashi Sakamotob9980552023-10-17 20:14:11167// Since Mac's base::debug::StackTrace().Print() is not malloc-free, skip
168// StackDumpSignalHandlerIsMallocFree if BUILDFLAG(IS_MAC).
Arthur Sonzogni62e877a2024-04-30 16:09:43169#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM) && !BUILDFLAG(IS_MAC)
Takashi Sakamotob9980552023-10-17 20:14:11170
171namespace {
172
173// ImmediateCrash if a signal handler incorrectly uses malloc().
174// In an actual implementation, this could cause infinite recursion into the
175// signal handler or other problems. Because malloc() is not guaranteed to be
176// async signal safe.
Yuki Shiino3b110492024-08-08 06:11:22177void* BadMalloc(size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11178 base::ImmediateCrash();
hanscd4cce32015-05-19 17:03:14179}
180
Yuki Shiino3b110492024-08-08 06:11:22181void* BadCalloc(size_t, size_t, void* context) {
Takashi Sakamotob9980552023-10-17 20:14:11182 base::ImmediateCrash();
[email protected]1e218b72012-11-14 19:32:23183}
184
Yuki Shiino3b110492024-08-08 06:11:22185void* BadAlignedAlloc(size_t, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11186 base::ImmediateCrash();
[email protected]1e218b72012-11-14 19:32:23187}
Takashi Sakamotob9980552023-10-17 20:14:11188
Yuki Shiino3b110492024-08-08 06:11:22189void* BadAlignedRealloc(void*, size_t, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11190 base::ImmediateCrash();
191}
192
Yuki Shiino3b110492024-08-08 06:11:22193void* BadRealloc(void*, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11194 base::ImmediateCrash();
195}
196
Yuki Shiino3b110492024-08-08 06:11:22197void BadFree(void*, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11198 base::ImmediateCrash();
199}
200
201allocator_shim::AllocatorDispatch g_bad_malloc_dispatch = {
202 &BadMalloc, /* alloc_function */
203 &BadMalloc, /* alloc_unchecked_function */
204 &BadCalloc, /* alloc_zero_initialized_function */
Aldo Culquicondor189a4b52025-09-12 16:22:03205 &BadCalloc, /* alloc_zero_initialized_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11206 &BadAlignedAlloc, /* alloc_aligned_function */
207 &BadRealloc, /* realloc_function */
danakj19cd9b82024-07-05 14:03:40208 &BadRealloc, /* realloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11209 &BadFree, /* free_function */
mikt989d97892025-04-23 12:45:18210 nullptr, /* free_with_size_function */
211 nullptr, /* free_with_alignment_function */
212 nullptr, /* free_with_size_and_alignment_function */
Takashi Sakamotob9980552023-10-17 20:14:11213 nullptr, /* get_size_estimate_function */
Benoit Lizecd75515a2023-11-29 14:47:42214 nullptr, /* good_size_function */
Takashi Sakamotob9980552023-10-17 20:14:11215 nullptr, /* claimed_address_function */
216 nullptr, /* batch_malloc_function */
217 nullptr, /* batch_free_function */
Takashi Sakamotob9980552023-10-17 20:14:11218 nullptr, /* try_free_default_function */
219 &BadAlignedAlloc, /* aligned_malloc_function */
danakj19cd9b82024-07-05 14:03:40220 &BadAlignedAlloc, /* aligned_malloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11221 &BadAlignedRealloc, /* aligned_realloc_function */
danakj19cd9b82024-07-05 14:03:40222 &BadAlignedRealloc, /* aligned_realloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11223 &BadFree, /* aligned_free_function */
224 nullptr, /* next */
225};
226
227} // namespace
228
229// Regression test for StackDumpSignalHandler async-signal unsafety.
230// Since malloc() is not guaranteed to be async signal safe, it is not allowed
231// to use malloc() inside StackDumpSignalHandler().
232TEST_F(StackTraceDeathTest, StackDumpSignalHandlerIsMallocFree) {
233 EXPECT_DEATH_IF_SUPPORTED(
234 [] {
235 // On Android, base::debug::EnableInProcessStackDumping() does not
236 // change any actions taken by signals to be StackDumpSignalHandler. So
237 // the StackDumpSignalHandlerIsMallocFree test doesn't work on Android.
238 EnableInProcessStackDumping();
239 allocator_shim::InsertAllocatorDispatch(&g_bad_malloc_dispatch);
240 // Raise SIGSEGV to invoke StackDumpSignalHandler().
241 kill(getpid(), SIGSEGV);
242 }(),
243 "\\[end of stack trace\\]\n");
244}
Arthur Sonzogni62e877a2024-04-30 16:09:43245#endif // PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
[email protected]1e218b72012-11-14 19:32:23246
247namespace {
248
[email protected]22d5b9822013-01-10 18:21:52249std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
danakjd53babfe2024-10-09 14:04:16250 std::array<char, 1024> buffer;
251 internal::itoa_r(i, base, padding, base::span(buffer).first(sz));
252 EXPECT_NE(buffer[0], '\0');
253 for (char c : buffer) {
254 if (c == '\0') {
255 return std::string(buffer.data());
256 }
257 }
258 ADD_FAILURE() << "buffer is not NUL terminated";
259 return std::string("");
[email protected]1e218b72012-11-14 19:32:23260}
261
262} // namespace
263
264TEST_F(StackTraceTest, itoa_r) {
[email protected]22d5b9822013-01-10 18:21:52265 EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
266 EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23267
268 // Test edge cases.
269 if (sizeof(intptr_t) == 4) {
[email protected]22d5b9822013-01-10 18:21:52270 EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23271 EXPECT_EQ("-2147483648",
[email protected]22d5b9822013-01-10 18:21:52272 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23273 EXPECT_EQ("2147483647",
[email protected]22d5b9822013-01-10 18:21:52274 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23275
276 EXPECT_EQ("80000000",
[email protected]22d5b9822013-01-10 18:21:52277 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23278 EXPECT_EQ("7fffffff",
[email protected]22d5b9822013-01-10 18:21:52279 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23280 } else if (sizeof(intptr_t) == 8) {
[email protected]22d5b9822013-01-10 18:21:52281 EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23282 EXPECT_EQ("-9223372036854775808",
[email protected]22d5b9822013-01-10 18:21:52283 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23284 EXPECT_EQ("9223372036854775807",
[email protected]22d5b9822013-01-10 18:21:52285 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23286
287 EXPECT_EQ("8000000000000000",
[email protected]22d5b9822013-01-10 18:21:52288 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23289 EXPECT_EQ("7fffffffffffffff",
[email protected]22d5b9822013-01-10 18:21:52290 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23291 } else {
292 ADD_FAILURE() << "Missing test case for your size of intptr_t ("
293 << sizeof(intptr_t) << ")";
294 }
295
296 // Test hex output.
[email protected]22d5b9822013-01-10 18:21:52297 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
298 EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23299
300 // Check that itoa_r respects passed buffer size limit.
danakjd53babfe2024-10-09 14:04:16301 std::array<char, 1024> buffer;
302 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(10u));
303 EXPECT_NE(buffer[0u], '\0');
304 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(9u));
305 EXPECT_NE(buffer[0u], '\0');
306 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(8u));
307 EXPECT_EQ(buffer[0u], '\0');
308 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(7u));
309 EXPECT_EQ(buffer[0u], '\0');
310 internal::itoa_r(0xbeef, 16, 4, base::span(buffer).first(5u));
311 EXPECT_NE(buffer[0u], '\0');
312 internal::itoa_r(0xbeef, 16, 5, base::span(buffer).first(5u));
313 EXPECT_EQ(buffer[0u], '\0');
314 internal::itoa_r(0xbeef, 16, 6, base::span(buffer).first(5u));
315 EXPECT_EQ(buffer[0u], '\0');
[email protected]22d5b9822013-01-10 18:21:52316
317 // Test padding.
318 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
319 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
320 EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
321 EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
322 EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
323 EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
324 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
325 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
326 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
327 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
328 EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
329 EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
[email protected]1e218b72012-11-14 19:32:23330}
Xiaohan Wang131aa4d2022-01-15 19:39:41331#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
[email protected]1e218b72012-11-14 19:32:23332
wez460b1242017-04-10 21:55:36333#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
erikchenf7c8a0d2017-04-06 21:15:27334
ssidc1d5a3d2020-09-11 05:20:30335class CopyFunction : public StackCopier {
336 public:
337 using StackCopier::CopyStackContentsAndRewritePointers;
338};
339
dskiba79080da02016-04-23 00:10:27340template <size_t Depth>
danakje75c6c812024-07-26 20:37:47341NOINLINE NOOPT void ExpectStackFramePointers(span<const void*> frames) {
Peter Kastingf541f7782023-03-10 23:44:46342code_start:
dskiba79080da02016-04-23 00:10:27343 // Calling __builtin_frame_address() forces compiler to emit
344 // frame pointers, even if they are not enabled.
345 EXPECT_NE(nullptr, __builtin_frame_address(0));
danakje75c6c812024-07-26 20:37:47346 ExpectStackFramePointers<Depth - 1>(frames);
dskiba79080da02016-04-23 00:10:27347
348 constexpr size_t frame_index = Depth - 1;
349 const void* frame = frames[frame_index];
350 EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index;
351 EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index;
Hans Wennborg4073b552023-03-13 17:39:18352code_end:
353 return;
354}
dskiba79080da02016-04-23 00:10:27355
Hans Wennborg4073b552023-03-13 17:39:18356template <>
danakje75c6c812024-07-26 20:37:47357NOINLINE NOOPT void ExpectStackFramePointers<1>(span<const void*> frames) {
Hans Wennborg4073b552023-03-13 17:39:18358code_start:
dskiba79080da02016-04-23 00:10:27359 // Calling __builtin_frame_address() forces compiler to emit
360 // frame pointers, even if they are not enabled.
361 EXPECT_NE(nullptr, __builtin_frame_address(0));
danakje75c6c812024-07-26 20:37:47362 size_t count = TraceStackFramePointers(frames, 0u);
363 ASSERT_EQ(frames.size(), count);
dskiba79080da02016-04-23 00:10:27364
365 const void* frame = frames[0];
366 EXPECT_GE(frame, &&code_start) << "For the top frame";
367 EXPECT_LE(frame, &&code_end) << "For the top frame";
Hans Wennborg4073b552023-03-13 17:39:18368code_end:
369 return;
370}
dskiba79080da02016-04-23 00:10:27371
372#if defined(MEMORY_SANITIZER)
373// The test triggers use-of-uninitialized-value errors on MSan bots.
374// This is expected because we're walking and reading the stack, and
375// sometimes we read fp / pc from the place that previously held
376// uninitialized value.
377#define MAYBE_TraceStackFramePointers DISABLED_TraceStackFramePointers
378#else
379#define MAYBE_TraceStackFramePointers TraceStackFramePointers
380#endif
381TEST_F(StackTraceTest, MAYBE_TraceStackFramePointers) {
382 constexpr size_t kDepth = 5;
383 const void* frames[kDepth];
danakje75c6c812024-07-26 20:37:47384 ExpectStackFramePointers<kDepth>(frames);
dskiba79080da02016-04-23 00:10:27385}
386
Xiaohan Wang131aa4d2022-01-15 19:39:41387#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
erikchend6b2b822017-02-22 21:10:31388#define MAYBE_StackEnd StackEnd
389#else
390#define MAYBE_StackEnd DISABLED_StackEnd
391#endif
392
393TEST_F(StackTraceTest, MAYBE_StackEnd) {
394 EXPECT_NE(0u, GetStackEnd());
395}
396
wez460b1242017-04-10 21:55:36397#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27398
Xiaohan Wang131aa4d2022-01-15 19:39:41399#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
Andre Kempeb54981c2021-04-13 08:59:53400
401#if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
402
Levi Zim14960c82025-10-09 16:12:39403#if defined(ARCH_CPU_X86_FAMILY)
404// Division by zero raising SIGFPE is mostly a x86 specific thing.
Andre Kempeb54981c2021-04-13 08:59:53405// On Arm architecture invalid math operations such as division by zero are not
406// trapped and do not trigger a SIGFPE.
Levi Zim14960c82025-10-09 16:12:39407// On RISC-V architecture, division by zero does not trigger SIGFPE.
408// Hence enable the test only for x86 platform
Andre Kempeb54981c2021-04-13 08:59:53409TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGFPE) {
410 // Values are volatile to prevent reordering of instructions, i.e. for
411 // optimization. Reordering may lead to tests erroneously failing due to
412 // SIGFPE being raised outside of EXPECT_EXIT.
413 volatile int const nominator = 23;
414 volatile int const denominator = 0;
Avi Drissmandea32052022-01-13 21:31:18415 [[maybe_unused]] volatile int result;
Andre Kempeb54981c2021-04-13 08:59:53416
417 EXPECT_EXIT(result = nominator / denominator,
418 ::testing::KilledBySignal(SIGFPE), "");
419}
Levi Zim14960c82025-10-09 16:12:39420#endif // defined(ARCH_CPU_X86_FAMILY)
Andre Kempeb54981c2021-04-13 08:59:53421
422TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGSEGV) {
423 // Pointee and pointer are volatile to prevent reordering of instructions,
424 // i.e. for optimization. Reordering may lead to tests erroneously failing due
425 // to SIGSEGV being raised outside of EXPECT_EXIT.
426 volatile int* const volatile p_int = nullptr;
427
428 EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "");
429}
430
Benoit Lizebf3f3aea2022-11-22 11:11:18431#if defined(ARCH_CPU_X86_64)
432TEST(CheckExitCodeAfterSignalHandlerDeathTest,
433 CheckSIGSEGVNonCanonicalAddress) {
434 // Pointee and pointer are volatile to prevent reordering of instructions,
435 // i.e. for optimization. Reordering may lead to tests erroneously failing due
436 // to SIGSEGV being raised outside of EXPECT_EXIT.
437 //
438 // On Linux, the upper half of the address space is reserved by the kernel, so
439 // all upper bits must be 0 for canonical addresses.
440 volatile int* const volatile p_int =
441 reinterpret_cast<int*>(0xabcdabcdabcdabcdULL);
442
443 EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "SI_KERNEL");
444}
445#endif
446
Andre Kempeb54981c2021-04-13 08:59:53447#endif // #if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
448
449TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGILL) {
Sorin Jianuad4cc6232024-10-08 19:06:01450 auto const raise_sigill = [] {
Andre Kempeb54981c2021-04-13 08:59:53451#if defined(ARCH_CPU_X86_FAMILY)
452 asm("ud2");
453#elif defined(ARCH_CPU_ARM_FAMILY)
454 asm("udf 0");
Levi Zim0e3083472025-10-09 16:13:43455#elif defined(ARCH_CPU_RISCV_FAMILY)
456 asm("unimp");
Andre Kempeb54981c2021-04-13 08:59:53457#else
458#error Unsupported platform!
459#endif
460 };
461
462 EXPECT_EXIT(raise_sigill(), ::testing::KilledBySignal(SIGILL), "");
463}
464
Xiaohan Wang131aa4d2022-01-15 19:39:41465#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
Andre Kempeb54981c2021-04-13 08:59:53466
Alex Goughd007d622025-09-11 17:55:49467#if BUILDFLAG(IS_WIN)
468TEST(StackTraceTest, EnabledStackTraces) {
469 // This is slightly pointless as this is also enabled by the test harness, but
470 // it ensures we are exercising the InProcessStackDumpingEnabled() path.
471 EXPECT_TRUE(base::debug::EnableInProcessStackDumping());
472 EXPECT_TRUE(base::debug::InProcessStackDumpingEnabled());
473}
Alex Gough0bbe87d2025-09-12 21:12:11474
475TEST(StackTraceTest, UnsymbolizedStackTraces) {
476 EXPECT_TRUE(base::debug::DisableInProcessStackDumpingForTesting());
477 EXPECT_FALSE(base::debug::InProcessStackDumpingEnabled());
478
479 StackTrace trace;
480 auto as_string = trace.ToString();
481 EXPECT_THAT(as_string,
482 ::testing::ContainsRegex("Dumping unresolved backtrace"));
483
484 // Restore global state.
485 EXPECT_TRUE(base::debug::EnableInProcessStackDumping());
486}
Alex Goughd007d622025-09-11 17:55:49487#endif // BUILDFLAG(IS_WIN)
488
Peter Kasting811504a72025-01-09 03:18:50489} // namespace base::debug