Remove GOOGLE_GLOG_COMPILE_ASSERT
[platform/upstream/glog.git] / src / symbolize_unittest.cc
index 2405362..a0a9737 100644 (file)
@@ -1,8 +1,38 @@
-// Copyright 2006 Google Inc. All Rights Reserved.
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
 // Author: Satoru Takabayashi
 //
 // Unit tests for functions in symbolize.cc.
 
+#include "utilities.h"
+
 #include <signal.h>
 #include <iostream>
 
 #include "symbolize.h"
 #include "googletest.h"
 #include "config.h"
-#include "utilities.h"
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
 
 using namespace std;
 using namespace GOOGLE_NAMESPACE;
 
-#if defined(HAVE_STACKTRACE) && defined(__ELF__)
+#if defined(HAVE_STACKTRACE)
 
 #define always_inline
 
+// A wrapper function for Symbolize() to make the unit test simple.
+static const char *TrySymbolize(void *pc) {
+  static char symbol[4096];
+  if (Symbolize(pc, symbol, sizeof(symbol))) {
+    return symbol;
+  } else {
+    return NULL;
+  }
+}
+
+# if defined(__ELF__)
+
 // This unit tests make sense only with GCC.
 // Uses lots of GCC specific features.
 #if defined(__GNUC__) && !defined(__OPENCC__)
@@ -36,16 +82,6 @@ using namespace GOOGLE_NAMESPACE;
 #  endif  // defined(__i386__) || defined(__x86_64__)
 #endif
 
-// A wrapper function for Symbolize() to make the unit test simple.
-static const char *TrySymbolize(void *pc) {
-  static char symbol[4096];
-  if (Symbolize(pc, symbol, sizeof(symbol))) {
-    return symbol;
-  } else {
-    return NULL;
-  }
-}
-
 // Make them C linkage to avoid mangled names.
 extern "C" {
 void nonstatic_func() {
@@ -65,7 +101,13 @@ TEST(Symbolize, Symbolize) {
 
   // Compilers should give us pointers to them.
   EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
-  EXPECT_STREQ("static_func", TrySymbolize((void *)(&static_func)));
+
+  // The name of an internal linkage symbol is not specified; allow either a
+  // mangled or an unmangled name here.
+  const char *static_func_symbol = TrySymbolize((void *)(&static_func));
+  CHECK(NULL != static_func_symbol);
+  EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
+              strcmp("static_func()", static_func_symbol) == 0);
 
   EXPECT_TRUE(NULL == TrySymbolize(NULL));
 }
@@ -126,7 +168,7 @@ const char kAlternateStackFillValue = 0x55;
 // These helper functions look at the alternate stack buffer, and figure
 // out what portion of this buffer has been touched - this is the stack
 // consumption of the signal handler running on this alternate stack.
-static bool StackGrowsDown(int *x) {
+static ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) {
   int y;
   return &y < x;
 }
@@ -164,7 +206,8 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
   memset(altstack, kAlternateStackFillValue, kAlternateStackSize);
 
   // Set up the alt-signal-stack (and save the older one).
-  stack_t sigstk = {};  // Zero-clear.
+  stack_t sigstk;
+  memset(&sigstk, 0, sizeof(stack_t));
   stack_t old_sigstk;
   sigstk.ss_sp = altstack;
   sigstk.ss_size = kAlternateStackSize;
@@ -172,7 +215,8 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
   CHECK_ERR(sigaltstack(&sigstk, &old_sigstk));
 
   // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones).
-  struct sigaction sa = {};  // Zero-clear;
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(struct sigaction));
   struct sigaction old_sa1, old_sa2;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = SA_ONSTACK;
@@ -218,8 +262,13 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
   return g_symbolize_result;
 }
 
+#ifdef __ppc64__
+// Symbolize stack consumption should be within 4kB.
+const int kStackConsumptionUpperLimit = 4096;
+#else
 // Symbolize stack consumption should be within 2kB.
 const int kStackConsumptionUpperLimit = 2048;
