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 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. 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. 112 TEST(StackTrace, DebugPrintBacktrace) { 113 StackTrace().PrintBacktrace(); 114 } 115 116 } // namespace debug 117 } // namespace base 118