Home | History | Annotate | Download | only in debug
      1 // Copyright (c) 2011 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 <limits>
      6 #include <sstream>
      7 #include <string>
      8 
      9 #include "base/debug/stack_trace.h"
     10 #include "base/logging.h"
     11 #include "base/process/kill.h"
     12 #include "base/process/process_handle.h"
     13 #include "base/test/test_timeouts.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "testing/multiprocess_func_list.h"
     16 
     17 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
     18 #include "base/test/multiprocess_test.h"
     19 #endif
     20 
     21 namespace base {
     22 namespace debug {
     23 
     24 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
     25 typedef MultiProcessTest StackTraceTest;
     26 #else
     27 typedef testing::Test StackTraceTest;
     28 #endif
     29 
     30 // Note: On Linux, this test currently only fully works on Debug builds.
     31 // See comments in the #ifdef soup if you intend to change this.
     32 #if defined(OS_WIN)
     33 // Always fails on Windows: crbug.com/32070
     34 #define MAYBE_OutputToStream DISABLED_OutputToStream
     35 #else
     36 #define MAYBE_OutputToStream OutputToStream
     37 #endif
     38 TEST_F(StackTraceTest, MAYBE_OutputToStream) {
     39   StackTrace trace;
     40 
     41   // Dump the trace into a string.
     42   std::ostringstream os;
     43   trace.OutputToStream(&os);
     44   std::string backtrace_message = os.str();
     45 
     46   // ToString() should produce the same output.
     47   EXPECT_EQ(backtrace_message, trace.ToString());
     48 
     49 #if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
     50   // Stack traces require an extra data table that bloats our binaries,
     51   // so they're turned off for release builds.  We stop the test here,
     52   // at least letting us verify that the calls don't crash.
     53   return;
     54 #endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG
     55 
     56   size_t frames_found = 0;
     57   trace.Addresses(&frames_found);
     58   ASSERT_GE(frames_found, 5u) <<
     59       "No stack frames found.  Skipping rest of test.";
     60 
     61   // Check if the output has symbol initialization warning.  If it does, fail.
     62   ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"),
     63             std::string::npos) <<
     64       "Unable to resolve symbols.  Skipping rest of test.";
     65 
     66 #if defined(OS_MACOSX)
     67 #if 0
     68   // Disabled due to -fvisibility=hidden in build config.
     69 
     70   // Symbol resolution via the backtrace_symbol function does not work well
     71   // in OS X.
     72   // See this thread:
     73   //
     74   //    http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html
     75   //
     76   // Just check instead that we find our way back to the "start" symbol
     77   // which should be the first symbol in the trace.
     78   //
     79   // TODO(port): Find a more reliable way to resolve symbols.
     80 
     81   // Expect to at least find main.
     82   EXPECT_TRUE(backtrace_message.find("start") != std::string::npos)
     83       << "Expected to find start in backtrace:\n"
     84       << backtrace_message;
     85 
     86 #endif
     87 #elif defined(USE_SYMBOLIZE)
     88   // This branch is for gcc-compiled code, but not Mac due to the
     89   // above #if.
     90   // Expect a demangled symbol.
     91   EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") !=
     92               std::string::npos)
     93       << "Expected a demangled symbol in backtrace:\n"
     94       << backtrace_message;
     95 
     96 #elif 0
     97   // This is the fall-through case; it used to cover Windows.
     98   // But it's disabled because of varying buildbot configs;
     99   // some lack symbols.
    100 
    101   // Expect to at least find main.
    102   EXPECT_TRUE(backtrace_message.find("main") != std::string::npos)
    103       << "Expected to find main in backtrace:\n"
    104       << backtrace_message;
    105 
    106 #if defined(OS_WIN)
    107 // MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with
    108 // MSVC's __FUNCTION__ macro.
    109 #define __func__ __FUNCTION__
    110 #endif
    111 
    112   // Expect to find this function as well.
    113   // Note: This will fail if not linked with -rdynamic (aka -export_dynamic)
    114   EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos)
    115       << "Expected to find " << __func__ << " in backtrace:\n"
    116       << backtrace_message;
    117 
    118 #endif  // define(OS_MACOSX)
    119 }
    120 
    121 // The test is used for manual testing, e.g., to see the raw output.
    122 TEST_F(StackTraceTest, DebugOutputToStream) {
    123   StackTrace trace;
    124   std::ostringstream os;
    125   trace.OutputToStream(&os);
    126   VLOG(1) << os.str();
    127 }
    128 
    129 // The test is used for manual testing, e.g., to see the raw output.
    130 TEST_F(StackTraceTest, DebugPrintBacktrace) {
    131   StackTrace().Print();
    132 }
    133 
    134 #if defined(OS_POSIX) && !defined(OS_ANDROID)
    135 #if !defined(OS_IOS)
    136 MULTIPROCESS_TEST_MAIN(MismatchedMallocChildProcess) {
    137   char* pointer = new char[10];
    138   delete pointer;
    139   return 2;
    140 }
    141 
    142 // Regression test for StackDumpingSignalHandler async-signal unsafety.
    143 // Combined with tcmalloc's debugallocation, that signal handler
    144 // and e.g. mismatched new[]/delete would cause a hang because
    145 // of re-entering malloc.
    146 TEST_F(StackTraceTest, AsyncSignalUnsafeSignalHandlerHang) {
    147   ProcessHandle child = this->SpawnChild("MismatchedMallocChildProcess", false);
    148   ASSERT_NE(kNullProcessHandle, child);
    149   ASSERT_TRUE(WaitForSingleProcess(child, TestTimeouts::action_timeout()));
    150 }
    151 #endif  // !defined(OS_IOS)
    152 
    153 namespace {
    154 
    155 std::string itoa_r_wrapper(intptr_t i, size_t sz, int base, size_t padding) {
    156   char buffer[1024];
    157   CHECK_LE(sz, sizeof(buffer));
    158 
    159   char* result = internal::itoa_r(i, buffer, sz, base, padding);
    160   EXPECT_TRUE(result);
    161   return std::string(buffer);
    162 }
    163 
    164 }  // namespace
    165 
    166 TEST_F(StackTraceTest, itoa_r) {
    167   EXPECT_EQ("0", itoa_r_wrapper(0, 128, 10, 0));
    168   EXPECT_EQ("-1", itoa_r_wrapper(-1, 128, 10, 0));
    169 
    170   // Test edge cases.
    171   if (sizeof(intptr_t) == 4) {
    172     EXPECT_EQ("ffffffff", itoa_r_wrapper(-1, 128, 16, 0));
    173     EXPECT_EQ("-2147483648",
    174               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
    175     EXPECT_EQ("2147483647",
    176               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
    177 
    178     EXPECT_EQ("80000000",
    179               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
    180     EXPECT_EQ("7fffffff",
    181               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
    182   } else if (sizeof(intptr_t) == 8) {
    183     EXPECT_EQ("ffffffffffffffff", itoa_r_wrapper(-1, 128, 16, 0));
    184     EXPECT_EQ("-9223372036854775808",
    185               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 10, 0));
    186     EXPECT_EQ("9223372036854775807",
    187               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 10, 0));
    188 
    189     EXPECT_EQ("8000000000000000",
    190               itoa_r_wrapper(std::numeric_limits<intptr_t>::min(), 128, 16, 0));
    191     EXPECT_EQ("7fffffffffffffff",
    192               itoa_r_wrapper(std::numeric_limits<intptr_t>::max(), 128, 16, 0));
    193   } else {
    194     ADD_FAILURE() << "Missing test case for your size of intptr_t ("
    195                   << sizeof(intptr_t) << ")";
    196   }
    197 
    198   // Test hex output.
    199   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
    200   EXPECT_EQ("deadbeef", itoa_r_wrapper(0xdeadbeef, 128, 16, 0));
    201 
    202   // Check that itoa_r respects passed buffer size limit.
    203   char buffer[1024];
    204   EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 10, 16, 0));
    205   EXPECT_TRUE(internal::itoa_r(0xdeadbeef, buffer, 9, 16, 0));
    206   EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 8, 16, 0));
    207   EXPECT_FALSE(internal::itoa_r(0xdeadbeef, buffer, 7, 16, 0));
    208   EXPECT_TRUE(internal::itoa_r(0xbeef, buffer, 5, 16, 4));
    209   EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 5));
    210   EXPECT_FALSE(internal::itoa_r(0xbeef, buffer, 5, 16, 6));
    211 
    212   // Test padding.
    213   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 0));
    214   EXPECT_EQ("1", itoa_r_wrapper(1, 128, 10, 1));
    215   EXPECT_EQ("01", itoa_r_wrapper(1, 128, 10, 2));
    216   EXPECT_EQ("001", itoa_r_wrapper(1, 128, 10, 3));
    217   EXPECT_EQ("0001", itoa_r_wrapper(1, 128, 10, 4));
    218   EXPECT_EQ("00001", itoa_r_wrapper(1, 128, 10, 5));
    219   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 0));
    220   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 1));
    221   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 2));
    222   EXPECT_EQ("688", itoa_r_wrapper(0x688, 128, 16, 3));
    223   EXPECT_EQ("0688", itoa_r_wrapper(0x688, 128, 16, 4));
    224   EXPECT_EQ("00688", itoa_r_wrapper(0x688, 128, 16, 5));
    225 }
    226 #endif  // defined(OS_POSIX) && !defined(OS_ANDROID)
    227 
    228 }  // namespace debug
    229 }  // namespace base
    230