+#endif
 
 TEST(Symbolize, SymbolizeStackConsumption) {
   int stack_consumed;
@@ -231,9 +280,13 @@ TEST(Symbolize, SymbolizeStackConsumption) {
   EXPECT_GT(stack_consumed, 0);
   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
 
+  // The name of an internal linkage symbol is not specified; allow either a
+  // mangled or an unmangled name here.
   symbol = SymbolizeStackConsumption((void *)(&static_func),
                                      &stack_consumed);
-  EXPECT_STREQ("static_func", symbol);
+  CHECK(NULL != symbol);
+  EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
+              strcmp("static_func()", symbol) == 0);
   EXPECT_GT(stack_consumed, 0);
   EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
 }
@@ -277,7 +330,7 @@ void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
   void *pc = non_inline_func();
   const char *symbol = TrySymbolize(pc);
   CHECK(symbol != NULL);
-  CHECK_EQ(0, strcmp(symbol, "non_inline_func"));
+  CHECK_STREQ(symbol, "non_inline_func");
   cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
 #endif
 }
@@ -287,7 +340,7 @@ void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
   void *pc = inline_func();  // Must be inlined.
   const char *symbol = TrySymbolize(pc);
   CHECK(symbol != NULL);
-  CHECK_EQ(0, strcmp(symbol, __FUNCTION__));
+  CHECK_STREQ(symbol, __FUNCTION__);
   cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
 #endif
 }
@@ -299,30 +352,64 @@ void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
   void *return_address = __builtin_return_address(0);
   const char *symbol = TrySymbolize(return_address);
   CHECK(symbol != NULL);
-  CHECK_EQ(0, strcmp(symbol, "main"));
+  CHECK_STREQ(symbol, "main");
   cout << "Test case TestWithReturnAddress passed." << endl;
 #endif
 }
 
+# elif defined(OS_WINDOWS)
+
+#include <intrin.h>
+#pragma intrinsic(_ReturnAddress)
+
+struct Foo {
+  static void func(int x);
+};
+
+__declspec(noinline) void Foo::func(int x) {
+  volatile int a = x;
+  ++a;
+}
+
+TEST(Symbolize, SymbolizeWithDemangling) {
+  Foo::func(100);
+  const char* ret = TrySymbolize((void *)(&Foo::func));
+  EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret);
+}
+
+__declspec(noinline) void TestWithReturnAddress() {
+  void *return_address = _ReturnAddress();
+  const char *symbol = TrySymbolize(return_address);
+  CHECK(symbol != NULL);
+  CHECK_STREQ(symbol, "main");
+  cout << "Test case TestWithReturnAddress passed." << endl;
+}
+# endif  // __ELF__
+#endif  // HAVE_STACKTRACE
+
 int main(int argc, char **argv) {
   FLAGS_logtostderr = true;
   InitGoogleLogging(argv[0]);
+  InitGoogleTest(&argc, argv);
+#if defined(HAVE_SYMBOLIZE)
+# if defined(__ELF__)
+  // We don't want to get affected by the callback interface, that may be
+  // used to install some callback function at InitGoogle() time.
+  InstallSymbolizeCallback(NULL);
 
-  // Symbolize() now only supports ELF binaries.
-  // The test makes sense only if __ELF__ is defined.
-#ifndef __ELF__
-  return 0;
-#else
   TestWithPCInsideInlineFunction();
   TestWithPCInsideNonInlineFunction();
   TestWithReturnAddress();
   return RUN_ALL_TESTS();
-#endif
-}
-
+# elif defined(OS_WINDOWS)
+  TestWithReturnAddress();
+  return RUN_ALL_TESTS();
+# else  // OS_WINDOWS
+  printf("PASS (no symbolize_unittest support)\n");
+  return 0;
+# endif  // __ELF__
 #else
-int main() {
   printf("PASS (no symbolize support)\n");
   return 0;
+#endif  // HAVE_SYMBOLIZE
 }
-#endif  // HAVE_STACKTRACE