1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
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 <sstream>
6 #include <string>
7
8 #include "base/debug/stack_trace.h"
9 #include "base/logging.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace base {
13 namespace debug {
14
15 // Note: On Linux, this test currently only fully works on Debug builds.
16 // See comments in the #ifdef soup if you intend to change this.
17 #if defined(OS_WIN)
18 // Always fails on Windows: crbug.com/32070
19 #define MAYBE_OutputToStream FAILS_OutputToStream
20 #else
21 #define MAYBE_OutputToStream OutputToStream
22 #endif
TEST(StackTrace,MAYBE_OutputToStream)23 TEST(StackTrace, MAYBE_OutputToStream) {
24 StackTrace trace;
25
26 // Dump the trace into a string.
27 std::ostringstream os;
28 trace.OutputToStream(&os);
29 std::string backtrace_message = os.str();
30
31 #if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
32 // Stack traces require an extra data table that bloats our binaries,
33 // so they're turned off for release builds. We stop the test here,
34 // at least letting us verify that the calls don't crash.
35 return;
36 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
37
38 size_t frames_found = 0;
39 trace.Addresses(&frames_found);
40 ASSERT_GE(frames_found, 5u) <<
41 "No stack frames found. Skipping rest of test.";
42
43 // Check if the output has symbol initialization warning. If it does, fail.
44 ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
45 std::string::npos) <<
46 "Unable to resolve symbols. Skipping rest of test.";
47
48 #if defined(OS_MACOSX)
49 #if 0
50 // Disabled due to -fvisibility=hidden in build config.
51
52 // Symbol resolution via the backtrace_symbol function does not work well
53 // in OS X.
54 // See this thread:
55 //
56 // http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html
57 //
58 // Just check instead that we find our way back to the "start" symbol
59 // which should be the first symbol in the trace.
60 //
61 // TODO(port): Find a more reliable way to resolve symbols.
62
63 // Expect to at least find main.
64 EXPECT_TRUE(backtrace_message.find("start") != std::string::npos)
65 << "Expected to find start in backtrace:\n"
66 << backtrace_message;
67
68 #endif
69 #elif defined(__GLIBCXX__)
70 // This branch is for gcc-compiled code, but not Mac due to the
71 // above #if.
72 // Expect a demangled symbol.
73 EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") !=
74 std::string::npos)
75 << "Expected a demangled symbol in backtrace:\n"
76 << backtrace_message;
77
78 #elif 0
79 // This is the fall-through case; it used to cover Windows.
80 // But it's disabled because of varying buildbot configs;
81 // some lack symbols.
82
83 // Expect to at least find main.
84 EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
85 << "Expected to find main in backtrace:\n"
86 << backtrace_message;
87
88 #if defined(OS_WIN)
89 // MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with
90 // MSVC's __FUNCTION__ macro.
91 #define __func__ __FUNCTION__
92 #endif
93
94 // Expect to find this function as well.
95 // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
96 EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
97 << "Expected to find " << __func__ << " in backtrace:\n"
98 << backtrace_message;
99
100 #endif // define(OS_MACOSX)
101 }
102
103 // The test is used for manual testing, e.g., to see the raw output.
TEST(StackTrace,DebugOutputToStream)104 TEST(StackTrace, DebugOutputToStream) {
105 StackTrace trace;
106 std::ostringstream os;
107 trace.OutputToStream(&os);
108 VLOG(1) << os.str();
109 }
110
111 // The test is used for manual testing, e.g., to see the raw output.
TEST(StackTrace,DebugPrintBacktrace)112 TEST(StackTrace, DebugPrintBacktrace) {
113 StackTrace().PrintBacktrace();
114 }
115
116 } // namespace debug
117 } // namespace base
118