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