Home | History | Annotate | Download | only in debug
      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