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