• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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