blob: 15918b7488da0a884404a7a0c88cd50160a3b43f [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"
danakj51d26a42024-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"
14#include "base/containers/span.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"
[email protected]96fd0032009-04-24 00:13:0826#include "testing/gtest/include/gtest/gtest.h"
[email protected]1e218b72012-11-14 19:32:2327#include "testing/multiprocess_func_list.h"
Arthur Sonzogni62e877a2024-04-30 16:09:4328#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
Yuki Shiino985ab91e2024-03-14 07:20:4629#include "partition_alloc/shim/allocator_shim.h"
Takashi Sakamotob9980552023-10-17 20:14:1130#endif
31
Xiaohan Wang131aa4d2022-01-15 19:39:4132#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
[email protected]1e218b72012-11-14 19:32:2333#include "base/test/multiprocess_test.h"
34#endif
[email protected]96fd0032009-04-24 00:13:0835
Peter Kasting811504a72025-01-09 03:18:5036namespace base::debug {
[email protected]58580352010-10-26 04:07:5037
Xiaohan Wang131aa4d2022-01-15 19:39:4138#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
[email protected]1e218b72012-11-14 19:32:2339typedef MultiProcessTest StackTraceTest;
40#else
41typedef testing::Test StackTraceTest;
42#endif
Takashi Sakamotob9980552023-10-17 20:14:1143typedef testing::Test StackTraceDeathTest;
[email protected]1e218b72012-11-14 19:32:2344
Mike West040aca72019-11-13 08:10:2145#if !defined(__UCLIBC__) && !defined(_AIX)
Wez7c0794d2019-11-14 18:30:4146// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX.
47// See https://crbug.com/706728
48
49TEST_F(StackTraceTest, OutputToStream) {
[email protected]96fd0032009-04-24 00:13:0850 StackTrace trace;
51
52 // Dump the trace into a string.
53 std::ostringstream os;
54 trace.OutputToStream(&os);
55 std::string backtrace_message = os.str();
56
[email protected]d4114ba2011-10-12 16:13:4057 // ToString() should produce the same output.
58 EXPECT_EQ(backtrace_message, trace.ToString());
59
Daniel Chenga0e290d2023-10-16 18:47:2460 span<const void* const> addresses = trace.addresses();
Wez7c0794d2019-11-14 18:30:4161
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5862#if defined(OFFICIAL_BUILD) && \
Xiaohan Wang131aa4d2022-01-15 19:39:4163 ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) || BUILDFLAG(IS_FUCHSIA))
Wez7c0794d2019-11-14 18:30:4164 // Stack traces require an extra data table that bloats our binaries,
65 // so they're turned off for official builds. Stop the test here, so
66 // it at least verifies that StackTrace calls don't crash.
67 return;
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5868#endif // defined(OFFICIAL_BUILD) &&
Xiaohan Wang131aa4d2022-01-15 19:39:4169 // ((BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)) ||
70 // BUILDFLAG(IS_FUCHSIA))
Wezeaf15532019-11-15 22:00:3171
Daniel Chenga0e290d2023-10-16 18:47:2472 ASSERT_GT(addresses.size(), 5u) << "Too few frames found.";
Peter Kasting654bb6252024-11-16 02:29:0873 ASSERT_NE(nullptr, addresses[0]);
Wez7c0794d2019-11-14 18:30:4174
Peter Kasting134ef9af2024-12-28 02:30:0975 if (!StackTrace::WillSymbolizeToStreamForTesting()) {
Gabriel Charetteae1bb012021-05-06 19:31:2176 return;
Peter Kasting134ef9af2024-12-28 02:30:0977 }
[email protected]96fd0032009-04-24 00:13:0878
79 // Check if the output has symbol initialization warning. If it does, fail.
[email protected]de1b764f2009-08-24 15:36:4180 ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
Wez7c0794d2019-11-14 18:30:4181 std::string::npos)
82 << "Unable to resolve symbols.";
[email protected]96fd0032009-04-24 00:13:0883
[email protected]79b6fa62009-10-14 03:01:4484 // Expect a demangled symbol.
Wez7c0794d2019-11-14 18:30:4185 // Note that Windows Release builds omit the function parameters from the
Zequan Wu76eee5e92020-07-06 17:38:4086 // demangled stack output, otherwise this could be "testing::UnitTest::Run()".
87 EXPECT_TRUE(backtrace_message.find("testing::UnitTest::Run") !=
88 std::string::npos)
[email protected]79b6fa62009-10-14 03:01:4489 << "Expected a demangled symbol in backtrace:\n"
90 << backtrace_message;
[email protected]889da7e42009-12-31 02:28:0991
[email protected]96fd0032009-04-24 00:13:0892 // 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
[email protected]96fd0032009-04-24 00:13:0897 // 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;
[email protected]96fd0032009-04-24 00:13:08102}
[email protected]48c27f72010-01-26 06:26:26103
halliwell5e1e4fa2017-03-28 03:21:08104#if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
wezec97f912017-02-05 01:29:25105// Disabled in Official builds, where Link-Time Optimization can result in two
106// or fewer stack frames being available, causing the test to fail.
wez73f8d7e2017-01-29 06:18:13107TEST_F(StackTraceTest, TruncatedTrace) {
108 StackTrace trace;
109
Daniel Chenga0e290d2023-10-16 18:47:24110 ASSERT_LT(2u, trace.addresses().size());
wez73f8d7e2017-01-29 06:18:13111
112 StackTrace truncated(2);
Daniel Chenga0e290d2023-10-16 18:47:24113 EXPECT_EQ(2u, truncated.addresses().size());
wez73f8d7e2017-01-29 06:18:13114}
Wez7c0794d2019-11-14 18:30:41115#endif // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
wez73f8d7e2017-01-29 06:18:13116
[email protected]a15115f02010-05-25 20:07:12117// The test is used for manual testing, e.g., to see the raw output.
scottmgf063a7e2015-02-25 00:17:30118TEST_F(StackTraceTest, DebugOutputToStream) {
[email protected]48c27f72010-01-26 06:26:26119 StackTrace trace;
120 std::ostringstream os;
121 trace.OutputToStream(&os);
[email protected]b026e35d2010-10-19 02:31:03122 VLOG(1) << os.str();
[email protected]48c27f72010-01-26 06:26:26123}
124
[email protected]a15115f02010-05-25 20:07:12125// The test is used for manual testing, e.g., to see the raw output.
scottmgf063a7e2015-02-25 00:17:30126TEST_F(StackTraceTest, DebugPrintBacktrace) {
[email protected]5ddbf1c2013-08-29 01:59:38127 StackTrace().Print();
[email protected]48c27f72010-01-26 06:26:26128}
Mason Freedb9ef2b62018-09-10 17:17:27129
130// The test is used for manual testing, e.g., to see the raw output.
131TEST_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.
137TEST_F(StackTraceTest, DebugPrintWithNullPrefixBacktrace) {
Greg Thompson8b1b295b2024-04-10 07:44:14138 StackTrace().PrintWithPrefix({});
Mason Freedb9ef2b62018-09-10 17:17:27139}
140
141// Test OutputToStreamWithPrefix, mainly to make sure it doesn't
142// crash. Any "real" stack trace testing happens above.
143TEST_F(StackTraceTest, DebugOutputToStreamWithPrefix) {
144 StackTrace trace;
Greg Thompson8b1b295b2024-04-10 07:44:14145 cstring_view prefix_string = "[test]";
Mason Freedb9ef2b62018-09-10 17:17:27146 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.
156TEST_F(StackTraceTest, DebugOutputToStreamWithNullPrefix) {
157 StackTrace trace;
158 std::ostringstream os;
Greg Thompson8b1b295b2024-04-10 07:44:14159 trace.OutputToStreamWithPrefix(&os, {});
160 trace.ToStringWithPrefix({});
Mason Freedb9ef2b62018-09-10 17:17:27161}
162
Wez7c0794d2019-11-14 18:30:41163#endif // !defined(__UCLIBC__) && !defined(_AIX)
[email protected]58580352010-10-26 04:07:50164
Xiaohan Wang131aa4d2022-01-15 19:39:41165#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
Takashi Sakamotob9980552023-10-17 20:14:11166// Since Mac's base::debug::StackTrace().Print() is not malloc-free, skip
167// StackDumpSignalHandlerIsMallocFree if BUILDFLAG(IS_MAC).
Arthur Sonzogni62e877a2024-04-30 16:09:43168#if PA_BUILDFLAG(USE_ALLOCATOR_SHIM) && !BUILDFLAG(IS_MAC)
Takashi Sakamotob9980552023-10-17 20:14:11169
170namespace {
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.
Yuki Shiino3b110492024-08-08 06:11:22176void* BadMalloc(size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11177 base::ImmediateCrash();
hanscd4cce32015-05-19 17:03:14178}
179
Yuki Shiino3b110492024-08-08 06:11:22180void* BadCalloc(size_t, size_t, void* context) {
Takashi Sakamotob9980552023-10-17 20:14:11181 base::ImmediateCrash();
[email protected]1e218b72012-11-14 19:32:23182}
183
Yuki Shiino3b110492024-08-08 06:11:22184void* BadAlignedAlloc(size_t, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11185 base::ImmediateCrash();
[email protected]1e218b72012-11-14 19:32:23186}
Takashi Sakamotob9980552023-10-17 20:14:11187
Yuki Shiino3b110492024-08-08 06:11:22188void* BadAlignedRealloc(void*, size_t, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11189 base::ImmediateCrash();
190}
191
Yuki Shiino3b110492024-08-08 06:11:22192void* BadRealloc(void*, size_t, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11193 base::ImmediateCrash();
194}
195
Yuki Shiino3b110492024-08-08 06:11:22196void BadFree(void*, void*) {
Takashi Sakamotob9980552023-10-17 20:14:11197 base::ImmediateCrash();
198}
199
200allocator_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 */
danakj19cd9b82024-07-05 14:03:40206 &BadRealloc, /* realloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11207 &BadFree, /* free_function */
mikt989d9782025-04-23 12:45:18208 nullptr, /* free_with_size_function */
209 nullptr, /* free_with_alignment_function */
210 nullptr, /* free_with_size_and_alignment_function */
Takashi Sakamotob9980552023-10-17 20:14:11211 nullptr, /* get_size_estimate_function */
Benoit Lizecd75515a2023-11-29 14:47:42212 nullptr, /* good_size_function */
Takashi Sakamotob9980552023-10-17 20:14:11213 nullptr, /* claimed_address_function */
214 nullptr, /* batch_malloc_function */
215 nullptr, /* batch_free_function */
Takashi Sakamotob9980552023-10-17 20:14:11216 nullptr, /* try_free_default_function */
217 &BadAlignedAlloc, /* aligned_malloc_function */
danakj19cd9b82024-07-05 14:03:40218 &BadAlignedAlloc, /* aligned_malloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11219 &BadAlignedRealloc, /* aligned_realloc_function */
danakj19cd9b82024-07-05 14:03:40220 &BadAlignedRealloc, /* aligned_realloc_unchecked_function */
Takashi Sakamotob9980552023-10-17 20:14:11221 &BadFree, /* aligned_free_function */
222 nullptr, /* next */
223};
224
225} // namespace
226
227// Regression test for StackDumpSignalHandler async-signal unsafety.
228// Since malloc() is not guaranteed to be async signal safe, it is not allowed
229// to use malloc() inside StackDumpSignalHandler().
230TEST_F(StackTraceDeathTest, StackDumpSignalHandlerIsMallocFree) {
231 EXPECT_DEATH_IF_SUPPORTED(
232 [] {
233 // On Android, base::debug::EnableInProcessStackDumping() does not
234 // change any actions taken by signals to be StackDumpSignalHandler. So
235 // the StackDumpSignalHandlerIsMallocFree test doesn't work on Android.
236 EnableInProcessStackDumping();
237 allocator_shim::InsertAllocatorDispatch(&g_bad_malloc_dispatch);
238 // Raise SIGSEGV to invoke StackDumpSignalHandler().
239 kill(getpid(), SIGSEGV);
240 }(),
241 "\\[end of stack trace\\]\n");
242}
Arthur Sonzogni62e877a2024-04-30 16:09:43243#endif // PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
[email protected]1e218b72012-11-14 19:32:23244
245namespace {
246
[email protected]22d5b9822013-01-10 18:21:52247std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
danakjd53babfe2024-10-09 14:04:16248 std::array<char, 1024> buffer;
249 internal::itoa_r(i, base, padding, base::span(buffer).first(sz));
250 EXPECT_NE(buffer[0], '\0');
251 for (char c : buffer) {
252 if (c == '\0') {
253 return std::string(buffer.data());
254 }
255 }
256 ADD_FAILURE() << "buffer is not NUL terminated";
257 return std::string("");
[email protected]1e218b72012-11-14 19:32:23258}
259
260} // namespace
261
262TEST_F(StackTraceTest, itoa_r) {
[email protected]22d5b9822013-01-10 18:21:52263 EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
264 EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23265
266 // Test edge cases.
267 if (sizeof(intptr_t) == 4) {
[email protected]22d5b9822013-01-10 18:21:52268 EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23269 EXPECT_EQ("-2147483648",
[email protected]22d5b9822013-01-10 18:21:52270 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23271 EXPECT_EQ("2147483647",
[email protected]22d5b9822013-01-10 18:21:52272 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23273
274 EXPECT_EQ("80000000",
[email protected]22d5b9822013-01-10 18:21:52275 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23276 EXPECT_EQ("7fffffff",
[email protected]22d5b9822013-01-10 18:21:52277 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23278 } else if (sizeof(intptr_t) == 8) {
[email protected]22d5b9822013-01-10 18:21:52279 EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23280 EXPECT_EQ("-9223372036854775808",
[email protected]22d5b9822013-01-10 18:21:52281 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23282 EXPECT_EQ("9223372036854775807",
[email protected]22d5b9822013-01-10 18:21:52283 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23284
285 EXPECT_EQ("8000000000000000",
[email protected]22d5b9822013-01-10 18:21:52286 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23287 EXPECT_EQ("7fffffffffffffff",
[email protected]22d5b9822013-01-10 18:21:52288 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23289 } else {
290 ADD_FAILURE() << "Missing test case for your size of intptr_t ("
291 << sizeof(intptr_t) << ")";
292 }
293
294 // Test hex output.
[email protected]22d5b9822013-01-10 18:21:52295 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
296 EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23297
298 // Check that itoa_r respects passed buffer size limit.
danakjd53babfe2024-10-09 14:04:16299 std::array<char, 1024> buffer;
300 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(10u));
301 EXPECT_NE(buffer[0u], '\0');
302 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(9u));
303 EXPECT_NE(buffer[0u], '\0');
304 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(8u));
305 EXPECT_EQ(buffer[0u], '\0');
306 internal::itoa_r(0xdeadbeef, 16, 0, base::span(buffer).first(7u));
307 EXPECT_EQ(buffer[0u], '\0');
308 internal::itoa_r(0xbeef, 16, 4, base::span(buffer).first(5u));
309 EXPECT_NE(buffer[0u], '\0');
310 internal::itoa_r(0xbeef, 16, 5, base::span(buffer).first(5u));
311 EXPECT_EQ(buffer[0u], '\0');
312 internal::itoa_r(0xbeef, 16, 6, base::span(buffer).first(5u));
313 EXPECT_EQ(buffer[0u], '\0');
[email protected]22d5b9822013-01-10 18:21:52314
315 // Test padding.
316 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
317 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
318 EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
319 EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
320 EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
321 EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
322 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
323 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
324 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
325 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
326 EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
327 EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
[email protected]1e218b72012-11-14 19:32:23328}
Xiaohan Wang131aa4d2022-01-15 19:39:41329#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
[email protected]1e218b72012-11-14 19:32:23330
wez460b1242017-04-10 21:55:36331#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
erikchenf7c8a0d2017-04-06 21:15:27332
ssidc1d5a3d2020-09-11 05:20:30333class CopyFunction : public StackCopier {
334 public:
335 using StackCopier::CopyStackContentsAndRewritePointers;
336};
337
dskiba79080da02016-04-23 00:10:27338template <size_t Depth>
danakje75c6c812024-07-26 20:37:47339NOINLINE NOOPT void ExpectStackFramePointers(span<const void*> frames) {
Peter Kastingf541f7782023-03-10 23:44:46340code_start:
dskiba79080da02016-04-23 00:10:27341 // Calling __builtin_frame_address() forces compiler to emit
342 // frame pointers, even if they are not enabled.
343 EXPECT_NE(nullptr, __builtin_frame_address(0));
danakje75c6c812024-07-26 20:37:47344 ExpectStackFramePointers<Depth - 1>(frames);
dskiba79080da02016-04-23 00:10:27345
346 constexpr size_t frame_index = Depth - 1;
347 const void* frame = frames[frame_index];
348 EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index;
349 EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index;
Hans Wennborg4073b552023-03-13 17:39:18350code_end:
351 return;
352}
dskiba79080da02016-04-23 00:10:27353
Hans Wennborg4073b552023-03-13 17:39:18354template <>
danakje75c6c812024-07-26 20:37:47355NOINLINE NOOPT void ExpectStackFramePointers<1>(span<const void*> frames) {
Hans Wennborg4073b552023-03-13 17:39:18356code_start:
dskiba79080da02016-04-23 00:10:27357 // Calling __builtin_frame_address() forces compiler to emit
358 // frame pointers, even if they are not enabled.
359 EXPECT_NE(nullptr, __builtin_frame_address(0));
danakje75c6c812024-07-26 20:37:47360 size_t count = TraceStackFramePointers(frames, 0u);
361 ASSERT_EQ(frames.size(), count);
dskiba79080da02016-04-23 00:10:27362
363 const void* frame = frames[0];
364 EXPECT_GE(frame, &&code_start) << "For the top frame";
365 EXPECT_LE(frame, &&code_end) << "For the top frame";
Hans Wennborg4073b552023-03-13 17:39:18366code_end:
367 return;
368}
dskiba79080da02016-04-23 00:10:27369
370#if defined(MEMORY_SANITIZER)
371// The test triggers use-of-uninitialized-value errors on MSan bots.
372// This is expected because we're walking and reading the stack, and
373// sometimes we read fp / pc from the place that previously held
374// uninitialized value.
375#define MAYBE_TraceStackFramePointers DISABLED_TraceStackFramePointers
376#else
377#define MAYBE_TraceStackFramePointers TraceStackFramePointers
378#endif
379TEST_F(StackTraceTest, MAYBE_TraceStackFramePointers) {
380 constexpr size_t kDepth = 5;
381 const void* frames[kDepth];
danakje75c6c812024-07-26 20:37:47382 ExpectStackFramePointers<kDepth>(frames);
dskiba79080da02016-04-23 00:10:27383}
384
Xiaohan Wang131aa4d2022-01-15 19:39:41385#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
erikchend6b2b822017-02-22 21:10:31386#define MAYBE_StackEnd StackEnd
387#else
388#define MAYBE_StackEnd DISABLED_StackEnd
389#endif
390
391TEST_F(StackTraceTest, MAYBE_StackEnd) {
392 EXPECT_NE(0u, GetStackEnd());
393}
394
wez460b1242017-04-10 21:55:36395#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27396
Xiaohan Wang131aa4d2022-01-15 19:39:41397#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
Andre Kempeb54981c2021-04-13 08:59:53398
399#if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
400
401#if !defined(ARCH_CPU_ARM_FAMILY)
402// On Arm architecture invalid math operations such as division by zero are not
403// trapped and do not trigger a SIGFPE.
404// Hence disable the test for Arm platforms.
405TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGFPE) {
406 // Values are volatile to prevent reordering of instructions, i.e. for
407 // optimization. Reordering may lead to tests erroneously failing due to
408 // SIGFPE being raised outside of EXPECT_EXIT.
409 volatile int const nominator = 23;
410 volatile int const denominator = 0;
Avi Drissmandea32052022-01-13 21:31:18411 [[maybe_unused]] volatile int result;
Andre Kempeb54981c2021-04-13 08:59:53412
413 EXPECT_EXIT(result = nominator / denominator,
414 ::testing::KilledBySignal(SIGFPE), "");
415}
416#endif // !defined(ARCH_CPU_ARM_FAMILY)
417
418TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGSEGV) {
419 // Pointee and pointer are volatile to prevent reordering of instructions,
420 // i.e. for optimization. Reordering may lead to tests erroneously failing due
421 // to SIGSEGV being raised outside of EXPECT_EXIT.
422 volatile int* const volatile p_int = nullptr;
423
424 EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "");
425}
426
Benoit Lizebf3f3aea2022-11-22 11:11:18427#if defined(ARCH_CPU_X86_64)
428TEST(CheckExitCodeAfterSignalHandlerDeathTest,
429 CheckSIGSEGVNonCanonicalAddress) {
430 // Pointee and pointer are volatile to prevent reordering of instructions,
431 // i.e. for optimization. Reordering may lead to tests erroneously failing due
432 // to SIGSEGV being raised outside of EXPECT_EXIT.
433 //
434 // On Linux, the upper half of the address space is reserved by the kernel, so
435 // all upper bits must be 0 for canonical addresses.
436 volatile int* const volatile p_int =
437 reinterpret_cast<int*>(0xabcdabcdabcdabcdULL);
438
439 EXPECT_EXIT(*p_int = 1234, ::testing::KilledBySignal(SIGSEGV), "SI_KERNEL");
440}
441#endif
442
Andre Kempeb54981c2021-04-13 08:59:53443#endif // #if !defined(ADDRESS_SANITIZER) && !defined(UNDEFINED_SANITIZER)
444
445TEST(CheckExitCodeAfterSignalHandlerDeathTest, CheckSIGILL) {
Sorin Jianuad4cc6232024-10-08 19:06:01446 auto const raise_sigill = [] {
Andre Kempeb54981c2021-04-13 08:59:53447#if defined(ARCH_CPU_X86_FAMILY)
448 asm("ud2");
449#elif defined(ARCH_CPU_ARM_FAMILY)
450 asm("udf 0");
451#else
452#error Unsupported platform!
453#endif
454 };
455
456 EXPECT_EXIT(raise_sigill(), ::testing::KilledBySignal(SIGILL), "");
457}
458
Xiaohan Wang131aa4d2022-01-15 19:39:41459#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
Andre Kempeb54981c2021-04-13 08:59:53460
Peter Kasting811504a72025-01-09 03:18:50461} // namespace base::debug