blob: 7bba4535e1fe5e94161e942b30f4c25c47a284af [file] [log] [blame]
[email protected]d4114ba2011-10-12 16:13:401// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[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
aviebe805c2015-12-24 08:20:285#include <stddef.h>
6
[email protected]1e218b72012-11-14 19:32:237#include <limits>
[email protected]96fd0032009-04-24 00:13:088#include <sstream>
9#include <string>
10
Scott Violet44165792018-02-22 02:08:0811#include "base/debug/debugging_buildflags.h"
[email protected]58580352010-10-26 04:07:5012#include "base/debug/stack_trace.h"
[email protected]96fd0032009-04-24 00:13:0813#include "base/logging.h"
[email protected]dd4b51262013-07-25 21:38:2314#include "base/process/kill.h"
15#include "base/process/process_handle.h"
[email protected]1e218b72012-11-14 19:32:2316#include "base/test/test_timeouts.h"
aviebe805c2015-12-24 08:20:2817#include "build/build_config.h"
[email protected]96fd0032009-04-24 00:13:0818#include "testing/gtest/include/gtest/gtest.h"
[email protected]1e218b72012-11-14 19:32:2319#include "testing/multiprocess_func_list.h"
20
21#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
22#include "base/test/multiprocess_test.h"
23#endif
[email protected]96fd0032009-04-24 00:13:0824
[email protected]58580352010-10-26 04:07:5025namespace base {
26namespace debug {
27
[email protected]1e218b72012-11-14 19:32:2328#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
29typedef MultiProcessTest StackTraceTest;
30#else
31typedef testing::Test StackTraceTest;
32#endif
33
Mike West040aca72019-11-13 08:10:2134#if !defined(__UCLIBC__) && !defined(_AIX)
Wez7c0794d2019-11-14 18:30:4135// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX.
36// See https://crbug.com/706728
37
38TEST_F(StackTraceTest, OutputToStream) {
[email protected]96fd0032009-04-24 00:13:0839 StackTrace trace;
40
41 // Dump the trace into a string.
42 std::ostringstream os;
43 trace.OutputToStream(&os);
44 std::string backtrace_message = os.str();
45
[email protected]d4114ba2011-10-12 16:13:4046 // ToString() should produce the same output.
47 EXPECT_EQ(backtrace_message, trace.ToString());
48
Mike West040aca72019-11-13 08:10:2149 size_t frames_found = 0;
Wez7c0794d2019-11-14 18:30:4150 const void* const* addresses = trace.Addresses(&frames_found);
51
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5852#if defined(OFFICIAL_BUILD) && \
53 ((defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA))
Wez7c0794d2019-11-14 18:30:4154 // Stack traces require an extra data table that bloats our binaries,
55 // so they're turned off for official builds. Stop the test here, so
56 // it at least verifies that StackTrace calls don't crash.
57 return;
Fabrice de Gans-Riberi4c5ebe42019-11-20 04:45:5858#endif // defined(OFFICIAL_BUILD) &&
59 // ((defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA))
Wezeaf15532019-11-15 22:00:3160
Wez7c0794d2019-11-14 18:30:4161 ASSERT_TRUE(addresses);
62 ASSERT_GT(frames_found, 5u) << "Too few frames found.";
63
64#if defined(OS_FUCHSIA) || defined(OS_ANDROID)
65 // Under Fuchsia and Android, StackTrace emits executable build-Ids and
66 // address offsets which are symbolized on the test host system, rather than
67 // being symbolized in-process.
68 return;
69#endif // defined(OS_FUCHSIA) || defined(OS_ANDROID)
70
71#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
72 defined(MEMORY_SANITIZER)
73 // Sanitizer configurations (ASan, TSan, MSan) emit unsymbolized stacks.
74 return;
75#endif // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||
76 // defined(MEMORY_SANITIZER)
[email protected]96fd0032009-04-24 00:13:0877
78 // Check if the output has symbol initialization warning. If it does, fail.
[email protected]de1b764f2009-08-24 15:36:4179 ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
Wez7c0794d2019-11-14 18:30:4180 std::string::npos)
81 << "Unable to resolve symbols.";
[email protected]96fd0032009-04-24 00:13:0882
[email protected]79b6fa62009-10-14 03:01:4483 // Expect a demangled symbol.
Wez7c0794d2019-11-14 18:30:4184 // Note that Windows Release builds omit the function parameters from the
85 // demangled stack output, otherwise this could be "testing::Test::Run()".
86 EXPECT_TRUE(backtrace_message.find("testing::Test::Run") != std::string::npos)
[email protected]79b6fa62009-10-14 03:01:4487 << "Expected a demangled symbol in backtrace:\n"
88 << backtrace_message;
[email protected]889da7e42009-12-31 02:28:0989
[email protected]96fd0032009-04-24 00:13:0890 // Expect to at least find main.
91 EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
92 << "Expected to find main in backtrace:\n"
93 << backtrace_message;
94
[email protected]96fd0032009-04-24 00:13:0895 // Expect to find this function as well.
96 // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
97 EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
98 << "Expected to find " << __func__ << " in backtrace:\n"
99 << backtrace_message;
[email protected]96fd0032009-04-24 00:13:08100}
[email protected]48c27f72010-01-26 06:26:26101
halliwell5e1e4fa2017-03-28 03:21:08102#if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
wezec97f912017-02-05 01:29:25103// Disabled in Official builds, where Link-Time Optimization can result in two
104// or fewer stack frames being available, causing the test to fail.
wez73f8d7e2017-01-29 06:18:13105TEST_F(StackTraceTest, TruncatedTrace) {
106 StackTrace trace;
107
108 size_t count = 0;
109 trace.Addresses(&count);
110 ASSERT_LT(2u, count);
111
112 StackTrace truncated(2);
113 truncated.Addresses(&count);
114 EXPECT_EQ(2u, count);
115}
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) {
139 StackTrace().PrintWithPrefix(nullptr);
140}
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;
146 const char* prefix_string = "[test]";
147 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;
160 trace.OutputToStreamWithPrefix(&os, nullptr);
161 trace.ToStringWithPrefix(nullptr);
162}
163
Wez7c0794d2019-11-14 18:30:41164#endif // !defined(__UCLIBC__) && !defined(_AIX)
[email protected]58580352010-10-26 04:07:50165
Wez35539132018-07-17 11:26:05166#if defined(OS_POSIX) && !defined(OS_ANDROID)
[email protected]1e218b72012-11-14 19:32:23167#if !defined(OS_IOS)
hanscd4cce32015-05-19 17:03:14168static char* newArray() {
169 // Clang warns about the mismatched new[]/delete if they occur in the same
170 // function.
171 return new char[10];
172}
173
[email protected]1e218b72012-11-14 19:32:23174MULTIPROCESS_TEST_MAIN(MismatchedMallocChildProcess) {
hanscd4cce32015-05-19 17:03:14175 char* pointer = newArray();
[email protected]1e218b72012-11-14 19:32:23176 delete pointer;
177 return 2;
178}
179
180// Regression test for StackDumpingSignalHandler async-signal unsafety.
181// Combined with tcmalloc's debugallocation, that signal handler
182// and e.g. mismatched new[]/delete would cause a hang because
183// of re-entering malloc.
184TEST_F(StackTraceTest, AsyncSignalUnsafeSignalHandlerHang) {
Jay Civelli4a44260b2017-08-21 19:26:29185 Process child = SpawnChild("MismatchedMallocChildProcess");
186 ASSERT_TRUE(child.IsValid());
rvargas2f70a152015-02-24 00:28:11187 int exit_code;
Jay Civelli4a44260b2017-08-21 19:26:29188 ASSERT_TRUE(
189 child.WaitForExitWithTimeout(TestTimeouts::action_timeout(), &exit_code));
[email protected]1e218b72012-11-14 19:32:23190}
191#endif // !defined(OS_IOS)
192
193namespace {
194
[email protected]22d5b9822013-01-10 18:21:52195std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
[email protected]1e218b72012-11-14 19:32:23196 char buffer[1024];
197 CHECK_LE(sz, sizeof(buffer));
198
[email protected]22d5b9822013-01-10 18:21:52199 char* result = internal::itoa_r(i, buffer, sz, base, padding);
[email protected]1e218b72012-11-14 19:32:23200 EXPECT_TRUE(result);
201 return std::string(buffer);
202}
203
204} // namespace
205
206TEST_F(StackTraceTest, itoa_r) {
[email protected]22d5b9822013-01-10 18:21:52207 EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
208 EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23209
210 // Test edge cases.
211 if (sizeof(intptr_t) == 4) {
[email protected]22d5b9822013-01-10 18:21:52212 EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23213 EXPECT_EQ("-2147483648",
[email protected]22d5b9822013-01-10 18:21:52214 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23215 EXPECT_EQ("2147483647",
[email protected]22d5b9822013-01-10 18:21:52216 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23217
218 EXPECT_EQ("80000000",
[email protected]22d5b9822013-01-10 18:21:52219 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23220 EXPECT_EQ("7fffffff",
[email protected]22d5b9822013-01-10 18:21:52221 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23222 } else if (sizeof(intptr_t) == 8) {
[email protected]22d5b9822013-01-10 18:21:52223 EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23224 EXPECT_EQ("-9223372036854775808",
[email protected]22d5b9822013-01-10 18:21:52225 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23226 EXPECT_EQ("9223372036854775807",
[email protected]22d5b9822013-01-10 18:21:52227 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
[email protected]1e218b72012-11-14 19:32:23228
229 EXPECT_EQ("8000000000000000",
[email protected]22d5b9822013-01-10 18:21:52230 itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23231 EXPECT_EQ("7fffffffffffffff",
[email protected]22d5b9822013-01-10 18:21:52232 itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23233 } else {
234 ADD_FAILURE() << "Missing test case for your size of intptr_t ("
235 << sizeof(intptr_t) << ")";
236 }
237
238 // Test hex output.
[email protected]22d5b9822013-01-10 18:21:52239 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
240 EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
[email protected]1e218b72012-11-14 19:32:23241
242 // Check that itoa_r respects passed buffer size limit.
243 char buffer[1024];
[email protected]22d5b9822013-01-10 18:21:52244 EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 10, 16, 0));
245 EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 9, 16, 0));
246 EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 8, 16, 0));
247 EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 7, 16, 0));
248 EXPECT_TRUE(internal::itoa_r(0xbeef, buffer, 5, 16, 4));
249 EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 5));
250 EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 6));
251
252 // Test padding.
253 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
254 EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
255 EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
256 EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
257 EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
258 EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
259 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
260 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
261 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
262 EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
263 EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
264 EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
[email protected]1e218b72012-11-14 19:32:23265}
Wez35539132018-07-17 11:26:05266#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
[email protected]1e218b72012-11-14 19:32:23267
wez460b1242017-04-10 21:55:36268#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
erikchenf7c8a0d2017-04-06 21:15:27269
dskiba79080da02016-04-23 00:10:27270template <size_t Depth>
271void NOINLINE ExpectStackFramePointers(const void** frames,
272 size_t max_depth) {
273 code_start:
274 // Calling __builtin_frame_address() forces compiler to emit
275 // frame pointers, even if they are not enabled.
276 EXPECT_NE(nullptr, __builtin_frame_address(0));
277 ExpectStackFramePointers<Depth - 1>(frames, max_depth);
278
279 constexpr size_t frame_index = Depth - 1;
280 const void* frame = frames[frame_index];
281 EXPECT_GE(frame, &&code_start) << "For frame at index " << frame_index;
282 EXPECT_LE(frame, &&code_end) << "For frame at index " << frame_index;
283 code_end: return;
284}
285
286template <>
287void NOINLINE ExpectStackFramePointers<1>(const void** frames,
288 size_t max_depth) {
289 code_start:
290 // Calling __builtin_frame_address() forces compiler to emit
291 // frame pointers, even if they are not enabled.
292 EXPECT_NE(nullptr, __builtin_frame_address(0));
293 size_t count = TraceStackFramePointers(frames, max_depth, 0);
294 ASSERT_EQ(max_depth, count);
295
296 const void* frame = frames[0];
297 EXPECT_GE(frame, &&code_start) << "For the top frame";
298 EXPECT_LE(frame, &&code_end) << "For the top frame";
299 code_end: return;
300}
301
302#if defined(MEMORY_SANITIZER)
303// The test triggers use-of-uninitialized-value errors on MSan bots.
304// This is expected because we're walking and reading the stack, and
305// sometimes we read fp / pc from the place that previously held
306// uninitialized value.
307#define MAYBE_TraceStackFramePointers DISABLED_TraceStackFramePointers
308#else
309#define MAYBE_TraceStackFramePointers TraceStackFramePointers
310#endif
311TEST_F(StackTraceTest, MAYBE_TraceStackFramePointers) {
312 constexpr size_t kDepth = 5;
313 const void* frames[kDepth];
314 ExpectStackFramePointers<kDepth>(frames, kDepth);
315}
316
erikchend6b2b822017-02-22 21:10:31317#if defined(OS_ANDROID) || defined(OS_MACOSX)
318#define MAYBE_StackEnd StackEnd
319#else
320#define MAYBE_StackEnd DISABLED_StackEnd
321#endif
322
323TEST_F(StackTraceTest, MAYBE_StackEnd) {
324 EXPECT_NE(0u, GetStackEnd());
325}
326
wez460b1242017-04-10 21:55:36327#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27328
[email protected]58580352010-10-26 04:07:50329} // namespace debug
330} // namespace base