From c43107d1fed5f96770024d52c10cd7bd061bb7c1 Mon Sep 17 00:00:00 2001 From: Harshad Deshmukh Date: Fri, 15 Dec 2017 15:06:49 -0600 Subject: [PATCH] Remove glog source code from third party - glog source code is now downloaded through the download script. - Added patches for glog. --- CMakeLists.txt | 3 +- .../download_and_patch_prerequisites.sh | 8 + .../patches/glog/glogCMakeLists.txt.patch | 23 + third_party/patches/glog/utilities.cc.patch | 11 + third_party/reset_third_party_dir.sh | 1 + third_party/src/glog/AUTHORS | 2 - third_party/src/glog/CMakeLists.txt | 208 -- third_party/src/glog/COPYING | 65 - third_party/src/glog/ChangeLog | 84 - third_party/src/glog/INSTALL | 297 --- third_party/src/glog/NEWS | 0 third_party/src/glog/README | 5 - third_party/src/glog/README.windows | 26 - third_party/src/glog/doc/designstyle.css | 115 - third_party/src/glog/doc/glog.html | 613 ----- .../src/glog/src/base/commandlineflags.h | 133 -- third_party/src/glog/src/base/googleinit.h | 51 - third_party/src/glog/src/base/mutex.h | 331 --- third_party/src/glog/src/config.h.in | 171 -- third_party/src/glog/src/config_cmake.h.in | 169 -- .../src/glog/src/config_for_unittests.h | 66 - third_party/src/glog/src/demangle.cc | 1304 ----------- third_party/src/glog/src/demangle.h | 84 - third_party/src/glog/src/demangle_unittest.cc | 142 -- third_party/src/glog/src/demangle_unittest.sh | 95 - .../src/glog/src/demangle_unittest.txt | 137 -- third_party/src/glog/src/glog/log_severity.h | 92 - third_party/src/glog/src/glog/logging.h | 1619 ------------- third_party/src/glog/src/glog/raw_logging.h | 191 -- third_party/src/glog/src/glog/stl_logging.h | 183 -- third_party/src/glog/src/glog/vlog_is_on.h | 129 -- third_party/src/glog/src/googletest.h | 604 ----- third_party/src/glog/src/logging.cc | 2049 ---------------- .../src/glog/src/logging_striplog_test.sh | 79 - .../src/glog/src/logging_striptest10.cc | 35 - .../src/glog/src/logging_striptest2.cc | 35 - .../src/glog/src/logging_striptest_main.cc | 73 - third_party/src/glog/src/logging_unittest.cc | 1215 ---------- third_party/src/glog/src/logging_unittest.err | 305 --- third_party/src/glog/src/mock-log.h | 155 -- third_party/src/glog/src/mock-log_test.cc | 106 - third_party/src/glog/src/raw_logging.cc | 172 -- third_party/src/glog/src/signalhandler.cc | 350 --- .../src/glog/src/signalhandler_unittest.cc | 97 - .../src/glog/src/signalhandler_unittest.sh | 131 -- third_party/src/glog/src/stacktrace.h | 60 - .../src/glog/src/stacktrace_generic-inl.h | 59 - .../src/glog/src/stacktrace_libunwind-inl.h | 87 - .../src/glog/src/stacktrace_powerpc-inl.h | 130 -- .../src/glog/src/stacktrace_unittest.cc | 208 -- third_party/src/glog/src/stacktrace_x86-inl.h | 139 -- .../src/glog/src/stacktrace_x86_64-inl.h | 109 - .../src/glog/src/stl_logging_unittest.cc | 182 -- third_party/src/glog/src/symbolize.cc | 681 ------ third_party/src/glog/src/symbolize.h | 116 - .../src/glog/src/symbolize_unittest.cc | 365 --- third_party/src/glog/src/utilities.cc | 347 --- third_party/src/glog/src/utilities.h | 226 -- .../src/glog/src/utilities_unittest.cc | 54 - third_party/src/glog/src/vlog_is_on.cc | 249 -- .../glog/src/windows/base/commandlineflags.h | 133 -- .../src/glog/src/windows/base/googleinit.h | 51 - third_party/src/glog/src/windows/base/mutex.h | 331 --- .../src/glog/src/windows/config_cmake.h.in | 142 -- .../src/glog/src/windows/glog/log_severity.h | 96 - .../src/glog/src/windows/glog/logging.h | 1603 ------------- .../src/glog/src/windows/glog/raw_logging.h | 189 -- .../src/glog/src/windows/glog/stl_logging.h | 187 -- .../src/glog/src/windows/glog/vlog_is_on.h | 133 -- third_party/src/glog/src/windows/logging.cc | 2050 ----------------- third_party/src/glog/src/windows/port.cc | 66 - third_party/src/glog/src/windows/port.h | 165 -- .../src/glog/src/windows/preprocess.sh | 119 - .../src/glog/src/windows/raw_logging.cc | 172 -- third_party/src/glog/src/windows/utilities.cc | 347 --- third_party/src/glog/src/windows/utilities.h | 226 -- .../src/glog/src/windows/vlog_is_on.cc | 249 -- 77 files changed, 45 insertions(+), 20990 deletions(-) create mode 100644 third_party/patches/glog/glogCMakeLists.txt.patch create mode 100644 third_party/patches/glog/utilities.cc.patch delete mode 100644 third_party/src/glog/AUTHORS delete mode 100644 third_party/src/glog/CMakeLists.txt delete mode 100644 third_party/src/glog/COPYING delete mode 100644 third_party/src/glog/ChangeLog delete mode 100644 third_party/src/glog/INSTALL delete mode 100644 third_party/src/glog/NEWS delete mode 100644 third_party/src/glog/README delete mode 100644 third_party/src/glog/README.windows delete mode 100644 third_party/src/glog/doc/designstyle.css delete mode 100644 third_party/src/glog/doc/glog.html delete mode 100644 third_party/src/glog/src/base/commandlineflags.h delete mode 100644 third_party/src/glog/src/base/googleinit.h delete mode 100644 third_party/src/glog/src/base/mutex.h delete mode 100644 third_party/src/glog/src/config.h.in delete mode 100644 third_party/src/glog/src/config_cmake.h.in delete mode 100644 third_party/src/glog/src/config_for_unittests.h delete mode 100644 third_party/src/glog/src/demangle.cc delete mode 100644 third_party/src/glog/src/demangle.h delete mode 100644 third_party/src/glog/src/demangle_unittest.cc delete mode 100644 third_party/src/glog/src/demangle_unittest.sh delete mode 100644 third_party/src/glog/src/demangle_unittest.txt delete mode 100644 third_party/src/glog/src/glog/log_severity.h delete mode 100644 third_party/src/glog/src/glog/logging.h delete mode 100644 third_party/src/glog/src/glog/raw_logging.h delete mode 100644 third_party/src/glog/src/glog/stl_logging.h delete mode 100644 third_party/src/glog/src/glog/vlog_is_on.h delete mode 100644 third_party/src/glog/src/googletest.h delete mode 100644 third_party/src/glog/src/logging.cc delete mode 100644 third_party/src/glog/src/logging_striplog_test.sh delete mode 100644 third_party/src/glog/src/logging_striptest10.cc delete mode 100644 third_party/src/glog/src/logging_striptest2.cc delete mode 100644 third_party/src/glog/src/logging_striptest_main.cc delete mode 100644 third_party/src/glog/src/logging_unittest.cc delete mode 100644 third_party/src/glog/src/logging_unittest.err delete mode 100644 third_party/src/glog/src/mock-log.h delete mode 100644 third_party/src/glog/src/mock-log_test.cc delete mode 100644 third_party/src/glog/src/raw_logging.cc delete mode 100644 third_party/src/glog/src/signalhandler.cc delete mode 100644 third_party/src/glog/src/signalhandler_unittest.cc delete mode 100644 third_party/src/glog/src/signalhandler_unittest.sh delete mode 100644 third_party/src/glog/src/stacktrace.h delete mode 100644 third_party/src/glog/src/stacktrace_generic-inl.h delete mode 100644 third_party/src/glog/src/stacktrace_libunwind-inl.h delete mode 100644 third_party/src/glog/src/stacktrace_powerpc-inl.h delete mode 100644 third_party/src/glog/src/stacktrace_unittest.cc delete mode 100644 third_party/src/glog/src/stacktrace_x86-inl.h delete mode 100644 third_party/src/glog/src/stacktrace_x86_64-inl.h delete mode 100644 third_party/src/glog/src/stl_logging_unittest.cc delete mode 100644 third_party/src/glog/src/symbolize.cc delete mode 100644 third_party/src/glog/src/symbolize.h delete mode 100644 third_party/src/glog/src/symbolize_unittest.cc delete mode 100644 third_party/src/glog/src/utilities.cc delete mode 100644 third_party/src/glog/src/utilities.h delete mode 100644 third_party/src/glog/src/utilities_unittest.cc delete mode 100644 third_party/src/glog/src/vlog_is_on.cc delete mode 100644 third_party/src/glog/src/windows/base/commandlineflags.h delete mode 100644 third_party/src/glog/src/windows/base/googleinit.h delete mode 100644 third_party/src/glog/src/windows/base/mutex.h delete mode 100644 third_party/src/glog/src/windows/config_cmake.h.in delete mode 100644 third_party/src/glog/src/windows/glog/log_severity.h delete mode 100644 third_party/src/glog/src/windows/glog/logging.h delete mode 100644 third_party/src/glog/src/windows/glog/raw_logging.h delete mode 100644 third_party/src/glog/src/windows/glog/stl_logging.h delete mode 100644 third_party/src/glog/src/windows/glog/vlog_is_on.h delete mode 100644 third_party/src/glog/src/windows/logging.cc delete mode 100644 third_party/src/glog/src/windows/port.cc delete mode 100644 third_party/src/glog/src/windows/port.h delete mode 100644 third_party/src/glog/src/windows/preprocess.sh delete mode 100644 third_party/src/glog/src/windows/raw_logging.cc delete mode 100644 third_party/src/glog/src/windows/utilities.cc delete mode 100644 third_party/src/glog/src/windows/utilities.h delete mode 100644 third_party/src/glog/src/windows/vlog_is_on.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 60d8a2d1..88835ac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -587,6 +587,7 @@ if(USE_TCMALLOC) if (COMPILER_HAS_WNO_RETURN_TYPE_C_LINKAGE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage") endif() + include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party) endif() # Add Protocol Buffers. @@ -649,7 +650,7 @@ if (WIN32) include_directories(${THIRD_PARTY_SOURCE_DIR}/glog/src/windows) else() include_directories(${THIRD_PARTY_SOURCE_DIR}/glog/src) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party) + include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party/glog) endif() include_directories("${THIRD_PARTY_SOURCE_DIR}/re2") diff --git a/third_party/download_and_patch_prerequisites.sh b/third_party/download_and_patch_prerequisites.sh index b9b3d537..2295525e 100755 --- a/third_party/download_and_patch_prerequisites.sh +++ b/third_party/download_and_patch_prerequisites.sh @@ -49,6 +49,7 @@ third_party_dir_names=("benchmark" "linenoise" "re2" "gperftools" + "glog" ) third_party_lib_urls=("https://github.com/google/benchmark/archive/v1.1.0.tar.gz" @@ -57,6 +58,7 @@ third_party_lib_urls=("https://github.com/google/benchmark/archive/v1.1.0.tar.gz "https://github.com/antirez/linenoise/archive/1.0.tar.gz" "https://github.com/google/re2/archive/2017-01-01.tar.gz" "https://github.com/gperftools/gperftools/releases/download/gperftools-2.5/gperftools-2.5.tar.gz" + "https://github.com/google/glog/archive/v0.3.5.tar.gz" ) downloaded_archive_names=("v1.1.0.tar.gz" @@ -65,6 +67,7 @@ downloaded_archive_names=("v1.1.0.tar.gz" "1.0.tar.gz" "2017-01-01.tar.gz" "gperftools-2.5.tar.gz" + "v0.3.5.tar.gz" ) tar_options=("-xzf" @@ -73,6 +76,7 @@ tar_options=("-xzf" "-xzf" "-xzf" "-xzf" + "-xzf" ) for ((lib_index=0; lib_index < ${#third_party_dir_names[*]}; lib_index++)) @@ -125,3 +129,7 @@ patch ${THIRD_PARTY_SRC_DIR}/re2/CMakeLists.txt ${PATCH_DIR}/re2/re2CMake.patch # Apply benchmark patches. patch ${THIRD_PARTY_SRC_DIR}/benchmark/CMakeLists.txt ${PATCH_DIR}/benchmark/benchmarkCMake.patch patch ${THIRD_PARTY_SRC_DIR}/benchmark/src/CMakeLists.txt ${PATCH_DIR}/benchmark/benchmarkSrcCMakeLists.patch + +# Apply glog patches. +patch ${THIRD_PARTY_SRC_DIR}/glog/CMakeLists.txt ${PATCH_DIR}/glog/glogCMakeLists.txt.patch +patch ${THIRD_PARTY_SRC_DIR}/glog/src/utilities.cc ${PATCH_DIR}/glog/utilities.cc.patch diff --git a/third_party/patches/glog/glogCMakeLists.txt.patch b/third_party/patches/glog/glogCMakeLists.txt.patch new file mode 100644 index 00000000..94c1d955 --- /dev/null +++ b/third_party/patches/glog/glogCMakeLists.txt.patch @@ -0,0 +1,23 @@ +--- CMakeLists.txt 2017-12-15 14:10:23.000000002 -0600 ++++ CMakeLists-new.txt 2017-12-15 14:07:52.000000002 -0600 +@@ -26,7 +26,7 @@ + set (CPACK_PACKAGE_VERSION_PATCH ${GLOG_PATCH_VERSION}) + set (CPACK_PACKAGE_VERSION ${GLOG_VERSION}) + +-option (WITH_GFLAGS "Use gflags" ON) ++option (WITH_GFLAGS "Use gflags" OFF) + option (WITH_THREADS "Enable multithreading support" ON) + + list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +@@ -377,6 +377,11 @@ + + add_compile_options ($<$:-Wno-unnamed-type-template-args>) + ++CHECK_CXX_COMPILER_FLAG("-Wno-sign-compare" COMPILER_HAS_WNO_SIGN_ERROR) ++if (COMPILER_HAS_WNO_SIGN_ERROR) ++ add_compile_options(-Wno-sign-compare) ++endif() ++ + add_library (glog + ${GLOG_SRCS} + ) diff --git a/third_party/patches/glog/utilities.cc.patch b/third_party/patches/glog/utilities.cc.patch new file mode 100644 index 00000000..cdd626fc --- /dev/null +++ b/third_party/patches/glog/utilities.cc.patch @@ -0,0 +1,11 @@ +--- utilities.cc 2017-12-15 14:10:40.000000002 -0600 ++++ utilities.cc.new 2017-12-15 14:08:13.000000002 -0600 +@@ -300,7 +300,7 @@ + g_my_user_name = "invalid-user"; + } + } +-REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()); ++REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()) + + #ifdef HAVE_STACKTRACE + void DumpStackTraceToString(string* stacktrace) { diff --git a/third_party/reset_third_party_dir.sh b/third_party/reset_third_party_dir.sh index 3c043814..a98ee3e8 100755 --- a/third_party/reset_third_party_dir.sh +++ b/third_party/reset_third_party_dir.sh @@ -32,6 +32,7 @@ third_party_dir_names=("benchmark" "linenoise" "re2" "gperftools" + "glog" ) for ((lib_index=0; lib_index < ${#third_party_dir_names[*]}; lib_index++)) diff --git a/third_party/src/glog/AUTHORS b/third_party/src/glog/AUTHORS deleted file mode 100644 index ee92be88..00000000 --- a/third_party/src/glog/AUTHORS +++ /dev/null @@ -1,2 +0,0 @@ -opensource@google.com - diff --git a/third_party/src/glog/CMakeLists.txt b/third_party/src/glog/CMakeLists.txt deleted file mode 100644 index a916b964..00000000 --- a/third_party/src/glog/CMakeLists.txt +++ /dev/null @@ -1,208 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# This file allows building glog with CMake instead of autotools. glog itself -# is copyright Google, Inc. and is covered by the license described in the -# COPYING file in this directory. - -if(CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare") -endif() - -if (WIN32) - # Windows uses a preprocessed config file and some other wierdness. - set_property( - DIRECTORY - APPEND PROPERTY COMPILE_DEFINITIONS GOOGLE_GLOG_DLL_DECL= - ) - - # Check if snprintf is available. It usually isn't on Windows, but MinGW - # provides it. - include(CheckCXXSymbolExists) - check_cxx_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) - - # Similarly, check if pid_t is defined in process.h. Usually the answer is no - # on Windows, but MinGW has it. - include(CheckTypeSize) - check_type_size("pid_t" PID_T) - configure_file ( - "${CMAKE_CURRENT_SOURCE_DIR}/src/windows/config_cmake.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/config.h" - ) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - - include_directories(src/windows) - add_library(glog - src/windows/logging.cc - src/windows/port.cc - src/windows/raw_logging.cc - src/windows/utilities.cc - src/windows/vlog_is_on.cc) -else() - # The big, happy UNIX family (and friends). - - # System headers. - include(CheckIncludeFileCXX) - check_include_file_cxx(dlfcn.h HAVE_DLFCN_H) - check_include_file_cxx(execinfo.h HAVE_EXECINFO_H) - check_include_file_cxx(glob.h HAVE_GLOB_H) - check_include_file_cxx(inttypes.h HAVE_INTTYPES_H) - check_include_file_cxx(libunwind.h HAVE_LIBUNWIND_H) - check_include_file_cxx(memory.h HAVE_MEMORY_H) - check_include_file_cxx(pwd.h HAVE_PWD_H) - check_include_file_cxx(libunwind.h HAVE_LIBUNWIND_H) - check_include_file_cxx(stdint.h HAVE_STDINT_H) - check_include_file_cxx(stdlib.h HAVE_STDLIB_H) - check_include_file_cxx(strings.h HAVE_STRINGS_H) - check_include_file_cxx(string.h HAVE_STRING_H) - check_include_file_cxx(syscall.h HAVE_SYSCALL_H) - check_include_file_cxx(syslog.h HAVE_SYSLOG_H) - check_include_file_cxx(sys/stat.h HAVE_SYS_STAT_H) - check_include_file_cxx(sys/syscall.h HAVE_SYS_SYSCALL_H) - check_include_file_cxx(sys/time.h HAVE_SYS_TIME_H) - check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H) - check_include_file_cxx(sys/ucontext.h HAVE_SYS_UCONTEXT_H) - check_include_file_cxx(sys/utsname.h HAVE_SYS_UTSNAME_H) - check_include_file_cxx(ucontext.h HAVE_UCONTEXT_H) - check_include_file_cxx(unistd.h HAVE_UNISTD_H) - check_include_file_cxx(unwind.h HAVE_UNWIND_H) - - # Check if functions exist. - include(CheckFunctionExists) - check_function_exists(fcntl HAVE_FCNTL) - check_function_exists(sigalstack HAVE_SIGALSTACK) - - # Check if we are using pthreads. - find_package(Threads) - if (CMAKE_HAVE_PTHREAD_H) - set(HAVE_LIBPTHREAD 1) - set(HAVE_PTHREAD 1) - set(HAVE_RWLOCK 1) - endif() - - # Check pointer size. - include(CheckTypeSize) - check_type_size("void*" SIZEOF_VOID_P) - - # Check compiler builtins. - include(CheckCXXSourceCompiles) - - CHECK_CXX_SOURCE_COMPILES(" - int main(int argc, char **argv) { - if (__builtin_expect(argc, 1)) { - return 0; - } else { - return argc; - } - } - " HAVE___BUILTIN_EXPECT) - - CHECK_CXX_SOURCE_COMPILES(" - int numfun(int n) __attribute__((const)); - - int main(int argc, char **argv) { - return numfun(argc); - } - - int numfun(int n) { - return n + 1; - } - " HAVE___ATTRIBUTE__) - - CHECK_CXX_SOURCE_COMPILES(" - int atomicswap(int *ptr, int oldval, int newval) { - return __sync_val_compare_and_swap(ptr, oldval, newval); - } - - int main(int argc, char **argv) { - return atomicswap(&argc, 1, 2); - } - " HAVE___SYNC_VAL_COMPARE_AND_SWAP) - - # Try a bunch of different platform-specific ways to get the program counter - # from a ucontext_t. This particular code snippet is based on Apache-licensed - # code from https://maiter.googlecode.com/svn/trunk/Maiter/cmake/PcFromUcontext.cmake - set(UCONTEXT_INCLUDES) - if (HAVE_SYS_UCONTEXT_H) - set(UCONTEXT_INCLUDES "${UCONTEXT_INCLUDES}\n#include ") - endif() - if (HAVE_UCONTEXT_H) - set(UCONTEXT_INCLUDES "${UCONTEXT_INCLUDES}\n#include ") - endif() - - foreach (pc_field - "uc_mcontext.gregs[REG_EIP]" - "uc_mcontext.gregs[REG_RIP]" - "uc_mcontext.sc_ip" - "uc_mcontext.uc_regs->gregs[PT_NIP]" - "uc_mcontext.gregs[R15]" - "uc_mcontext.arm_pc" - "uc_mcontext.mc_eip" - "uc_mcontext.mc_rip" - "uc_mcontext.__gregs[_REG_EIP]" - "uc_mcontext.__gregs[_REG_RIP]" - "uc_mcontext->ss.eip" - "uc_mcontext->__ss.__eip" - "uc_mcontext->ss.rip" - "uc_mcontext->__ss.__rip" - "uc_mcontext->ss.srr0" - "uc_mcontext->__ss.__srr0") - message(STATUS "Checking program counter fetch from ucontext_t member: ${pc_field}") - - CHECK_CXX_SOURCE_COMPILES(" - ${UCONTEXT_INCLUDES} - int main(int argc, char **argv) { - ucontext_t ctx; - return ctx.${pc_field} == 0; - } - " PC_FROM_UCONTEXT_COMPILES) - - if (PC_FROM_UCONTEXT_COMPILES) - unset(PC_FROM_UCONTEXT_COMPILES CACHE) - message(STATUS "Found program counter field in ucontext_t: ${pc_field}") - set(PC_FROM_UCONTEXT ${pc_field}) - break() - else() - unset(PC_FROM_UCONTEXT_COMPILES CACHE) - endif() - endforeach() - - if (NOT PC_FROM_UCONTEXT) - message(WARNING "Unable to find program counter field in ucontext_t. GLOG " - "signal handler will not be able to report precise PC " - "position.") - endif() - - # Generate config.h - configure_file ( - "${CMAKE_CURRENT_SOURCE_DIR}/src/config_cmake.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/config.h" - ) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) - - include_directories(src) - add_library(glog - src/demangle.cc - src/logging.cc - src/raw_logging.cc - src/signalhandler.cc - src/symbolize.cc - src/utilities.cc - src/vlog_is_on.cc) - target_link_libraries(glog ${CMAKE_THREAD_LIBS_INIT}) -endif() diff --git a/third_party/src/glog/COPYING b/third_party/src/glog/COPYING deleted file mode 100644 index 38396b58..00000000 --- a/third_party/src/glog/COPYING +++ /dev/null @@ -1,65 +0,0 @@ -Copyright (c) 2008, 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. - - -A function gettimeofday in utilities.cc is based on - -http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd - -The license of this code is: - -Copyright (c) 2003-2008, Jouni Malinen and contributors -All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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. - -3. Neither the name(s) of the above-listed copyright holder(s) 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. diff --git a/third_party/src/glog/ChangeLog b/third_party/src/glog/ChangeLog deleted file mode 100644 index d1b42484..00000000 --- a/third_party/src/glog/ChangeLog +++ /dev/null @@ -1,84 +0,0 @@ -2013-02-01 Google Inc. - - * google-glog: version 0.3.3 - * Add --disable-rtti option for configure. - * Visual Studio build and test fix. - * QNX build fix (thanks vanuan). - * Reduce warnings. - * Fixed LOG_SYSRESULT (thanks ukai). - * FreeBSD build fix (thanks yyanagisawa). - * Clang build fix. - * Now users can re-initialize glog after ShutdownGoogleLogging. - * Color output support by GLOG_colorlogtostderr (thanks alexs). - * Now glog's ABI around flags are compatible with gflags. - * Document mentions how to modify flags from user programs. - -2012-01-12 Google Inc. - - * google-glog: version 0.3.2 - * Clang support. - * Demangler and stacktrace improvement for newer GCCs. - * Now fork(2) doesn't mess up log files. - * Make valgrind happier. - * Reduce warnings for more -W options. - * Provide a workaround for ERROR defined by windows.h. - -2010-06-15 Google Inc. - - * google-glog: version 0.3.1 - * GLOG_* environment variables now work even when gflags is installed. - * Snow leopard support. - * Now we can build and test from out side tree. - * Add DCHECK_NOTNULL. - * Add ShutdownGoogleLogging to close syslog (thanks DGunchev) - * Fix --enable-frame-pointers option (thanks kazuki.ohta) - * Fix libunwind detection (thanks giantchen) - -2009-07-30 Google Inc. - - * google-glog: version 0.3.0 - * Fix a deadlock happened when user uses glog with recent gflags. - * Suppress several unnecessary warnings (thanks keir). - * NetBSD and OpenBSD support. - * Use Win32API GetComputeNameA properly (thanks magila). - * Fix user name detection for Windows (thanks ademin). - * Fix several minor bugs. - -2009-04-10 Google Inc. - * google-glog: version 0.2.1 - * Fix timestamps of VC++ version. - * Add pkg-config support (thanks Tomasz) - * Fix build problem when building with gtest (thanks Michael) - * Add --with-gflags option for configure (thanks Michael) - * Fixes for GCC 4.4 (thanks John) - -2009-01-23 Google Inc. - * google-glog: version 0.2 - * Add initial Windows VC++ support. - * Google testing/mocking frameworks integration. - * Link pthread library automatically. - * Flush logs in signal handlers. - * Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY. - * Log microseconds. - * Add --log_backtrace_at option. - * Fix some minor bugs. - -2008-11-18 Google Inc. - * google-glog: version 0.1.2 - * Add InstallFailureSignalHandler(). (satorux) - * Re-organize the way to produce stacktraces. - * Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS. - -2008-10-15 Google Inc. - * google-glog: version 0.1.1 - * Support symbolize for MacOSX 10.5. - * BUG FIX: --vmodule didn't work with gflags. - * BUG FIX: symbolize_unittest failed with GCC 4.3. - * Several fixes on the document. - -2008-10-07 Google Inc. - - * google-glog: initial release: - The glog package contains a library that implements application-level - logging. This library provides logging APIs based on C++-style - streams and various helper macros. diff --git a/third_party/src/glog/INSTALL b/third_party/src/glog/INSTALL deleted file mode 100644 index 0babe243..00000000 --- a/third_party/src/glog/INSTALL +++ /dev/null @@ -1,297 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Glog-Specific Install Notes -================================ - -*** NOTE FOR 64-BIT LINUX SYSTEMS - -The glibc built-in stack-unwinder on 64-bit systems has some problems -with the glog libraries. (In particular, if you are using -InstallFailureSignalHandler(), the signal may be raised in the middle -of malloc, holding some malloc-related locks when they invoke the -stack unwinder. The built-in stack unwinder may call malloc -recursively, which may require the thread to acquire a lock it already -holds: deadlock.) - -For that reason, if you use a 64-bit system and you need -InstallFailureSignalHandler(), we strongly recommend you install -libunwind before trying to configure or install google glog. -libunwind can be found at - - http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz - -Even if you already have libunwind installed, you will probably still -need to install from the snapshot to get the latest version. - -CAUTION: if you install libunwind from the URL above, be aware that -you may have trouble if you try to statically link your binary with -glog: that is, if you link with 'gcc -static -lgcc_eh ...'. This -is because both libunwind and libgcc implement the same C++ exception -handling APIs, but they implement them differently on some platforms. -This is not likely to be a problem on ia64, but may be on x86-64. - -Also, if you link binaries statically, make sure that you add --Wl,--eh-frame-hdr to your linker options. This is required so that -libunwind can find the information generated by the compiler required -for stack unwinding. - -Using -static is rare, though, so unless you know this will affect you -it probably won't. - -If you cannot or do not wish to install libunwind, you can still try -to use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder -and 2. frame pointer based stack-unwinder. - -1. As we already mentioned, glibc's unwinder has a deadlock issue. -However, if you don't use InstallFailureSignalHandler() or you don't -worry about the rare possibilities of deadlocks, you can use this -stack-unwinder. If you specify no options and libunwind isn't -detected on your system, the configure script chooses this unwinder by -default. - -2. The frame pointer based stack unwinder requires that your -application, the glog library, and system libraries like libc, all be -compiled with a frame pointer. This is *not* the default for x86-64. - -If you are on x86-64 system, know that you have a set of system -libraries with frame-pointers enabled, and compile all your -applications with -fno-omit-frame-pointer, then you can enable the -frame pointer based stack unwinder by passing the ---enable-frame-pointers flag to configure. - - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 6. Often, you can also type `make uninstall' to remove the installed - files again. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/third_party/src/glog/NEWS b/third_party/src/glog/NEWS deleted file mode 100644 index e69de29b..00000000 diff --git a/third_party/src/glog/README b/third_party/src/glog/README deleted file mode 100644 index 77efd375..00000000 --- a/third_party/src/glog/README +++ /dev/null @@ -1,5 +0,0 @@ -This repository contains a C++ implementation of the Google logging -module. Documentation for the implementation is in doc/. - -See INSTALL for (generic) installation instructions for C++: basically - ./configure && make && make install diff --git a/third_party/src/glog/README.windows b/third_party/src/glog/README.windows deleted file mode 100644 index 74ff6904..00000000 --- a/third_party/src/glog/README.windows +++ /dev/null @@ -1,26 +0,0 @@ -This project has begun being ported to Windows. A working solution -file exists in this directory: - google-glog.sln - -You can load this solution file into VC++ 9.0 (Visual Studio -2008). You may also be able to use this solution file with older -Visual Studios by converting the solution file. - -Note that stack tracing and some unittests are not ported -yet. - -You can also link glog code in statically -- see the example project -libglog_static and logging_unittest_static, which does this. For this -to work, you'll need to add "/D GOOGLE_GLOG_DLL_DECL=" to the compile -line of every glog's .cc file. - -I have little experience with Windows programming, so there may be -better ways to set this up than I've done! If you run across any -problems, please post to the google-glog Google Group, or report -them on the google-glog Google Code site: - http://groups.google.com/group/google-glog - http://code.google.com/p/google-glog/issues/list - --- Shinichiro Hamaji - -Last modified: 23 January 2009 diff --git a/third_party/src/glog/doc/designstyle.css b/third_party/src/glog/doc/designstyle.css deleted file mode 100644 index f5d1ec2f..00000000 --- a/third_party/src/glog/doc/designstyle.css +++ /dev/null @@ -1,115 +0,0 @@ -body { - background-color: #ffffff; - color: black; - margin-right: 1in; - margin-left: 1in; -} - - -h1, h2, h3, h4, h5, h6 { - color: #3366ff; - font-family: sans-serif; -} -@media print { - /* Darker version for printing */ - h1, h2, h3, h4, h5, h6 { - color: #000080; - font-family: helvetica, sans-serif; - } -} - -h1 { - text-align: center; - font-size: 18pt; -} -h2 { - margin-left: -0.5in; -} -h3 { - margin-left: -0.25in; -} -h4 { - margin-left: -0.125in; -} -hr { - margin-left: -1in; -} - -/* Definition lists: definition term bold */ -dt { - font-weight: bold; -} - -address { - text-align: right; -} -/* Use the tag for bits of code and for variables and objects. */ -code,pre,samp,var { - color: #006000; -} -/* Use the tag for file and directory paths and names. */ -file { - color: #905050; - font-family: monospace; -} -/* Use the tag for stuff the user should type. */ -kbd { - color: #600000; -} -div.note p { - float: right; - width: 3in; - margin-right: 0%; - padding: 1px; - border: 2px solid #6060a0; - background-color: #fffff0; -} - -UL.nobullets { - list-style-type: none; - list-style-image: none; - margin-left: -1em; -} - -/* -body:after { - content: "Google Confidential"; -} -*/ - -/* pretty printing styles. See prettify.js */ -.str { color: #080; } -.kwd { color: #008; } -.com { color: #800; } -.typ { color: #606; } -.lit { color: #066; } -.pun { color: #660; } -.pln { color: #000; } -.tag { color: #008; } -.atn { color: #606; } -.atv { color: #080; } -pre.prettyprint { padding: 2px; border: 1px solid #888; } - -.embsrc { background: #eee; } - -@media print { - .str { color: #060; } - .kwd { color: #006; font-weight: bold; } - .com { color: #600; font-style: italic; } - .typ { color: #404; font-weight: bold; } - .lit { color: #044; } - .pun { color: #440; } - .pln { color: #000; } - .tag { color: #006; font-weight: bold; } - .atn { color: #404; } - .atv { color: #060; } -} - -/* Table Column Headers */ -.hdr { - color: #006; - font-weight: bold; - background-color: #dddddd; } -.hdr2 { - color: #006; - background-color: #eeeeee; } \ No newline at end of file diff --git a/third_party/src/glog/doc/glog.html b/third_party/src/glog/doc/glog.html deleted file mode 100644 index 8b200bac..00000000 --- a/third_party/src/glog/doc/glog.html +++ /dev/null @@ -1,613 +0,0 @@ - - - - -How To Use Google Logging Library (glog) - - - - - - - - - -

How To Use Google Logging Library (glog)

-(as of -) - -
- -

Introduction

- -

Google glog is a library that implements application-level -logging. This library provides logging APIs based on C++-style -streams and various helper macros. -You can log a message by simply streaming things to LOG(<a -particular severity level>), e.g. - -

-   #include <glog/logging.h>
-
-   int main(int argc, char* argv[]) {
-     // Initialize Google's logging library.
-     google::InitGoogleLogging(argv[0]);
-
-     // ...
-     LOG(INFO) << "Found " << num_cookies << " cookies";
-   }
-
- -

Google glog defines a series of macros that simplify many common logging -tasks. You can log messages by severity level, control logging -behavior from the command line, log based on conditionals, abort the -program when expected conditions are not met, introduce your own -verbose logging levels, and more. This document describes the -functionality supported by glog. Please note that this document -doesn't describe all features in this library, but the most useful -ones. If you want to find less common features, please check -header files under src/glog directory. - -

Severity Level

- -

-You can specify one of the following severity levels (in -increasing order of severity): INFO, WARNING, -ERROR, and FATAL. -Logging a FATAL message terminates the program (after the -message is logged). -Note that messages of a given severity are logged not only in the -logfile for that severity, but also in all logfiles of lower severity. -E.g., a message of severity FATAL will be logged to the -logfiles of severity FATAL, ERROR, -WARNING, and INFO. - -

-The DFATAL severity logs a FATAL error in -debug mode (i.e., there is no NDEBUG macro defined), but -avoids halting the program in production by automatically reducing the -severity to ERROR. - -

Unless otherwise specified, glog writes to the filename -"/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>" -(e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474"). -By default, glog copies the log messages of severity level -ERROR or FATAL to standard error (stderr) -in addition to log files. - -

Setting Flags

- -

Several flags influence glog's output behavior. -If the Google -gflags library is installed on your machine, the -configure script (see the INSTALL file in the package for -detail of this script) will automatically detect and use it, -allowing you to pass flags on the command line. For example, if you -want to turn the flag --logtostderr on, you can start -your application with the following command line: - -

-   ./your_application --logtostderr=1
-
- -If the Google gflags library isn't installed, you set flags via -environment variables, prefixing the flag name with "GLOG_", e.g. - -
-   GLOG_logtostderr=1 ./your_application
-
- - - -

The following flags are most commonly used: - -

-
logtostderr (bool, default=false) -
Log messages to stderr instead of logfiles.
-Note: you can set binary flags to true by specifying -1, true, or yes (case -insensitive). -Also, you can set binary flags to false by specifying -0, false, or no (again, case -insensitive). -
stderrthreshold (int, default=2, which -is ERROR) -
Copy log messages at or above this level to stderr in -addition to logfiles. The numbers of severity levels -INFO, WARNING, ERROR, and -FATAL are 0, 1, 2, and 3, respectively. -
minloglevel (int, default=0, which -is INFO) -
Log messages at or above this level. Again, the numbers of -severity levels INFO, WARNING, -ERROR, and FATAL are 0, 1, 2, and 3, -respectively. -
log_dir (string, default="") -
If specified, logfiles are written into this directory instead -of the default logging directory. -
v (int, default=0) -
Show all VLOG(m) messages for m less or -equal the value of this flag. Overridable by --vmodule. -See the section about verbose logging for more -detail. -
vmodule (string, default="") -
Per-module verbose level. The argument has to contain a -comma-separated list of <module name>=<log level>. -<module name> -is a glob pattern (e.g., gfs* for all modules whose name -starts with "gfs"), matched against the filename base -(that is, name ignoring .cc/.h./-inl.h). -<log level> overrides any value given by --v. -See also the section about verbose logging. -
- -

There are some other flags defined in logging.cc. Please grep the -source code for "DEFINE_" to see a complete list of all flags. - -

You can also modify flag values in your program by modifying global -variables FLAGS_* . Most settings start working -immediately after you update FLAGS_* . The exceptions are -the flags related to destination files. For example, you might want to -set FLAGS_log_dir before -calling google::InitGoogleLogging . Here is an example: - -

-   LOG(INFO) << "file";
-   // Most flags work immediately after updating values.
-   FLAGS_logtostderr = 1;
-   LOG(INFO) << "stderr";
-   FLAGS_logtostderr = 0;
-   // This won't change the log destination. If you want to set this
-   // value, you should do this before google::InitGoogleLogging .
-   FLAGS_log_dir = "/some/log/directory";
-   LOG(INFO) << "the same file";
-
- -

Conditional / Occasional Logging

- -

Sometimes, you may only want to log a message under certain -conditions. You can use the following macros to perform conditional -logging: - -

-   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-
- -The "Got lots of cookies" message is logged only when the variable -num_cookies exceeds 10. - -If a line of code is executed many times, it may be useful to only log -a message at certain intervals. This kind of logging is most useful -for informational messages. - -
-   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-
- -

The above line outputs a log messages on the 1st, 11th, -21st, ... times it is executed. Note that the special -google::COUNTER value is used to identify which repetition is -happening. - -

You can combine conditional and occasional logging with the -following macro. - -

-   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
-                                           << "th big cookie";
-
- -

Instead of outputting a message every nth time, you can also limit -the output to the first n occurrences: - -

-   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
-
- -

Outputs log messages for the first 20 times it is executed. Again, -the google::COUNTER identifier indicates which repetition is -happening. - -

Debug Mode Support

- -

Special "debug mode" logging macros only have an effect in debug -mode and are compiled away to nothing for non-debug mode -compiles. Use these macros to avoid slowing down your production -application due to excessive logging. - -

-   DLOG(INFO) << "Found cookies";
-
-   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
-
-   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
-
- -

CHECK Macros

- -

It is a good practice to check expected conditions in your program -frequently to detect errors as early as possible. The -CHECK macro provides the ability to abort the application -when a condition is not met, similar to the assert macro -defined in the standard C library. - -

CHECK aborts the application if a condition is not -true. Unlike assert, it is *not* controlled by -NDEBUG, so the check will be executed regardless of -compilation mode. Therefore, fp->Write(x) in the -following example is always executed: - -

-   CHECK(fp->Write(x) == 4) << "Write failed!";
-
- -

There are various helper macros for -equality/inequality checks - CHECK_EQ, -CHECK_NE, CHECK_LE, CHECK_LT, -CHECK_GE, and CHECK_GT. -They compare two values, and log a -FATAL message including the two values when the result is -not as expected. The values must have operator<<(ostream, -...) defined. - -

You may append to the error message like so: - -

-   CHECK_NE(1, 2) << ": The world must be ending!";
-
- -

We are very careful to ensure that each argument is evaluated exactly -once, and that anything which is legal to pass as a function argument is -legal here. In particular, the arguments may be temporary expressions -which will end up being destroyed at the end of the apparent statement, -for example: - -

-   CHECK_EQ(string("abc")[1], 'b');
-
- -

The compiler reports an error if one of the arguments is a -pointer and the other is NULL. To work around this, simply static_cast -NULL to the type of the desired pointer. - -

-   CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL));
-
- -

Better yet, use the CHECK_NOTNULL macro: - -

-   CHECK_NOTNULL(some_ptr);
-   some_ptr->DoSomething();
-
- -

Since this macro returns the given pointer, this is very useful in -constructor initializer lists. - -

-   struct S {
-     S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {}
-     Something* ptr_;
-   };
-
- -

Note that you cannot use this macro as a C++ stream due to this -feature. Please use CHECK_EQ described above to log a -custom message before aborting the application. - -

If you are comparing C strings (char *), a handy set of macros -performs case sensitive as well as case insensitive comparisons - -CHECK_STREQ, CHECK_STRNE, -CHECK_STRCASEEQ, and CHECK_STRCASENE. The -CASE versions are case-insensitive. You can safely pass NULL -pointers for this macro. They treat NULL and any -non-NULL string as not equal. Two NULLs are -equal. - -

Note that both arguments may be temporary strings which are -destructed at the end of the current "full expression" -(e.g., CHECK_STREQ(Foo().c_str(), Bar().c_str()) where -Foo and Bar return C++'s -std::string). - -

The CHECK_DOUBLE_EQ macro checks the equality of two -floating point values, accepting a small error margin. -CHECK_NEAR accepts a third floating point argument, which -specifies the acceptable error margin. - -

Verbose Logging

- -

When you are chasing difficult bugs, thorough log messages are very -useful. However, you may want to ignore too verbose messages in usual -development. For such verbose logging, glog provides the -VLOG macro, which allows you to define your own numeric -logging levels. The --v command line option controls -which verbose messages are logged: - -

-   VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
-   VLOG(2) << "I'm printed when you run the program with --v=2 or higher";
-
- -

With VLOG, the lower the verbose level, the more -likely messages are to be logged. For example, if ---v==1, VLOG(1) will log, but -VLOG(2) will not log. This is opposite of the severity -level, where INFO is 0, and ERROR is 2. ---minloglevel of 1 will log WARNING and -above. Though you can specify any integers for both VLOG -macro and --v flag, the common values for them are small -positive integers. For example, if you write VLOG(0), -you should specify --v=-1 or lower to silence it. This -is less useful since we may not want verbose logs by default in most -cases. The VLOG macros always log at the -INFO log level (when they log at all). - -

Verbose logging can be controlled from the command line on a -per-module basis: - -

-   --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
-
- -

will: - -

    -
  • a. Print VLOG(2) and lower messages from mapreduce.{h,cc} -
  • b. Print VLOG(1) and lower messages from file.{h,cc} -
  • c. Print VLOG(3) and lower messages from files prefixed with "gfs" -
  • d. Print VLOG(0) and lower messages from elsewhere -
- -

The wildcarding functionality shown by (c) supports both '*' -(matches 0 or more characters) and '?' (matches any single character) -wildcards. Please also check the section about command line flags. - -

There's also VLOG_IS_ON(n) "verbose level" condition -macro. This macro returns true when the --v is equal or -greater than n. To be used as - -

-   if (VLOG_IS_ON(2)) {
-     // do some logging preparation and logging
-     // that can't be accomplished with just VLOG(2) << ...;
-   }
-
- -

Verbose level condition macros VLOG_IF, -VLOG_EVERY_N and VLOG_IF_EVERY_N behave -analogous to LOG_IF, LOG_EVERY_N, -LOF_IF_EVERY, but accept a numeric verbosity level as -opposed to a severity level. - -

-   VLOG_IF(1, (size > 1024))
-      << "I'm printed when size is more than 1024 and when you run the "
-         "program with --v=1 or more";
-   VLOG_EVERY_N(1, 10)
-      << "I'm printed every 10th occurrence, and when you run the program "
-         "with --v=1 or more. Present occurence is " << google::COUNTER;
-   VLOG_IF_EVERY_N(1, (size > 1024), 10)
-      << "I'm printed on every 10th occurence of case when size is more "
-         " than 1024, when you run the program with --v=1 or more. ";
-         "Present occurence is " << google::COUNTER;
-
- -

Failure Signal Handler

- -

-The library provides a convenient signal handler that will dump useful -information when the program crashes on certain signals such as SIGSEGV. -The signal handler can be installed by -google::InstallFailureSignalHandler(). The following is an example of output -from the signal handler. - -

-*** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***
-*** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***
-PC: @           0x412eb1 TestWaitingLogSink::send()
-    @     0x7f892fb417d0 (unknown)
-    @           0x412eb1 TestWaitingLogSink::send()
-    @     0x7f89304f7f06 google::LogMessage::SendToLog()
-    @     0x7f89304f35af google::LogMessage::Flush()
-    @     0x7f89304f3739 google::LogMessage::~LogMessage()
-    @           0x408cf4 TestLogSinkWaitTillSent()
-    @           0x4115de main
-    @     0x7f892f7ef1c4 (unknown)
-    @           0x4046f9 (unknown)
-
- -

-By default, the signal handler writes the failure dump to the standard -error. You can customize the destination by InstallFailureWriter(). - -

Miscellaneous Notes

- -

Performance of Messages

- -

The conditional logging macros provided by glog (e.g., -CHECK, LOG_IF, VLOG, ...) are -carefully implemented and don't execute the right hand side -expressions when the conditions are false. So, the following check -may not sacrifice the performance of your application. - -

-   CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow();
-
- -

User-defined Failure Function

- -

FATAL severity level messages or unsatisfied -CHECK condition terminate your program. You can change -the behavior of the termination by -InstallFailureFunction. - -

-   void YourFailureFunction() {
-     // Reports something...
-     exit(1);
-   }
-
-   int main(int argc, char* argv[]) {
-     google::InstallFailureFunction(&YourFailureFunction);
-   }
-
- -

By default, glog tries to dump stacktrace and makes the program -exit with status 1. The stacktrace is produced only when you run the -program on an architecture for which glog supports stack tracing (as -of September 2008, glog supports stack tracing for x86 and x86_64). - -

Raw Logging

- -

The header file <glog/raw_logging.h> can be -used for thread-safe logging, which does not allocate any memory or -acquire any locks. Therefore, the macros defined in this -header file can be used by low-level memory allocation and -synchronization code. -Please check src/glog/raw_logging.h.in for detail. -

- -

Google Style perror()

- -

PLOG() and PLOG_IF() and -PCHECK() behave exactly like their LOG* and -CHECK equivalents with the addition that they append a -description of the current state of errno to their output lines. -E.g. - -

-   PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed";
-
- -

This check fails with the following error message. - -

-   F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14]
-
- -

Syslog

- -

SYSLOG, SYSLOG_IF, and -SYSLOG_EVERY_N macros are available. -These log to syslog in addition to the normal logs. Be aware that -logging to syslog can drastically impact performance, especially if -syslog is configured for remote logging! Make sure you understand the -implications of outputting to syslog before you use these macros. In -general, it's wise to use these macros sparingly. - -

Strip Logging Messages

- -

Strings used in log messages can increase the size of your binary -and present a privacy concern. You can therefore instruct glog to -remove all strings which fall below a certain severity level by using -the GOOGLE_STRIP_LOG macro: - -

If your application has code like this: - -

-   #define GOOGLE_STRIP_LOG 1    // this must go before the #include!
-   #include <glog/logging.h>
-
- -

The compiler will remove the log messages whose severities are less -than the specified integer value. Since -VLOG logs at the severity level INFO -(numeric value 0), -setting GOOGLE_STRIP_LOG to 1 or greater removes -all log messages associated with VLOGs as well as -INFO log statements. - -

Notes for Windows users

- -

Google glog defines a severity level ERROR, which is -also defined in windows.h . You can make glog not define -INFO, WARNING, ERROR, -and FATAL by defining -GLOG_NO_ABBREVIATED_SEVERITIES before -including glog/logging.h . Even with this macro, you can -still use the iostream like logging facilities: - -

-  #define GLOG_NO_ABBREVIATED_SEVERITIES
-  #include <windows.h>
-  #include <glog/logging.h>
-
-  // ...
-
-  LOG(ERROR) << "This should work";
-  LOG_IF(ERROR, x > y) << "This should be also OK";
-
- -

-However, you cannot -use INFO, WARNING, ERROR, -and FATAL anymore for functions defined -in glog/logging.h . - -

-  #define GLOG_NO_ABBREVIATED_SEVERITIES
-  #include <windows.h>
-  #include <glog/logging.h>
-
-  // ...
-
-  // This won't work.
-  // google::FlushLogFiles(google::ERROR);
-
-  // Use this instead.
-  google::FlushLogFiles(google::GLOG_ERROR);
-
- -

-If you don't need ERROR defined -by windows.h, there are a couple of more workarounds -which sometimes don't work: - -

    -
  • #define WIN32_LEAN_AND_MEAN or NOGDI - before you #include windows.h . -
  • #undef ERROR after you #include - windows.h . -
- -

See -this issue for more detail. - -


-
-Shinichiro Hamaji
-Gregor Hohpe
- -
- - - diff --git a/third_party/src/glog/src/base/commandlineflags.h b/third_party/src/glog/src/base/commandlineflags.h deleted file mode 100644 index c8d50890..00000000 --- a/third_party/src/glog/src/base/commandlineflags.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2008, 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. - -// --- -// This file is a compatibility layer that defines Google's version of -// command line flags that are used for configuration. -// -// We put flags into their own namespace. It is purposefully -// named in an opaque way that people should have trouble typing -// directly. The idea is that DEFINE puts the flag in the weird -// namespace, and DECLARE imports the flag from there into the -// current namespace. The net result is to force people to use -// DECLARE to get access to a flag, rather than saying -// extern bool FLAGS_logtostderr; -// or some such instead. We want this so we can put extra -// functionality (like sanity-checking) in DECLARE if we want, -// and make sure it is picked up everywhere. -// -// We also put the type of the variable in the namespace, so that -// people can't DECLARE_int32 something that they DEFINE_bool'd -// elsewhere. -#ifndef BASE_COMMANDLINEFLAGS_H__ -#define BASE_COMMANDLINEFLAGS_H__ - -#include "config.h" -#include -#include // for memchr -#include // for getenv - -#ifdef HAVE_LIB_GFLAGS - -#include - -#else - -#include "glog/logging.h" - -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name -#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \ - namespace fL##shorttype { \ - GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) -#define DEFINE_bool(name, value, meaning) \ - DEFINE_VARIABLE(bool, B, name, value, meaning, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32) -#define DEFINE_int32(name, value, meaning) \ - DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32) - -// Special case for string, because we have to specify the namespace -// std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace fLS { \ - extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#define DEFINE_string(name, value, meaning) \ - namespace fLS { \ - std::string FLAGS_##name##_buf(value); \ - GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \ - char FLAGS_no##name; \ - } \ - using fLS::FLAGS_##name - -#endif // HAVE_LIB_GFLAGS - -// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we -// have GLOG_* environ variables even if we have gflags installed. -// -// If both an environment variable and a flag are specified, the value -// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the -// verbosity will be 1, not 0. - -#define GLOG_DEFINE_bool(name, value, meaning) \ - DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_int32(name, value, meaning) \ - DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_string(name, value, meaning) \ - DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning) - -// These macros (could be functions, but I don't want to bother with a .cc -// file), make it easier to initialize flags from the environment. - -#define EnvToString(envname, dflt) \ - (!getenv(envname) ? (dflt) : getenv(envname)) - -#define EnvToBool(envname, dflt) \ - (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL) - -#define EnvToInt(envname, dflt) \ - (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10)) - -#endif // BASE_COMMANDLINEFLAGS_H__ diff --git a/third_party/src/glog/src/base/googleinit.h b/third_party/src/glog/src/base/googleinit.h deleted file mode 100644 index 5a8b515c..00000000 --- a/third_party/src/glog/src/base/googleinit.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2008, 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: Jacob Hoffman-Andrews - -#ifndef _GOOGLEINIT_H -#define _GOOGLEINIT_H - -class GoogleInitializer { - public: - typedef void (*void_function)(void); - GoogleInitializer(const char*, void_function f) { - f(); - } -}; - -#define REGISTER_MODULE_INITIALIZER(name, body) \ - namespace { \ - static void google_init_module_##name () { body; } \ - GoogleInitializer google_initializer_module_##name(#name, \ - google_init_module_##name); \ - } - -#endif /* _GOOGLEINIT_H */ diff --git a/third_party/src/glog/src/base/mutex.h b/third_party/src/glog/src/base/mutex.h deleted file mode 100644 index 37527d58..00000000 --- a/third_party/src/glog/src/base/mutex.h +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2007, 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: Craig Silverstein. -// -// A simple mutex wrapper, supporting locks and read-write locks. -// You should assume the locks are *not* re-entrant. -// -// To use: you should define the following macros in your configure.ac: -// ACX_PTHREAD -// AC_RWLOCK -// The latter is defined in ../autoconf. -// -// This class is meant to be internal-only and should be wrapped by an -// internal namespace. Before you use this module, please give the -// name of your internal namespace for this module. Or, if you want -// to expose it, you'll want to move it to the Google namespace. We -// cannot put this class in global namespace because there can be some -// problems when we have multiple versions of Mutex in each shared object. -// -// NOTE: by default, we have #ifdef'ed out the TryLock() method. -// This is for two reasons: -// 1) TryLock() under Windows is a bit annoying (it requires a -// #define to be defined very early). -// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG -// mode. -// If you need TryLock(), and either these two caveats are not a -// problem for you, or you're willing to work around them, then -// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs -// in the code below. -// -// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: -// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html -// Because of that, we might as well use windows locks for -// cygwin. They seem to be more reliable than the cygwin pthreads layer. -// -// TRICKY IMPLEMENTATION NOTE: -// This class is designed to be safe to use during -// dynamic-initialization -- that is, by global constructors that are -// run before main() starts. The issue in this case is that -// dynamic-initialization happens in an unpredictable order, and it -// could be that someone else's dynamic initializer could call a -// function that tries to acquire this mutex -- but that all happens -// before this mutex's constructor has run. (This can happen even if -// the mutex and the function that uses the mutex are in the same .cc -// file.) Basically, because Mutex does non-trivial work in its -// constructor, it's not, in the naive implementation, safe to use -// before dynamic initialization has run on it. -// -// The solution used here is to pair the actual mutex primitive with a -// bool that is set to true when the mutex is dynamically initialized. -// (Before that it's false.) Then we modify all mutex routines to -// look at the bool, and not try to lock/unlock until the bool makes -// it to true (which happens after the Mutex constructor has run.) -// -// This works because before main() starts -- particularly, during -// dynamic initialization -- there are no threads, so a) it's ok that -// the mutex operations are a no-op, since we don't need locking then -// anyway; and b) we can be quite confident our bool won't change -// state between a call to Lock() and a call to Unlock() (that would -// require a global constructor in one translation unit to call Lock() -// and another global constructor in another translation unit to call -// Unlock() later, which is pretty perverse). -// -// That said, it's tricky, and can conceivably fail; it's safest to -// avoid trying to acquire a mutex in a global constructor, if you -// can. One way it can fail is that a really smart compiler might -// initialize the bool to true at static-initialization time (too -// early) rather than at dynamic-initialization time. To discourage -// that, we set is_safe_ to true in code (not the constructor -// colon-initializer) and set it to true via a function that always -// evaluates to true, but that the compiler can't know always -// evaluates to true. This should be good enough. - -#ifndef GOOGLE_MUTEX_H_ -#define GOOGLE_MUTEX_H_ - -#include "config.h" // to figure out pthreads support - -#if defined(NO_THREADS) - typedef int MutexType; // to keep a lock-count -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN // We only need minimal includes -# endif -# ifdef GMUTEX_TRYLOCK - // We need Windows NT or later for TryEnterCriticalSection(). If you - // don't need that functionality, you can remove these _WIN32_WINNT - // lines, and change TryLock() to assert(0) or something. -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# endif -// To avoid macro definition of ERROR. -# ifndef NOGDI -# define NOGDI -# endif -// To avoid macro definition of min/max. -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include - typedef CRITICAL_SECTION MutexType; -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - // Needed for pthread_rwlock_*. If it causes problems, you could take it - // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it - // *does* cause problems for FreeBSD, or MacOSX, but isn't needed - // for locking there.) -# ifdef __linux__ -# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls -# endif -# include - typedef pthread_rwlock_t MutexType; -#elif defined(HAVE_PTHREAD) -# include - typedef pthread_mutex_t MutexType; -#else -# error Need to implement mutex.h for your architecture, or #define NO_THREADS -#endif - -// We need to include these header files after defining _XOPEN_SOURCE -// as they may define the _XOPEN_SOURCE macro. -#include -#include // for abort() - -#define MUTEX_NAMESPACE glog_internal_namespace_ - -namespace MUTEX_NAMESPACE { - -class Mutex { - public: - // Create a Mutex that is not held by anybody. This constructor is - // typically used for Mutexes allocated on the heap or the stack. - // See below for a recommendation for constructing global Mutex - // objects. - inline Mutex(); - - // Destructor - inline ~Mutex(); - - inline void Lock(); // Block if needed until free then acquire exclusively - inline void Unlock(); // Release a lock acquired via Lock() -#ifdef GMUTEX_TRYLOCK - inline bool TryLock(); // If free, Lock() and return true, else return false -#endif - // Note that on systems that don't support read-write locks, these may - // be implemented as synonyms to Lock() and Unlock(). So you can use - // these for efficiency, but don't use them anyplace where being able - // to do shared reads is necessary to avoid deadlock. - inline void ReaderLock(); // Block until free or shared then acquire a share - inline void ReaderUnlock(); // Release a read share of this Mutex - inline void WriterLock() { Lock(); } // Acquire an exclusive lock - inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() - - // TODO(hamaji): Do nothing, implement correctly. - inline void AssertHeld() {} - - private: - MutexType mutex_; - // We want to make sure that the compiler sets is_safe_ to true only - // when we tell it to, and never makes assumptions is_safe_ is - // always true. volatile is the most reliable way to do that. - volatile bool is_safe_; - - inline void SetIsSafe() { is_safe_ = true; } - - // Catch the error of writing Mutex when intending MutexLock. - Mutex(Mutex* /*ignored*/) {} - // Disallow "evil" constructors - Mutex(const Mutex&); - void operator=(const Mutex&); -}; - -// Now the implementation of Mutex for various systems -#if defined(NO_THREADS) - -// When we don't have threads, we can be either reading or writing, -// but not both. We can have lots of readers at once (in no-threads -// mode, that's most likely to happen in recursive function calls), -// but only one writer. We represent this by having mutex_ be -1 when -// writing and a number > 0 when reading (and 0 when no lock is held). -// -// In debug mode, we assert these invariants, while in non-debug mode -// we do nothing, for efficiency. That's why everything is in an -// assert. - -Mutex::Mutex() : mutex_(0) { } -Mutex::~Mutex() { assert(mutex_ == 0); } -void Mutex::Lock() { assert(--mutex_ == -1); } -void Mutex::Unlock() { assert(mutex_++ == -1); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } -#endif -void Mutex::ReaderLock() { assert(++mutex_ > 0); } -void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } - -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) - -Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } -Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } -void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } -void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - TryEnterCriticalSection(&mutex_) != 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks -void Mutex::ReaderUnlock() { Unlock(); } - -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_rwlock_trywrlock(&mutex_) == 0 : - true; } -#endif -void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } -void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#undef SAFE_PTHREAD - -#elif defined(HAVE_PTHREAD) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_mutex_trylock(&mutex_) == 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } -void Mutex::ReaderUnlock() { Unlock(); } -#undef SAFE_PTHREAD - -#endif - -// -------------------------------------------------------------------------- -// Some helper classes - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } - ~MutexLock() { mu_->Unlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - MutexLock(const MutexLock&); - void operator=(const MutexLock&); -}; - -// ReaderMutexLock and WriterMutexLock do the same, for rwlocks -class ReaderMutexLock { - public: - explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } - ~ReaderMutexLock() { mu_->ReaderUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - ReaderMutexLock(const ReaderMutexLock&); - void operator=(const ReaderMutexLock&); -}; - -class WriterMutexLock { - public: - explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } - ~WriterMutexLock() { mu_->WriterUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - WriterMutexLock(const WriterMutexLock&); - void operator=(const WriterMutexLock&); -}; - -// Catch bug where variable name is omitted, e.g. MutexLock (&mu); -#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) -#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) -#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) - -} // namespace MUTEX_NAMESPACE - -using namespace MUTEX_NAMESPACE; - -#undef MUTEX_NAMESPACE - -#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/third_party/src/glog/src/config.h.in b/third_party/src/glog/src/config.h.in deleted file mode 100644 index 0c5e8b0e..00000000 --- a/third_party/src/glog/src/config.h.in +++ /dev/null @@ -1,171 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* define if glog doesn't use RTTI */ -#undef DISABLE_RTTI - -/* Namespace for Google classes */ -#undef GOOGLE_NAMESPACE - -/* Define if you have the `dladdr' function */ -#undef HAVE_DLADDR - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXECINFO_H - -/* Define if you have the `fcntl' function */ -#undef HAVE_FCNTL - -/* Define to 1 if you have the header file. */ -#undef HAVE_GLOB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#undef HAVE_LIBPTHREAD - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_H - -/* define if you have google gflags library */ -#undef HAVE_LIB_GFLAGS - -/* define if you have google gmock library */ -#undef HAVE_LIB_GMOCK - -/* define if you have google gtest library */ -#undef HAVE_LIB_GTEST - -/* define if you have libunwind */ -#undef HAVE_LIB_UNWIND - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Define to 1 if you have the header file. */ -#undef HAVE_PWD_H - -/* define if the compiler implements pthread_rwlock_* */ -#undef HAVE_RWLOCK - -/* Define if you have the `sigaltstack' function */ -#undef HAVE_SIGALTSTACK - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSLOG_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UTSNAME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNWIND_H - -/* define if the compiler supports using expression for operator */ -#undef HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#undef HAVE___BUILTIN_EXPECT - -/* define if your compiler has __sync_val_compare_and_swap */ -#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#undef PC_FROM_UCONTEXT - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#undef STL_NAMESPACE - -/* location of source code */ -#undef TEST_SRC_DIR - -/* Version number of package */ -#undef VERSION - -/* Stops putting the code inside the Google namespace */ -#undef _END_GOOGLE_NAMESPACE_ - -/* Puts following code inside the Google namespace */ -#undef _START_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/config_cmake.h.in b/third_party/src/glog/src/config_cmake.h.in deleted file mode 100644 index 3a3ecb0b..00000000 --- a/third_party/src/glog/src/config_cmake.h.in +++ /dev/null @@ -1,169 +0,0 @@ -/* define if glog doesn't use RTTI */ -/* #undef DISABLE_RTTI */ - -/* Namespace for Google classes */ -#define GOOGLE_NAMESPACE google - -/* Define if you have the `dladdr' function */ -/* #undef HAVE_DLADDR */ - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_EXECINFO_H 1 - -/* Define if you have the `fcntl' function */ -#cmakedefine HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GLOB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#cmakedefine HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBUNWIND_H 1 - -/* define if you have google gflags library */ -/* #undef HAVE_LIB_GFLAGS */ - -/* define if you have google gmock library */ -/* #undef HAVE_LIB_GMOCK */ - -/* define if you have google gtest library */ -/* #undef HAVE_LIB_GTEST */ - -/* define if you have libunwind */ -/* #undef HAVE_LIB_UNWIND */ - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* define if the compiler implements namespaces */ -#define HAVE_NAMESPACES 1 - -/* Define if you have POSIX threads libraries and header files. */ -#cmakedefine HAVE_PTHREAD 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PWD_H 1 - -/* define if the compiler implements pthread_rwlock_* */ -#cmakedefine HAVE_RWLOCK 1 - -/* Define if you have the `sigaltstack' function */ -#cmakedefine HAVE_SIGALTSTACK 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYSCALL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYSLOG_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SYSCALL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UCONTEXT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTSNAME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UCONTEXT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNWIND_H 1 - -/* define if the compiler supports using expression for operator */ -#define HAVE_USING_OPERATOR 1 - -/* define if your compiler has __attribute__ */ -#cmakedefine HAVE___ATTRIBUTE__ 1 - -/* define if your compiler has __builtin_expect */ -#cmakedefine HAVE___BUILTIN_EXPECT 1 - -/* define if your compiler has __sync_val_compare_and_swap */ -#cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "glog" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "opensource@google.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "glog" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "glog 0.3.3" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "glog" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.3.3" - -/* How to access the PC from a struct ucontext */ -#cmakedefine PC_FROM_UCONTEXT ${PC_FROM_UCONTEXT} - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* The size of `void *', as computed by sizeof. */ -#define SIZEOF_VOID_P ${SIZEOF_VOID_P} - -/* Define to 1 if you have the ANSI C header files. */ -/* #undef STDC_HEADERS */ - -/* the namespace where STL code like vector<> is defined */ -#define STL_NAMESPACE std - -/* location of source code */ -#define TEST_SRC_DIR "../glog" - -/* Version number of package */ -#define VERSION "0.3.3" - -/* Stops putting the code inside the Google namespace */ -#define _END_GOOGLE_NAMESPACE_ } - -/* Puts following code inside the Google namespace */ -#define _START_GOOGLE_NAMESPACE_ namespace google { diff --git a/third_party/src/glog/src/config_for_unittests.h b/third_party/src/glog/src/config_for_unittests.h deleted file mode 100644 index 13ea8eab..00000000 --- a/third_party/src/glog/src/config_for_unittests.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2008, 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. - -// --- -// All Rights Reserved. -// -// Author: Craig Silverstein -// Copied from google-perftools and modified by Shinichiro Hamaji -// -// This file is needed for windows -- unittests are not part of the -// glog dll, but still want to include config.h just like the -// dll does, so they can use internal tools and APIs for testing. -// -// The problem is that config.h declares GOOGLE_GLOG_DLL_DECL to be -// for exporting symbols, but the unittest needs to *import* symbols -// (since it's not the dll). -// -// The solution is to have this file, which is just like config.h but -// sets GOOGLE_GLOG_DLL_DECL to do a dllimport instead of a dllexport. -// -// The reason we need this extra GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -// variable is in case people want to set GOOGLE_GLOG_DLL_DECL explicitly -// to something other than __declspec(dllexport). In that case, they -// may want to use something other than __declspec(dllimport) for the -// unittest case. For that, we allow folks to define both -// GOOGLE_GLOG_DLL_DECL and GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS explicitly. -// -// NOTE: This file is equivalent to config.h on non-windows systems, -// which never defined GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS and always -// define GOOGLE_GLOG_DLL_DECL to the empty string. - -#include "config.h" - -#undef GOOGLE_GLOG_DLL_DECL -#ifdef GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -# define GOOGLE_GLOG_DLL_DECL GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS -#else -// if DLL_DECL_FOR_UNITTESTS isn't defined, use "" -# define GOOGLE_GLOG_DLL_DECL -#endif diff --git a/third_party/src/glog/src/demangle.cc b/third_party/src/glog/src/demangle.cc deleted file mode 100644 index e858181a..00000000 --- a/third_party/src/glog/src/demangle.cc +++ /dev/null @@ -1,1304 +0,0 @@ -// 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 -// -// For reference check out: -// http://www.codesourcery.com/public/cxx-abi/abi.html#mangling -// -// Note that we only have partial C++0x support yet. - -#include // for NULL -#include "demangle.h" - -_START_GOOGLE_NAMESPACE_ - -typedef struct { - const char *abbrev; - const char *real_name; -} AbbrevPair; - -// List of operators from Itanium C++ ABI. -static const AbbrevPair kOperatorList[] = { - { "nw", "new" }, - { "na", "new[]" }, - { "dl", "delete" }, - { "da", "delete[]" }, - { "ps", "+" }, - { "ng", "-" }, - { "ad", "&" }, - { "de", "*" }, - { "co", "~" }, - { "pl", "+" }, - { "mi", "-" }, - { "ml", "*" }, - { "dv", "/" }, - { "rm", "%" }, - { "an", "&" }, - { "or", "|" }, - { "eo", "^" }, - { "aS", "=" }, - { "pL", "+=" }, - { "mI", "-=" }, - { "mL", "*=" }, - { "dV", "/=" }, - { "rM", "%=" }, - { "aN", "&=" }, - { "oR", "|=" }, - { "eO", "^=" }, - { "ls", "<<" }, - { "rs", ">>" }, - { "lS", "<<=" }, - { "rS", ">>=" }, - { "eq", "==" }, - { "ne", "!=" }, - { "lt", "<" }, - { "gt", ">" }, - { "le", "<=" }, - { "ge", ">=" }, - { "nt", "!" }, - { "aa", "&&" }, - { "oo", "||" }, - { "pp", "++" }, - { "mm", "--" }, - { "cm", "," }, - { "pm", "->*" }, - { "pt", "->" }, - { "cl", "()" }, - { "ix", "[]" }, - { "qu", "?" }, - { "st", "sizeof" }, - { "sz", "sizeof" }, - { NULL, NULL }, -}; - -// List of builtin types from Itanium C++ ABI. -static const AbbrevPair kBuiltinTypeList[] = { - { "v", "void" }, - { "w", "wchar_t" }, - { "b", "bool" }, - { "c", "char" }, - { "a", "signed char" }, - { "h", "unsigned char" }, - { "s", "short" }, - { "t", "unsigned short" }, - { "i", "int" }, - { "j", "unsigned int" }, - { "l", "long" }, - { "m", "unsigned long" }, - { "x", "long long" }, - { "y", "unsigned long long" }, - { "n", "__int128" }, - { "o", "unsigned __int128" }, - { "f", "float" }, - { "d", "double" }, - { "e", "long double" }, - { "g", "__float128" }, - { "z", "ellipsis" }, - { NULL, NULL } -}; - -// List of substitutions Itanium C++ ABI. -static const AbbrevPair kSubstitutionList[] = { - { "St", "" }, - { "Sa", "allocator" }, - { "Sb", "basic_string" }, - // std::basic_string,std::allocator > - { "Ss", "string"}, - // std::basic_istream > - { "Si", "istream" }, - // std::basic_ostream > - { "So", "ostream" }, - // std::basic_iostream > - { "Sd", "iostream" }, - { NULL, NULL } -}; - -// State needed for demangling. -typedef struct { - const char *mangled_cur; // Cursor of mangled name. - char *out_cur; // Cursor of output string. - const char *out_begin; // Beginning of output string. - const char *out_end; // End of output string. - const char *prev_name; // For constructors/destructors. - int prev_name_length; // For constructors/destructors. - short nest_level; // For nested names. - bool append; // Append flag. - bool overflowed; // True if output gets overflowed. -} State; - -// We don't use strlen() in libc since it's not guaranteed to be async -// signal safe. -static size_t StrLen(const char *str) { - size_t len = 0; - while (*str != '\0') { - ++str; - ++len; - } - return len; -} - -// Returns true if "str" has at least "n" characters remaining. -static bool AtLeastNumCharsRemaining(const char *str, int n) { - for (int i = 0; i < n; ++i) { - if (str[i] == '\0') { - return false; - } - } - return true; -} - -// Returns true if "str" has "prefix" as a prefix. -static bool StrPrefix(const char *str, const char *prefix) { - size_t i = 0; - while (str[i] != '\0' && prefix[i] != '\0' && - str[i] == prefix[i]) { - ++i; - } - return prefix[i] == '\0'; // Consumed everything in "prefix". -} - -static void InitState(State *state, const char *mangled, - char *out, int out_size) { - state->mangled_cur = mangled; - state->out_cur = out; - state->out_begin = out; - state->out_end = out + out_size; - state->prev_name = NULL; - state->prev_name_length = -1; - state->nest_level = -1; - state->append = true; - state->overflowed = false; -} - -// Returns true and advances "mangled_cur" if we find "one_char_token" -// at "mangled_cur" position. It is assumed that "one_char_token" does -// not contain '\0'. -static bool ParseOneCharToken(State *state, const char one_char_token) { - if (state->mangled_cur[0] == one_char_token) { - ++state->mangled_cur; - return true; - } - return false; -} - -// Returns true and advances "mangled_cur" if we find "two_char_token" -// at "mangled_cur" position. It is assumed that "two_char_token" does -// not contain '\0'. -static bool ParseTwoCharToken(State *state, const char *two_char_token) { - if (state->mangled_cur[0] == two_char_token[0] && - state->mangled_cur[1] == two_char_token[1]) { - state->mangled_cur += 2; - return true; - } - return false; -} - -// Returns true and advances "mangled_cur" if we find any character in -// "char_class" at "mangled_cur" position. -static bool ParseCharClass(State *state, const char *char_class) { - const char *p = char_class; - for (; *p != '\0'; ++p) { - if (state->mangled_cur[0] == *p) { - ++state->mangled_cur; - return true; - } - } - return false; -} - -// This function is used for handling an optional non-terminal. -static bool Optional(bool) { - return true; -} - -// This function is used for handling + syntax. -typedef bool (*ParseFunc)(State *); -static bool OneOrMore(ParseFunc parse_func, State *state) { - if (parse_func(state)) { - while (parse_func(state)) { - } - return true; - } - return false; -} - -// This function is used for handling * syntax. The function -// always returns true and must be followed by a termination token or a -// terminating sequence not handled by parse_func (e.g. -// ParseOneCharToken(state, 'E')). -static bool ZeroOrMore(ParseFunc parse_func, State *state) { - while (parse_func(state)) { - } - return true; -} - -// Append "str" at "out_cur". If there is an overflow, "overflowed" -// is set to true for later use. The output string is ensured to -// always terminate with '\0' as long as there is no overflow. -static void Append(State *state, const char * const str, const int length) { - int i; - for (i = 0; i < length; ++i) { - if (state->out_cur + 1 < state->out_end) { // +1 for '\0' - *state->out_cur = str[i]; - ++state->out_cur; - } else { - state->overflowed = true; - break; - } - } - if (!state->overflowed) { - *state->out_cur = '\0'; // Terminate it with '\0' - } -} - -// We don't use equivalents in libc to avoid locale issues. -static bool IsLower(char c) { - return c >= 'a' && c <= 'z'; -} - -static bool IsAlpha(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); -} - -static bool IsDigit(char c) { - return c >= '0' && c <= '9'; -} - -// Returns true if "str" is a function clone suffix. These suffixes are used -// by GCC 4.5.x and later versions to indicate functions which have been -// cloned during optimization. We treat any sequence (.+.+)+ as -// a function clone suffix. -static bool IsFunctionCloneSuffix(const char *str) { - size_t i = 0; - while (str[i] != '\0') { - // Consume a single .+.+ sequence. - if (str[i] != '.' || !IsAlpha(str[i + 1])) { - return false; - } - i += 2; - while (IsAlpha(str[i])) { - ++i; - } - if (str[i] != '.' || !IsDigit(str[i + 1])) { - return false; - } - i += 2; - while (IsDigit(str[i])) { - ++i; - } - } - return true; // Consumed everything in "str". -} - -// Append "str" with some tweaks, iff "append" state is true. -// Returns true so that it can be placed in "if" conditions. -static void MaybeAppendWithLength(State *state, const char * const str, - const int length) { - if (state->append && length > 0) { - // Append a space if the output buffer ends with '<' and "str" - // starts with '<' to avoid <<<. - if (str[0] == '<' && state->out_begin < state->out_cur && - state->out_cur[-1] == '<') { - Append(state, " ", 1); - } - // Remember the last identifier name for ctors/dtors. - if (IsAlpha(str[0]) || str[0] == '_') { - state->prev_name = state->out_cur; - state->prev_name_length = length; - } - Append(state, str, length); - } -} - -// A convenient wrapper arount MaybeAppendWithLength(). -static bool MaybeAppend(State *state, const char * const str) { - if (state->append) { - int length = StrLen(str); - MaybeAppendWithLength(state, str, length); - } - return true; -} - -// This function is used for handling nested names. -static bool EnterNestedName(State *state) { - state->nest_level = 0; - return true; -} - -// This function is used for handling nested names. -static bool LeaveNestedName(State *state, short prev_value) { - state->nest_level = prev_value; - return true; -} - -// Disable the append mode not to print function parameters, etc. -static bool DisableAppend(State *state) { - state->append = false; - return true; -} - -// Restore the append mode to the previous state. -static bool RestoreAppend(State *state, bool prev_value) { - state->append = prev_value; - return true; -} - -// Increase the nest level for nested names. -static void MaybeIncreaseNestLevel(State *state) { - if (state->nest_level > -1) { - ++state->nest_level; - } -} - -// Appends :: for nested names if necessary. -static void MaybeAppendSeparator(State *state) { - if (state->nest_level >= 1) { - MaybeAppend(state, "::"); - } -} - -// Cancel the last separator if necessary. -static void MaybeCancelLastSeparator(State *state) { - if (state->nest_level >= 1 && state->append && - state->out_begin <= state->out_cur - 2) { - state->out_cur -= 2; - *state->out_cur = '\0'; - } -} - -// Returns true if the identifier of the given length pointed to by -// "mangled_cur" is anonymous namespace. -static bool IdentifierIsAnonymousNamespace(State *state, int length) { - static const char anon_prefix[] = "_GLOBAL__N_"; - return (length > (int)sizeof(anon_prefix) - 1 && // Should be longer. - StrPrefix(state->mangled_cur, anon_prefix)); -} - -// Forward declarations of our parsing functions. -static bool ParseMangledName(State *state); -static bool ParseEncoding(State *state); -static bool ParseName(State *state); -static bool ParseUnscopedName(State *state); -static bool ParseUnscopedTemplateName(State *state); -static bool ParseNestedName(State *state); -static bool ParsePrefix(State *state); -static bool ParseUnqualifiedName(State *state); -static bool ParseSourceName(State *state); -static bool ParseLocalSourceName(State *state); -static bool ParseNumber(State *state, int *number_out); -static bool ParseFloatNumber(State *state); -static bool ParseSeqId(State *state); -static bool ParseIdentifier(State *state, int length); -static bool ParseOperatorName(State *state); -static bool ParseSpecialName(State *state); -static bool ParseCallOffset(State *state); -static bool ParseNVOffset(State *state); -static bool ParseVOffset(State *state); -static bool ParseCtorDtorName(State *state); -static bool ParseType(State *state); -static bool ParseCVQualifiers(State *state); -static bool ParseBuiltinType(State *state); -static bool ParseFunctionType(State *state); -static bool ParseBareFunctionType(State *state); -static bool ParseClassEnumType(State *state); -static bool ParseArrayType(State *state); -static bool ParsePointerToMemberType(State *state); -static bool ParseTemplateParam(State *state); -static bool ParseTemplateTemplateParam(State *state); -static bool ParseTemplateArgs(State *state); -static bool ParseTemplateArg(State *state); -static bool ParseExpression(State *state); -static bool ParseExprPrimary(State *state); -static bool ParseLocalName(State *state); -static bool ParseDiscriminator(State *state); -static bool ParseSubstitution(State *state); - -// Implementation note: the following code is a straightforward -// translation of the Itanium C++ ABI defined in BNF with a couple of -// exceptions. -// -// - Support GNU extensions not defined in the Itanium C++ ABI -// - and are combined to avoid infinite loop -// - Reorder patterns to shorten the code -// - Reorder patterns to give greedier functions precedence -// We'll mark "Less greedy than" for these cases in the code -// -// Each parsing function changes the state and returns true on -// success. Otherwise, don't change the state and returns false. To -// ensure that the state isn't changed in the latter case, we save the -// original state before we call more than one parsing functions -// consecutively with &&, and restore the state if unsuccessful. See -// ParseEncoding() as an example of this convention. We follow the -// convention throughout the code. -// -// Originally we tried to do demangling without following the full ABI -// syntax but it turned out we needed to follow the full syntax to -// parse complicated cases like nested template arguments. Note that -// implementing a full-fledged demangler isn't trivial (libiberty's -// cp-demangle.c has +4300 lines). -// -// Note that (foo) in <(foo) ...> is a modifier to be ignored. -// -// Reference: -// - Itanium C++ ABI -// - -// ::= _Z -static bool ParseMangledName(State *state) { - return ParseTwoCharToken(state, "_Z") && ParseEncoding(state); -} - -// ::= <(function) name> -// ::= <(data) name> -// ::= -static bool ParseEncoding(State *state) { - State copy = *state; - if (ParseName(state) && ParseBareFunctionType(state)) { - return true; - } - *state = copy; - - if (ParseName(state) || ParseSpecialName(state)) { - return true; - } - return false; -} - -// ::= -// ::= -// ::= -// ::= -static bool ParseName(State *state) { - if (ParseNestedName(state) || ParseLocalName(state)) { - return true; - } - - State copy = *state; - if (ParseUnscopedTemplateName(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - // Less greedy than . - if (ParseUnscopedName(state)) { - return true; - } - return false; -} - -// ::= -// ::= St -static bool ParseUnscopedName(State *state) { - if (ParseUnqualifiedName(state)) { - return true; - } - - State copy = *state; - if (ParseTwoCharToken(state, "St") && - MaybeAppend(state, "std::") && - ParseUnqualifiedName(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= -// ::= -static bool ParseUnscopedTemplateName(State *state) { - return ParseUnscopedName(state) || ParseSubstitution(state); -} - -// ::= N [] E -// ::= N [] E -static bool ParseNestedName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'N') && - EnterNestedName(state) && - Optional(ParseCVQualifiers(state)) && - ParsePrefix(state) && - LeaveNestedName(state, copy.nest_level) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// This part is tricky. If we literally translate them to code, we'll -// end up infinite loop. Hence we merge them to avoid the case. -// -// ::= -// ::= -// ::= -// ::= -// ::= # empty -// ::= <(template) unqualified-name> -// ::= -// ::= -static bool ParsePrefix(State *state) { - bool has_something = false; - while (true) { - MaybeAppendSeparator(state); - if (ParseTemplateParam(state) || - ParseSubstitution(state) || - ParseUnscopedName(state)) { - has_something = true; - MaybeIncreaseNestLevel(state); - continue; - } - MaybeCancelLastSeparator(state); - if (has_something && ParseTemplateArgs(state)) { - return ParsePrefix(state); - } else { - break; - } - } - return true; -} - -// ::= -// ::= -// ::= -// ::= -static bool ParseUnqualifiedName(State *state) { - return (ParseOperatorName(state) || - ParseCtorDtorName(state) || - ParseSourceName(state) || - ParseLocalSourceName(state)); -} - -// ::= -static bool ParseSourceName(State *state) { - State copy = *state; - int length = -1; - if (ParseNumber(state, &length) && ParseIdentifier(state, length)) { - return true; - } - *state = copy; - return false; -} - -// ::= L [] -// -// References: -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 -// http://gcc.gnu.org/viewcvs?view=rev&revision=124467 -static bool ParseLocalSourceName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'L') && ParseSourceName(state) && - Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - return false; -} - -// ::= [n] -// If "number_out" is non-null, then *number_out is set to the value of the -// parsed number on success. -static bool ParseNumber(State *state, int *number_out) { - int sign = 1; - if (ParseOneCharToken(state, 'n')) { - sign = -1; - } - const char *p = state->mangled_cur; - int number = 0; - for (;*p != '\0'; ++p) { - if (IsDigit(*p)) { - number = number * 10 + (*p - '0'); - } else { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - if (number_out != NULL) { - *number_out = number * sign; - } - return true; - } - return false; -} - -// Floating-point literals are encoded using a fixed-length lowercase -// hexadecimal string. -static bool ParseFloatNumber(State *state) { - const char *p = state->mangled_cur; - for (;*p != '\0'; ++p) { - if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - return true; - } - return false; -} - -// The is a sequence number in base 36, -// using digits and upper case letters -static bool ParseSeqId(State *state) { - const char *p = state->mangled_cur; - for (;*p != '\0'; ++p) { - if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) { - break; - } - } - if (p != state->mangled_cur) { // Conversion succeeded. - state->mangled_cur = p; - return true; - } - return false; -} - -// ::= (of given length) -static bool ParseIdentifier(State *state, int length) { - if (length == -1 || - !AtLeastNumCharsRemaining(state->mangled_cur, length)) { - return false; - } - if (IdentifierIsAnonymousNamespace(state, length)) { - MaybeAppend(state, "(anonymous namespace)"); - } else { - MaybeAppendWithLength(state, state->mangled_cur, length); - } - state->mangled_cur += length; - return true; -} - -// ::= nw, and other two letters cases -// ::= cv # (cast) -// ::= v # vendor extended operator -static bool ParseOperatorName(State *state) { - if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) { - return false; - } - // First check with "cv" (cast) case. - State copy = *state; - if (ParseTwoCharToken(state, "cv") && - MaybeAppend(state, "operator ") && - EnterNestedName(state) && - ParseType(state) && - LeaveNestedName(state, copy.nest_level)) { - return true; - } - *state = copy; - - // Then vendor extended operators. - if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") && - ParseSourceName(state)) { - return true; - } - *state = copy; - - // Other operator names should start with a lower alphabet followed - // by a lower/upper alphabet. - if (!(IsLower(state->mangled_cur[0]) && - IsAlpha(state->mangled_cur[1]))) { - return false; - } - // We may want to perform a binary search if we really need speed. - const AbbrevPair *p; - for (p = kOperatorList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[0] && - state->mangled_cur[1] == p->abbrev[1]) { - MaybeAppend(state, "operator"); - if (IsLower(*p->real_name)) { // new, delete, etc. - MaybeAppend(state, " "); - } - MaybeAppend(state, p->real_name); - state->mangled_cur += 2; - return true; - } - } - return false; -} - -// ::= TV -// ::= TT -// ::= TI -// ::= TS -// ::= Tc <(base) encoding> -// ::= GV <(object) name> -// ::= T <(base) encoding> -// G++ extensions: -// ::= TC <(offset) number> _ <(base) type> -// ::= TF -// ::= TJ -// ::= GR -// ::= GA -// ::= Th <(base) encoding> -// ::= Tv <(base) encoding> -// -// Note: we don't care much about them since they don't appear in -// stack traces. The are special data. -static bool ParseSpecialName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'T') && - ParseCharClass(state, "VTIS") && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) && - ParseCallOffset(state) && ParseEncoding(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GV") && - ParseName(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) && - ParseEncoding(state)) { - return true; - } - *state = copy; - - // G++ extensions - if (ParseTwoCharToken(state, "TC") && ParseType(state) && - ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && - DisableAppend(state) && - ParseType(state)) { - RestoreAppend(state, copy.append); - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GR") && ParseName(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") && - ParseCallOffset(state) && ParseEncoding(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= h _ -// ::= v _ -static bool ParseCallOffset(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'h') && - ParseNVOffset(state) && ParseOneCharToken(state, '_')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'v') && - ParseVOffset(state) && ParseOneCharToken(state, '_')) { - return true; - } - *state = copy; - - return false; -} - -// ::= <(offset) number> -static bool ParseNVOffset(State *state) { - return ParseNumber(state, NULL); -} - -// ::= <(offset) number> _ <(virtual offset) number> -static bool ParseVOffset(State *state) { - State copy = *state; - if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && - ParseNumber(state, NULL)) { - return true; - } - *state = copy; - return false; -} - -// ::= C1 | C2 | C3 -// ::= D0 | D1 | D2 -static bool ParseCtorDtorName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'C') && - ParseCharClass(state, "123")) { - const char * const prev_name = state->prev_name; - const int prev_name_length = state->prev_name_length; - MaybeAppendWithLength(state, prev_name, prev_name_length); - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'D') && - ParseCharClass(state, "012")) { - const char * const prev_name = state->prev_name; - const int prev_name_length = state->prev_name_length; - MaybeAppend(state, "~"); - MaybeAppendWithLength(state, prev_name, prev_name_length); - return true; - } - *state = copy; - return false; -} - -// ::= -// ::= P # pointer-to -// ::= R # reference-to -// ::= O # rvalue reference-to (C++0x) -// ::= C # complex pair (C 2000) -// ::= G # imaginary (C 2000) -// ::= U # vendor extended type qualifier -// ::= -// ::= -// ::= -// ::= -// ::= -// ::= -// ::= -// ::= -// ::= Dp # pack expansion of (C++0x) -// ::= Dt E # decltype of an id-expression or class -// # member access (C++0x) -// ::= DT E # decltype of an expression (C++0x) -// -static bool ParseType(State *state) { - // We should check CV-qualifers, and PRGC things first. - State copy = *state; - if (ParseCVQualifiers(state) && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseCharClass(state, "OPRCG") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "Dp") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") && - ParseExpression(state) && ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && - ParseType(state)) { - return true; - } - *state = copy; - - if (ParseBuiltinType(state) || - ParseFunctionType(state) || - ParseClassEnumType(state) || - ParseArrayType(state) || - ParsePointerToMemberType(state) || - ParseSubstitution(state)) { - return true; - } - - if (ParseTemplateTemplateParam(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - // Less greedy than . - if (ParseTemplateParam(state)) { - return true; - } - - return false; -} - -// ::= [r] [V] [K] -// We don't allow empty to avoid infinite loop in -// ParseType(). -static bool ParseCVQualifiers(State *state) { - int num_cv_qualifiers = 0; - num_cv_qualifiers += ParseOneCharToken(state, 'r'); - num_cv_qualifiers += ParseOneCharToken(state, 'V'); - num_cv_qualifiers += ParseOneCharToken(state, 'K'); - return num_cv_qualifiers > 0; -} - -// ::= v, etc. -// ::= u -static bool ParseBuiltinType(State *state) { - const AbbrevPair *p; - for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[0]) { - MaybeAppend(state, p->real_name); - ++state->mangled_cur; - return true; - } - } - - State copy = *state; - if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= F [Y] E -static bool ParseFunctionType(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'F') && - Optional(ParseOneCharToken(state, 'Y')) && - ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// ::= <(signature) type>+ -static bool ParseBareFunctionType(State *state) { - State copy = *state; - DisableAppend(state); - if (OneOrMore(ParseType, state)) { - RestoreAppend(state, copy.append); - MaybeAppend(state, "()"); - return true; - } - *state = copy; - return false; -} - -// ::= -static bool ParseClassEnumType(State *state) { - return ParseName(state); -} - -// ::= A <(positive dimension) number> _ <(element) type> -// ::= A [<(dimension) expression>] _ <(element) type> -static bool ParseArrayType(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) && - ParseOneCharToken(state, '_') && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) && - ParseOneCharToken(state, '_') && ParseType(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= M <(class) type> <(member) type> -static bool ParsePointerToMemberType(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'M') && ParseType(state) && - ParseType(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= T_ -// ::= T _ -static bool ParseTemplateParam(State *state) { - if (ParseTwoCharToken(state, "T_")) { - MaybeAppend(state, "?"); // We don't support template substitutions. - return true; - } - - State copy = *state; - if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) && - ParseOneCharToken(state, '_')) { - MaybeAppend(state, "?"); // We don't support template substitutions. - return true; - } - *state = copy; - return false; -} - - -// ::= -// ::= -static bool ParseTemplateTemplateParam(State *state) { - return (ParseTemplateParam(state) || - ParseSubstitution(state)); -} - -// ::= I + E -static bool ParseTemplateArgs(State *state) { - State copy = *state; - DisableAppend(state); - if (ParseOneCharToken(state, 'I') && - OneOrMore(ParseTemplateArg, state) && - ParseOneCharToken(state, 'E')) { - RestoreAppend(state, copy.append); - MaybeAppend(state, "<>"); - return true; - } - *state = copy; - return false; -} - -// ::= -// ::= -// ::= I * E # argument pack -// ::= X E -static bool ParseTemplateArg(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'I') && - ZeroOrMore(ParseTemplateArg, state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseType(state) || - ParseExprPrimary(state)) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'X') && ParseExpression(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - return false; -} - -// ::= -// ::= -// ::= -// ::= -// ::= -// -// ::= st -// ::= sr -// ::= sr -static bool ParseExpression(State *state) { - if (ParseTemplateParam(state) || ParseExprPrimary(state)) { - return true; - } - - State copy = *state; - if (ParseOperatorName(state) && - ParseExpression(state) && - ParseExpression(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseOperatorName(state) && - ParseExpression(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseOperatorName(state) && - ParseExpression(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "st") && ParseType(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "sr") && ParseType(state) && - ParseUnqualifiedName(state) && - ParseTemplateArgs(state)) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "sr") && ParseType(state) && - ParseUnqualifiedName(state)) { - return true; - } - *state = copy; - return false; -} - -// ::= L <(value) number> E -// ::= L <(value) float> E -// ::= L E -// // A bug in g++'s C++ ABI version 2 (-fabi-version=2). -// ::= LZ E -static bool ParseExprPrimary(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'L') && ParseType(state) && - ParseNumber(state, NULL) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'L') && ParseType(state) && - ParseFloatNumber(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'L') && ParseMangledName(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - *state = copy; - - return false; -} - -// := Z <(function) encoding> E <(entity) name> -// [] -// := Z <(function) encoding> E s [] -static bool ParseLocalName(State *state) { - State copy = *state; - if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && - ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") && - ParseName(state) && Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - - if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) && - ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) { - return true; - } - *state = copy; - return false; -} - -// := _ <(non-negative) number> -static bool ParseDiscriminator(State *state) { - State copy = *state; - if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) { - return true; - } - *state = copy; - return false; -} - -// ::= S_ -// ::= S _ -// ::= St, etc. -static bool ParseSubstitution(State *state) { - if (ParseTwoCharToken(state, "S_")) { - MaybeAppend(state, "?"); // We don't support substitutions. - return true; - } - - State copy = *state; - if (ParseOneCharToken(state, 'S') && ParseSeqId(state) && - ParseOneCharToken(state, '_')) { - MaybeAppend(state, "?"); // We don't support substitutions. - return true; - } - *state = copy; - - // Expand abbreviations like "St" => "std". - if (ParseOneCharToken(state, 'S')) { - const AbbrevPair *p; - for (p = kSubstitutionList; p->abbrev != NULL; ++p) { - if (state->mangled_cur[0] == p->abbrev[1]) { - MaybeAppend(state, "std"); - if (p->real_name[0] != '\0') { - MaybeAppend(state, "::"); - MaybeAppend(state, p->real_name); - } - ++state->mangled_cur; - return true; - } - } - } - *state = copy; - return false; -} - -// Parse , optionally followed by either a function-clone suffix -// or version suffix. Returns true only if all of "mangled_cur" was consumed. -static bool ParseTopLevelMangledName(State *state) { - if (ParseMangledName(state)) { - if (state->mangled_cur[0] != '\0') { - // Drop trailing function clone suffix, if any. - if (IsFunctionCloneSuffix(state->mangled_cur)) { - return true; - } - // Append trailing version suffix if any. - // ex. _Z3foo@@GLIBCXX_3.4 - if (state->mangled_cur[0] == '@') { - MaybeAppend(state, state->mangled_cur); - return true; - } - return false; // Unconsumed suffix. - } - return true; - } - return false; -} - -// The demangler entry point. -bool Demangle(const char *mangled, char *out, int out_size) { - State state; - InitState(&state, mangled, out, out_size); - return ParseTopLevelMangledName(&state) && !state.overflowed; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/demangle.h b/third_party/src/glog/src/demangle.h deleted file mode 100644 index 9c759152..00000000 --- a/third_party/src/glog/src/demangle.h +++ /dev/null @@ -1,84 +0,0 @@ -// 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 -// -// An async-signal-safe and thread-safe demangler for Itanium C++ ABI -// (aka G++ V3 ABI). - -// The demangler is implemented to be used in async signal handlers to -// symbolize stack traces. We cannot use libstdc++'s -// abi::__cxa_demangle() in such signal handlers since it's not async -// signal safe (it uses malloc() internally). -// -// Note that this demangler doesn't support full demangling. More -// specifically, it doesn't print types of function parameters and -// types of template arguments. It just skips them. However, it's -// still very useful to extract basic information such as class, -// function, constructor, destructor, and operator names. -// -// See the implementation note in demangle.cc if you are interested. -// -// Example: -// -// | Mangled Name | The Demangler | abi::__cxa_demangle() -// |---------------|---------------|----------------------- -// | _Z1fv | f() | f() -// | _Z1fi | f() | f(int) -// | _Z3foo3bar | foo() | foo(bar) -// | _Z1fIiEvi | f<>() | void f(int) -// | _ZN1N1fE | N::f | N::f -// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() -// | _Zrm1XS_" | operator%() | operator%(X, X) -// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() -// | _Z1fSs | f() | f(std::basic_string, -// | | | std::allocator >) -// -// See the unit test for more examples. -// -// Note: we might want to write demanglers for ABIs other than Itanium -// C++ ABI in the future. -// - -#ifndef BASE_DEMANGLE_H_ -#define BASE_DEMANGLE_H_ - -#include "config.h" - -_START_GOOGLE_NAMESPACE_ - -// Demangle "mangled". On success, return true and write the -// demangled symbol name to "out". Otherwise, return false. -// "out" is modified even if demangling is unsuccessful. -bool Demangle(const char *mangled, char *out, int out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_DEMANGLE_H_ diff --git a/third_party/src/glog/src/demangle_unittest.cc b/third_party/src/glog/src/demangle_unittest.cc deleted file mode 100644 index 9d219e65..00000000 --- a/third_party/src/glog/src/demangle_unittest.cc +++ /dev/null @@ -1,142 +0,0 @@ -// 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 demangle.c. - -#include "utilities.h" - -#include -#include -#include -#include "glog/logging.h" -#include "demangle.h" -#include "googletest.h" -#include "config.h" - -GLOG_DEFINE_bool(demangle_filter, false, - "Run demangle_unittest in filter mode"); - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -// A wrapper function for Demangle() to make the unit test simple. -static const char *DemangleIt(const char * const mangled) { - static char demangled[4096]; - if (Demangle(mangled, demangled, sizeof(demangled))) { - return demangled; - } else { - return mangled; - } -} - -// Test corner cases of bounary conditions. -TEST(Demangle, CornerCases) { - char tmp[10]; - EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp))); - // sizeof("foobar()") == 9 - EXPECT_STREQ("foobar()", tmp); - EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9)); - EXPECT_STREQ("foobar()", tmp); - EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8)); // Not enough. - EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1)); - EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0)); - EXPECT_FALSE(Demangle("_Z6foobarv", NULL, 0)); // Should not cause SEGV. -} - -// Test handling of functions suffixed with .clone.N, which is used by GCC -// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x. These -// suffixes are used to indicate functions which have been cloned during -// optimization. We ignore these suffixes. -TEST(Demangle, Clones) { - char tmp[20]; - EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp))); - EXPECT_STREQ("Foo()", tmp); - // Invalid (truncated), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp))); - // Invalid (.clone. not followed by number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp))); - // Invalid (.clone. followed by non-number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp))); - // Invalid (.constprop. not followed by number), should not demangle. - EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp))); -} - -TEST(Demangle, FromFile) { - string test_file = FLAGS_test_srcdir + "/src/demangle_unittest.txt"; - ifstream f(test_file.c_str()); // The file should exist. - EXPECT_FALSE(f.fail()); - - string line; - while (getline(f, line)) { - // Lines start with '#' are considered as comments. - if (line.empty() || line[0] == '#') { - continue; - } - // Each line should contain a mangled name and a demangled name - // separated by '\t'. Example: "_Z3foo\tfoo" - string::size_type tab_pos = line.find('\t'); - EXPECT_NE(string::npos, tab_pos); - string mangled = line.substr(0, tab_pos); - string demangled = line.substr(tab_pos + 1); - EXPECT_EQ(demangled, DemangleIt(mangled.c_str())); - } -} - -int main(int argc, char **argv) { -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - InitGoogleTest(&argc, argv); - - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - if (FLAGS_demangle_filter) { - // Read from cin and write to cout. - string line; - while (getline(cin, line, '\n')) { - cout << DemangleIt(line.c_str()) << endl; - } - return 0; - } else if (argc > 1) { - cout << DemangleIt(argv[1]) << endl; - return 0; - } else { - return RUN_ALL_TESTS(); - } -} diff --git a/third_party/src/glog/src/demangle_unittest.sh b/third_party/src/glog/src/demangle_unittest.sh deleted file mode 100644 index 91deee21..00000000 --- a/third_party/src/glog/src/demangle_unittest.sh +++ /dev/null @@ -1,95 +0,0 @@ -#! /bin/sh -# -# 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 demangle.c with a real binary. - -set -e - -die () { - echo $1 - exit 1 -} - -BINDIR=".libs" -LIBGLOG="$BINDIR/libglog.so" - -DEMANGLER="$BINDIR/demangle_unittest" - -if test -e "$DEMANGLER"; then - # We need shared object. - export LD_LIBRARY_PATH=$BINDIR - export DYLD_LIBRARY_PATH=$BINDIR -else - # For windows - DEMANGLER="./demangle_unittest.exe" - if ! test -e "$DEMANGLER"; then - echo "We coundn't find demangle_unittest binary." - exit 1 - fi -fi - -# Extract C++ mangled symbols from libbase.so. -NM_OUTPUT="demangle.nm" -nm "$LIBGLOG" | perl -nle 'print $1 if /\s(_Z\S+$)/' > "$NM_OUTPUT" - -# Check if mangled symbols exist. If there are none, we quit. -# The binary is more likely compiled with GCC 2.95 or something old. -if ! grep --quiet '^_Z' "$NM_OUTPUT"; then - echo "PASS" - exit 0 -fi - -# Demangle the symbols using our demangler. -DM_OUTPUT="demangle.dm" -GLOG_demangle_filter=1 "$DEMANGLER" --demangle_filter < "$NM_OUTPUT" > "$DM_OUTPUT" - -# Calculate the numbers of lines. -NM_LINES=`wc -l "$NM_OUTPUT" | awk '{ print $1 }'` -DM_LINES=`wc -l "$DM_OUTPUT" | awk '{ print $1 }'` - -# Compare the numbers of lines. They must be the same. -if test "$NM_LINES" != "$DM_LINES"; then - die "$NM_OUTPUT and $DM_OUTPUT don't have the same numbers of lines" -fi - -# Check if mangled symbols exist. They must not exist. -if grep --quiet '^_Z' "$DM_OUTPUT"; then - MANGLED=`grep '^_Z' "$DM_OUTPUT" | wc -l | awk '{ print \$1 }'` - echo "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT:" - grep '^_Z' "$DM_OUTPUT" - die "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT" -fi - -# All C++ symbols are demangled successfully. -echo "PASS" -exit 0 diff --git a/third_party/src/glog/src/demangle_unittest.txt b/third_party/src/glog/src/demangle_unittest.txt deleted file mode 100644 index 4e23c65b..00000000 --- a/third_party/src/glog/src/demangle_unittest.txt +++ /dev/null @@ -1,137 +0,0 @@ -# Test caces for demangle_unittest. Each line consists of a -# tab-separated pair of mangled and demangled symbol names. - -# Constructors and destructors. -_ZN3FooC1Ev Foo::Foo() -_ZN3FooD1Ev Foo::~Foo() -_ZNSoD0Ev std::ostream::~ostream() - -# G++ extensions. -_ZTCN10LogMessage9LogStreamE0_So LogMessage::LogStream -_ZTv0_n12_N10LogMessage9LogStreamD0Ev LogMessage::LogStream::~LogStream() -_ZThn4_N7icu_3_410UnicodeSetD0Ev icu_3_4::UnicodeSet::~UnicodeSet() - -# A bug in g++'s C++ ABI version 2 (-fabi-version=2). -_ZN7NSSInfoI5groupjjXadL_Z10getgrgid_rEELZ19nss_getgrgid_r_nameEEC1Ei NSSInfo<>::NSSInfo() - -# C linkage symbol names. Should keep them untouched. -main main -Demangle Demangle -_ZERO _ZERO - -# Cast operator. -_Zcviv operator int() -_ZN3foocviEv foo::operator int() - -# Versioned symbols. -_Z3Foo@GLIBCXX_3.4 Foo@GLIBCXX_3.4 -_Z3Foo@@GLIBCXX_3.4 Foo@@GLIBCXX_3.4 - -# Abbreviations. -_ZNSaE std::allocator -_ZNSbE std::basic_string -_ZNSdE std::iostream -_ZNSiE std::istream -_ZNSoE std::ostream -_ZNSsE std::string - -# Substitutions. We just replace them with ?. -_ZN3fooS_E foo::? -_ZN3foo3barS0_E foo::bar::? -_ZNcvT_IiEEv operator ?<>() - -# "<< <" case. -_ZlsI3fooE operator<< <> - -# Random things we found interesting. -_ZN3FooISt6vectorISsSaISsEEEclEv Foo<>::operator()() -_ZTI9Callback1IiE Callback1<> -_ZN7icu_3_47UMemorynwEj icu_3_4::UMemory::operator new() -_ZNSt6vectorIbE9push_backE std::vector<>::push_back -_ZNSt6vectorIbSaIbEE9push_backEb std::vector<>::push_back() -_ZlsRSoRK15PRIVATE_Counter operator<<() -_ZSt6fill_nIPPN9__gnu_cxx15_Hashtable_nodeISt4pairIKPKcjEEEjS8_ET_SA_T0_RKT1_ std::fill_n<>() -_ZZ3FoovE3Bar Foo()::Bar -_ZGVZ7UpTimervE8up_timer UpTimer()::up_timer - -# Test cases from gcc-4.1.0/libstdc++-v3/testsuite/demangle. -# Collected by: -# % grep verify_demangle **/*.cc | perl -nle 'print $1 if /"(_Z.*?)"/' | -# sort | uniq -# -# Note that the following symbols are invalid. -# That's why they are not demangled. -# - _ZNZN1N1fEiE1X1gE -# - _ZNZN1N1fEiE1X1gEv -# - _Z1xINiEE -_Z1fA37_iPS_ f() -_Z1fAszL_ZZNK1N1A1fEvE3foo_0E_i f() -_Z1fI1APS0_PKS0_EvT_T0_T1_PA4_S3_M1CS8_ f<>() -_Z1fI1XENT_1tES2_ f<>() -_Z1fI1XEvPVN1AIT_E1TE f<>() -_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE f<>() -_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE f<>() -_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE f<>() -_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE f<>() -_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE f<>() -_Z1fIiEvi f<>() -_Z1fKPFiiE f() -_Z1fM1AFivEPS0_ f() -_Z1fM1AKFivE f() -_Z1fM1AKFvvE f() -_Z1fPFPA1_ivE f() -_Z1fPFYPFiiEiE f() -_Z1fPFvvEM1SFvvE f() -_Z1fPKM1AFivE f() -_Z1fi f() -_Z1fv f() -_Z1jM1AFivEPS1_ j() -_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_ r() -_Z1sPA37_iPS0_ s() -_Z1xINiEE _Z1xINiEE -_Z3absILi11EEvv abs<>() -_Z3foo3bar foo() -_Z3foo5Hello5WorldS0_S_ foo() -_Z3fooA30_A_i foo() -_Z3fooIA6_KiEvA9_KT_rVPrS4_ foo<>() -_Z3fooILi2EEvRAplT_Li1E_i foo<>() -_Z3fooIiFvdEiEvv foo<>() -_Z3fooPM2ABi foo() -_Z3fooc foo() -_Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_ foo() -_Z3kooPA28_A30_i koo() -_Z4makeI7FactoryiET_IT0_Ev make<>() -_Z5firstI3DuoEvS0_ first<>() -_Z5firstI3DuoEvT_ first<>() -_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE hairyfunc() -_ZGVN5libcw24_GLOBAL__N_cbll.cc0ZhUKa23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE libcw::(anonymous namespace)::compiler_bug_workaround<>::ids -_ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_ libcw_app_ct::add_option<>() -_ZN1AIfEcvT_IiEEv A<>::operator ?<>() -_ZN1N1TIiiE2mfES0_IddE N::T<>::mf() -_ZN1N1fE N::f -_ZN1f1fE f::f -_ZN3FooIA4_iE3barE Foo<>::bar -_ZN5Arena5levelE Arena::level -_ZN5StackIiiE5levelE Stack<>::level -_ZN5libcw5debug13cwprint_usingINS_9_private_12GlobalObjectEEENS0_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE libcw::debug::cwprint_using<>() -_ZN6System5Sound4beepEv System::Sound::beep() -_ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv std::priority_queue<>::top() -_ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_ std::_Deque_iterator<>::operator==() -_ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_ std::__normal_iterator<>::operator-() -_ZNSbIcSt11char_traitsIcEN5libcw5debug27no_alloc_checking_allocatorEE12_S_constructIPcEES6_T_S7_RKS3_ std::basic_string<>::_S_construct<>() -_ZNSt13_Alloc_traitsISbIcSt18string_char_traitsIcEN5libcw5debug9_private_17allocator_adaptorIcSt24__default_alloc_templateILb0ELi327664EELb1EEEENS5_IS9_S7_Lb1EEEE15_S_instancelessE std::_Alloc_traits<>::_S_instanceless -_ZNSt3_In4wardE std::_In::ward -_ZNZN1N1fEiE1X1gE _ZNZN1N1fEiE1X1gE -_ZNZN1N1fEiE1X1gEv _ZNZN1N1fEiE1X1gEv -_ZSt1BISt1DIP1ARKS2_PS3_ES0_IS2_RS2_PS2_ES2_ET0_T_SB_SA_PT1_ std::B<>() -_ZSt5state std::state -_ZTI7a_class a_class -_ZZN1N1fEiE1p N::f()::p -_ZZN1N1fEiEs N::f() -_ZlsRK1XS1_ operator<<() -_ZlsRKU3fooU4bart1XS0_ operator<<() -_ZlsRKU3fooU4bart1XS2_ operator<<() -_ZlsRSoRKSs operator<<() -_ZngILi42EEvN1AIXplT_Li2EEE1TE operator-<>() -_ZplR1XS0_ operator+() -_Zrm1XS_ operator%() diff --git a/third_party/src/glog/src/glog/log_severity.h b/third_party/src/glog/src/glog/log_severity.h deleted file mode 100644 index 99945a42..00000000 --- a/third_party/src/glog/src/glog/log_severity.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2007, 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. - -#ifndef BASE_LOG_SEVERITY_H__ -#define BASE_LOG_SEVERITY_H__ - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// Variables of type LogSeverity are widely taken to lie in the range -// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if -// you ever need to change their values or add a new severity. -typedef int LogSeverity; - -const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, - NUM_SEVERITIES = 4; -#ifndef GLOG_NO_ABBREVIATED_SEVERITIES -# ifdef ERROR -# error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail. -# endif -const int INFO = GLOG_INFO, WARNING = GLOG_WARNING, - ERROR = GLOG_ERROR, FATAL = GLOG_FATAL; -#endif - -// DFATAL is FATAL in debug mode, ERROR in normal mode -#ifdef NDEBUG -#define DFATAL_LEVEL ERROR -#else -#define DFATAL_LEVEL FATAL -#endif - -extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; - -// NDEBUG usage helpers related to (RAW_)DCHECK: -// -// DEBUG_MODE is for small !NDEBUG uses like -// if (DEBUG_MODE) foo.CheckThatFoo(); -// instead of substantially more verbose -// #ifndef NDEBUG -// foo.CheckThatFoo(); -// #endif -// -// IF_DEBUG_MODE is for small !NDEBUG uses like -// IF_DEBUG_MODE( string error; ) -// DCHECK(Foo(&error)) << error; -// instead of substantially more verbose -// #ifndef NDEBUG -// string error; -// DCHECK(Foo(&error)) << error; -// #endif -// -#ifdef NDEBUG -enum { DEBUG_MODE = 0 }; -#define IF_DEBUG_MODE(x) -#else -enum { DEBUG_MODE = 1 }; -#define IF_DEBUG_MODE(x) x -#endif - -#endif // BASE_LOG_SEVERITY_H__ diff --git a/third_party/src/glog/src/glog/logging.h b/third_party/src/glog/src/glog/logging.h deleted file mode 100644 index 8a6dca0d..00000000 --- a/third_party/src/glog/src/glog/logging.h +++ /dev/null @@ -1,1619 +0,0 @@ -// Copyright (c) 1999, 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: Ray Sidney -// -// This file contains #include information about logging-related stuff. -// Pretty much everybody needs to #include this file so that they can -// log various happenings. -// -#ifndef _LOGGING_H_ -#define _LOGGING_H_ - -#include "glog/config.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif -#if defined(_MSC_VER) -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ - __pragma(warning(disable:n)) -#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop)) -#else -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) -#define GLOG_MSVC_POP_WARNING() -#endif - -// We care a lot about number of bits things take up. Unfortunately, -// systems define their bit-specific ints in a lot of different ways. -// We use our own way, and have a typedef to get there. -// Note: these commands below may look like "#if 1" or "#if 0", but -// that's because they were constructed that way at ./configure time. -// Look at logging.h.in to see how they're calculated (based on your config). -#ifdef HAVE_STDINT_H -#include // the normal place uint16_t is defined -#endif -#ifdef HAVE_SYS_TYPES_H -#include // the normal place u_int16_t is defined -#endif -#ifdef HAVE_INTTYPES_H -#include // a third place for uint16_t or u_int16_t -#endif - -#if 0 -#include -#endif - -namespace google { - -#if 1 // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif 0 // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif 0 // the windows (vc7) format -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else -#error Do not know how to define a 32-bit integer quantity on your system -#endif - -} - -// The global value of GOOGLE_STRIP_LOG. All the messages logged to -// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. -// If it can be determined at compile time that the message will not be -// printed, the statement will be compiled out. -// -// Example: to strip out all INFO and WARNING messages, use the value -// of 2 below. To make an exception for WARNING messages from a single -// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including -// base/logging.h -#ifndef GOOGLE_STRIP_LOG -#define GOOGLE_STRIP_LOG 0 -#endif - -// GCC can be told that a certain branch is not likely to be taken (for -// instance, a CHECK failure), and use that information in static analysis. -// Giving it this information can help it optimize for the common case in -// the absence of better information (ie. -fprofile-arcs). -// -#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN -#ifdef HAVE___BUILTIN_EXPECT -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x -#define GOOGLE_PREDICT_FALSE(x) x -#define GOOGLE_PREDICT_TRUE(x) x -#endif -#endif - -// Make a bunch of macros for logging. The way to log things is to stream -// things to LOG(). E.g., -// -// LOG(INFO) << "Found " << num_cookies << " cookies"; -// -// You can capture log messages in a string, rather than reporting them -// immediately: -// -// vector errors; -// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; -// -// This pushes back the new error onto 'errors'; if given a NULL pointer, -// it reports the error via LOG(ERROR). -// -// You can also do conditional logging: -// -// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// You can also do occasional logging (log every n'th occurrence of an -// event): -// -// LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// The above will cause log messages to be output on the 1st, 11th, 21st, ... -// times it is executed. Note that the special google::COUNTER value is used -// to identify which repetition is happening. -// -// You can also do occasional conditional logging (log every n'th -// occurrence of an event, when condition is satisfied): -// -// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER -// << "th big cookie"; -// -// You can log messages the first N times your code executes a line. E.g. -// -// LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; -// -// Outputs log messages for the first 20 times it is executed. -// -// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. -// These log to syslog as well as to the normal logs. If you use these at -// all, you need to be aware that syslog can drastically reduce performance, -// especially if it is configured for remote logging! Don't use these -// unless you fully understand this and have a concrete need to use them. -// Even then, try to minimize your use of them. -// -// There are also "debug mode" logging macros like the ones above: -// -// DLOG(INFO) << "Found cookies"; -// -// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// All "debug mode" logging is compiled away to nothing for non-debug mode -// compiles. -// -// We also have -// -// LOG_ASSERT(assertion); -// DLOG_ASSERT(assertion); -// -// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; -// -// There are "verbose level" logging macros. They look like -// -// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; -// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; -// -// These always log at the INFO log level (when they log at all). -// The verbose logging can also be turned on module-by-module. For instance, -// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 -// will cause: -// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} -// b. VLOG(1) and lower messages to be printed from file.{h,cc} -// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" -// d. VLOG(0) and lower messages to be printed from elsewhere -// -// The wildcarding functionality shown by (c) supports both '*' (match -// 0 or more characters) and '?' (match any single character) wildcards. -// -// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as -// -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished with just VLOG(2) << ...; -// } -// -// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" -// condition macros for sample cases, when some extra computation and -// preparation for logs is not needed. -// VLOG_IF(1, (size > 1024)) -// << "I'm printed when size is more than 1024 and when you run the " -// "program with --v=1 or more"; -// VLOG_EVERY_N(1, 10) -// << "I'm printed every 10th occurrence, and when you run the program " -// "with --v=1 or more. Present occurence is " << google::COUNTER; -// VLOG_IF_EVERY_N(1, (size > 1024), 10) -// << "I'm printed on every 10th occurence of case when size is more " -// " than 1024, when you run the program with --v=1 or more. "; -// "Present occurence is " << google::COUNTER; -// -// The supported severity levels for macros that allow you to specify one -// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. -// Note that messages of a given severity are logged not only in the -// logfile for that severity, but also in all logfiles of lower severity. -// E.g., a message of severity FATAL will be logged to the logfiles of -// severity FATAL, ERROR, WARNING, and INFO. -// -// There is also the special severity of DFATAL, which logs FATAL in -// debug mode, ERROR in normal mode. -// -// Very important: logging a message at the FATAL severity level causes -// the program to terminate (after the message is logged). -// -// Unless otherwise specified, logs will be written to the filename -// "...log..", followed -// by the date, time, and pid (you can't prevent the date, time, and pid -// from being in the filename). -// -// The logging code takes two flags: -// --v=# set the verbose level -// --logtostderr log all the messages to stderr instead of to logfiles - -// LOG LINE PREFIX FORMAT -// -// Log lines have this form: -// -// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... -// -// where the fields are defined as follows: -// -// L A single character, representing the log level -// (eg 'I' for INFO) -// mm The month (zero padded; ie May is '05') -// dd The day (zero padded) -// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds -// threadid The space-padded thread ID as returned by GetTID() -// (this matches the PID on Linux) -// file The file name -// line The line number -// msg The user-supplied message -// -// Example: -// -// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog -// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 -// -// NOTE: although the microseconds are useful for comparing events on -// a single machine, clocks on different machines may not be well -// synchronized. Hence, use caution when comparing the low bits of -// timestamps from different machines. - -#ifndef DECLARE_VARIABLE -#define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(google::int32, I, name, int32) - -// Special case for string, because we have to specify the namespace -// std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace fLS { \ - extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#endif - -// Set whether log messages go to stderr instead of logfiles -DECLARE_bool(logtostderr); - -// Set whether log messages go to stderr in addition to logfiles. -DECLARE_bool(alsologtostderr); - -// Set color messages logged to stderr (if supported by terminal). -DECLARE_bool(colorlogtostderr); - -// Log messages at a level >= this flag are automatically sent to -// stderr in addition to log files. -DECLARE_int32(stderrthreshold); - -// Set whether the log prefix should be prepended to each line of output. -DECLARE_bool(log_prefix); - -// Log messages at a level <= this flag are buffered. -// Log messages at a higher level are flushed immediately. -DECLARE_int32(logbuflevel); - -// Sets the maximum number of seconds which logs may be buffered for. -DECLARE_int32(logbufsecs); - -// Log suppression level: messages logged at a lower level than this -// are suppressed. -DECLARE_int32(minloglevel); - -// If specified, logfiles are written into this directory instead of the -// default logging directory. -DECLARE_string(log_dir); - -// Sets the path of the directory into which to put additional links -// to the log files. -DECLARE_string(log_link); - -DECLARE_int32(v); // in vlog_is_on.cc - -// Sets the maximum log file size (in MB). -DECLARE_int32(max_log_size); - -// Sets whether to avoid logging to the disk if the disk is full. -DECLARE_bool(stop_logging_if_full_disk); - -#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef DECLARE_VARIABLE -#undef DECLARE_bool -#undef DECLARE_int32 -#undef DECLARE_string -#endif - -// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for -// security reasons. See LOG(severtiy) below. - -// A few definitions of macros that don't generate much code. Since -// LOG(INFO) and its ilk are used all over our code, it's -// better to have compact code for these operations. - -#if GOOGLE_STRIP_LOG == 0 -#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_INFO(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_INFO, message) -#else -#define COMPACT_GOOGLE_LOG_INFO google::NullStream() -#define LOG_TO_STRING_INFO(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 1 -#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_WARNING) -#define LOG_TO_STRING_WARNING(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_WARNING, message) -#else -#define COMPACT_GOOGLE_LOG_WARNING google::NullStream() -#define LOG_TO_STRING_WARNING(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 2 -#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ERROR) -#define LOG_TO_STRING_ERROR(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ERROR, message) -#else -#define COMPACT_GOOGLE_LOG_ERROR google::NullStream() -#define LOG_TO_STRING_ERROR(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_FATAL(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_FATAL, message) -#else -#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal() -#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal() -#endif - -// For DFATAL, we want to use LogMessage (as opposed to -// LogMessageFatal), to be consistent with the original behavior. -#ifdef NDEBUG -#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR -#elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_FATAL) -#else -#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() -#endif - -#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, &google::LogMessage::SendToLog) -#define SYSLOG_INFO(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToSyslogAndLog) - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) -// A very useful logging macro to log windows errors: -#define LOG_SYSRESULT(result) \ - if (FAILED(HRESULT_FROM_WIN32(result))) { \ - LPSTR message = NULL; \ - LPSTR msg = reinterpret_cast(&message); \ - DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ - FORMAT_MESSAGE_FROM_SYSTEM, \ - 0, result, 0, msg, 100, NULL); \ - if (message_length > 0) { \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \ - &google::LogMessage::SendToLog).stream() \ - << reinterpret_cast(message); \ - LocalFree(message); \ - } \ - } -#endif - -// We use the preprocessor's merging operator, "##", so that, e.g., -// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny -// subtle difference between ostream member streaming functions (e.g., -// ostream::operator<<(int) and ostream non-member streaming functions -// (e.g., ::operator<<(ostream&, string&): it turns out that it's -// impossible to stream something like a string directly to an unnamed -// ostream. We employ a neat hack by calling the stream() member -// function of LogMessage which seems to avoid the problem. -#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() -#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() - -namespace google { - -// They need the definitions of integer types. -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Initialize google's logging library. You will see the program name -// specified by argv0 in log outputs. -GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); - -// Shutdown google's logging library. -GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); - -// Install a function which will be called after LOG(FATAL). -GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); - -class LogSink; // defined below - -// If a non-NULL sink pointer is given, we push this message to that sink. -// For LOG_TO_SINK we then do normal LOG(severity) logging as well. -// This is useful for capturing messages and passing/storing them -// somewhere more specific than the global log of the process. -// Argument types: -// LogSink* sink; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -#define LOG_TO_SINK(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast(sink), true).stream() -#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast(sink), false).stream() - -// If a non-NULL string pointer is given, we write this message to that string. -// We then do normal LOG(severity) logging as well. -// This is useful for capturing messages and storing them somewhere more -// specific than the global log of the process. -// Argument types: -// string* message; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -// NOTE: LOG(severity) expands to LogMessage().stream() for the specified -// severity. -#define LOG_TO_STRING(severity, message) \ - LOG_TO_STRING_##severity(static_cast(message)).stream() - -// If a non-NULL pointer is given, we push the message onto the end -// of a vector of strings; otherwise, we report it with LOG(severity). -// This is handy for capturing messages and perhaps passing them back -// to the caller, rather than reporting them immediately. -// Argument types: -// LogSeverity severity; -// vector *outvec; -// The cast is to disambiguate NULL arguments. -#define LOG_STRING(severity, outvec) \ - LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() - -#define LOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) -#define SYSLOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) - -#define LOG_ASSERT(condition) \ - LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition - -// CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by NDEBUG, so the check will be executed regardless of -// compilation mode. Therefore, it is safe to do things like: -// CHECK(fp->Write(x) == 4) -#define CHECK(condition) \ - LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A container for a string pointer which can be evaluated to a bool - -// true iff the pointer is NULL. -struct CheckOpString { - CheckOpString(std::string* str) : str_(str) { } - // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), - // so there's no point in cleaning up str_. - operator bool() const { - return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); - } - std::string* str_; -}; - -// Function is overloaded for integral types to allow static const -// integrals declared in classes and not defined to be used as arguments to -// CHECK* macros. It's not encouraged though. -template -inline const T& GetReferenceableValue(const T& t) { return t; } -inline char GetReferenceableValue(char t) { return t; } -inline unsigned char GetReferenceableValue(unsigned char t) { return t; } -inline signed char GetReferenceableValue(signed char t) { return t; } -inline short GetReferenceableValue(short t) { return t; } -inline unsigned short GetReferenceableValue(unsigned short t) { return t; } -inline int GetReferenceableValue(int t) { return t; } -inline unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline long GetReferenceableValue(long t) { return t; } -inline unsigned long GetReferenceableValue(unsigned long t) { return t; } -inline long long GetReferenceableValue(long long t) { return t; } -inline unsigned long long GetReferenceableValue(unsigned long long t) { - return t; -} - -// This is a dummy class to define the following operator. -struct DummyClassToDefineOperator {}; - -} - -// Define global operator<< to declare using ::operator<<. -// This declaration will allow use to use CHECK macros for user -// defined classes which have operator<< (e.g., stl_logging.h). -inline std::ostream& operator<<( - std::ostream& out, const google::DummyClassToDefineOperator&) { - return out; -} - -namespace google { - -// This formats a value for a failing CHECK_XX statement. Ordinarily, -// it uses the definition for operator<<, with a few special cases below. -template -inline void MakeCheckOpValueString(std::ostream* os, const T& v) { - (*os) << v; -} - -// Overrides for char types provide readable values for unprintable -// characters. -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const signed char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); - -// Build the error message string. Specify no inlining for code size. -template -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) -#ifdef HAVE___ATTRIBUTE__ - __attribute__((noinline)); -#else - ; -#endif - -namespace base { -namespace internal { - -// If "s" is less than base_logging::INFO, returns base_logging::INFO. -// If "s" is greater than base_logging::FATAL, returns -// base_logging::ERROR. Otherwise, returns "s". -LogSeverity NormalizeSeverity(LogSeverity s); - -} // namespace internal - -// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX -// statement. See MakeCheckOpString for sample usage. Other -// approaches were considered: use of a template method (e.g., -// base::BuildCheckOpString(exprtext, base::Print, &v1, -// base::Print, &v2), however this approach has complications -// related to volatile arguments and function-pointer arguments). -class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { - public: - // Inserts "exprtext" and " (" to the stream. - explicit CheckOpMessageBuilder(const char *exprtext); - // Deletes "stream_". - ~CheckOpMessageBuilder(); - // For inserting the first variable. - std::ostream* ForVar1() { return stream_; } - // For inserting the second variable (adds an intermediate " vs. "). - std::ostream* ForVar2(); - // Get the result (inserts the closing ")"). - std::string* NewString(); - - private: - std::ostringstream *stream_; -}; - -} // namespace base - -template -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { - base::CheckOpMessageBuilder comb(exprtext); - MakeCheckOpValueString(comb.ForVar1(), v1); - MakeCheckOpValueString(comb.ForVar2(), v2); - return comb.NewString(); -} - -// Helper functions for CHECK_OP macro. -// The (int, int) specialization works around the issue that the compiler -// will not instantiate the template version of the function on values of -// unnamed enum type - see comment below. -#define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* name##Impl(const T1& v1, const T2& v2, \ - const char* exprtext) { \ - if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ - else return MakeCheckOpString(v1, v2, exprtext); \ - } \ - inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ - return name##Impl(v1, v2, exprtext); \ - } - -// We use the full name Check_EQ, Check_NE, etc. in case the file including -// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. -// This happens if, for example, those are used as token names in a -// yacc grammar. -DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? -DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. -DEFINE_CHECK_OP_IMPL(Check_LE, <=) -DEFINE_CHECK_OP_IMPL(Check_LT, < ) -DEFINE_CHECK_OP_IMPL(Check_GE, >=) -DEFINE_CHECK_OP_IMPL(Check_GT, > ) -#undef DEFINE_CHECK_OP_IMPL - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. - -#if defined(STATIC_ANALYSIS) -// Only for static analysis tool to know that it is equivalent to assert -#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) -#elif !defined(NDEBUG) -// In debug mode, avoid constructing CheckOpStrings if possible, -// to reduce the overhead of CHECK statments by 2x. -// Real DCHECK-heavy tests have seen 1.5x speedups. - -// The meaning of "string" might be different between now and -// when this macro gets invoked (e.g., if someone is experimenting -// with other string implementations that get defined after this -// file is included). Save the current meaning now and use it -// in the macro. -typedef std::string _Check_string; -#define CHECK_OP_LOG(name, op, val1, val2, log) \ - while (google::_Check_string* _result = \ - google::Check##name##Impl( \ - google::GetReferenceableValue(val1), \ - google::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, \ - google::CheckOpString(_result)).stream() -#else -// In optimized mode, use CheckOpString to hint to compiler that -// the while condition is unlikely. -#define CHECK_OP_LOG(name, op, val1, val2, log) \ - while (google::CheckOpString _result = \ - google::Check##name##Impl( \ - google::GetReferenceableValue(val1), \ - google::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, _result).stream() -#endif // STATIC_ANALYSIS, !NDEBUG - -#if GOOGLE_STRIP_LOG <= 3 -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal) -#else -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal) -#endif // STRIP_LOG <= 3 - -// Equality/Inequality checks - compare two values, and log a FATAL message -// including the two values when the result is not as expected. The values -// must have operator<<(ostream, ...) defined. -// -// You may append to the error message like so: -// CHECK_NE(1, 2) << ": The world must be ending!"; -// -// We are very careful to ensure that each argument is evaluated exactly -// once, and that anything which is legal to pass as a function argument is -// legal here. In particular, the arguments may be temporary expressions -// which will end up being destroyed at the end of the apparent statement, -// for example: -// CHECK_EQ(string("abc")[1], 'b'); -// -// WARNING: These don't compile correctly if one of the arguments is a pointer -// and the other is NULL. To work around this, simply static_cast NULL to the -// type of the desired pointer. - -#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) -#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) -#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) -#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) -#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) -#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) - -// Check that the input is non NULL. This very useful in constructor -// initializer lists. - -#define CHECK_NOTNULL(val) \ - google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) - -// Helper functions for string comparisons. -// To avoid bloat, the definitions are in logging.cc. -#define DECLARE_CHECK_STROP_IMPL(func, expected) \ - GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ - const char* s1, const char* s2, const char* names); -DECLARE_CHECK_STROP_IMPL(strcmp, true) -DECLARE_CHECK_STROP_IMPL(strcmp, false) -DECLARE_CHECK_STROP_IMPL(strcasecmp, true) -DECLARE_CHECK_STROP_IMPL(strcasecmp, false) -#undef DECLARE_CHECK_STROP_IMPL - -// Helper macro for string comparisons. -// Don't use this macro directly in your code, use CHECK_STREQ et al below. -#define CHECK_STROP(func, op, expected, s1, s2) \ - while (google::CheckOpString _result = \ - google::Check##func##expected##Impl((s1), (s2), \ - #s1 " " #op " " #s2)) \ - LOG(FATAL) << *_result.str_ - - -// String (char*) equality/inequality checks. -// CASE versions are case-insensitive. -// -// Note that "s1" and "s2" may be temporary strings which are destroyed -// by the compiler at the end of the current "full expression" -// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). - -#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) -#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) -#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) -#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) - -#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) -#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) - -#define CHECK_DOUBLE_EQ(val1, val2) \ - do { \ - CHECK_LE((val1), (val2)+0.000000000000001L); \ - CHECK_GE((val1), (val2)-0.000000000000001L); \ - } while (0) - -#define CHECK_NEAR(val1, val2, margin) \ - do { \ - CHECK_LE((val1), (val2)+(margin)); \ - CHECK_GE((val1), (val2)-(margin)); \ - } while (0) - -// perror()..googly style! -// -// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and -// CHECK equivalents with the addition that they postpend a description -// of the current state of errno to their output lines. - -#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() - -#define GOOGLE_PLOG(severity, counter) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, counter, \ - &google::LogMessage::SendToLog) - -#define PLOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) - -// A CHECK() macro that postpends errno if the condition is false. E.g. -// -// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } -#define PCHECK(condition) \ - PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A CHECK() macro that lets you assert the success of a function that -// returns -1 and sets errno in case of an error. E.g. -// -// CHECK_ERR(mkdir(path, 0700)); -// -// or -// -// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; -#define CHECK_ERR(invocation) \ -PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ - << #invocation - -// Use macro expansion to create, for each use of LOG_EVERY_N(), static -// variables with the __LINE__ expansion as part of the variable name. -#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) -#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line - -#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) -#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (condition && \ - ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0; \ - if (LOG_OCCURRENCES <= n) \ - ++LOG_OCCURRENCES; \ - if (LOG_OCCURRENCES <= n) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -namespace glog_internal_namespace_ { -template -struct CompileAssert { -}; -struct CrashReason; -} // namespace glog_internal_namespace_ - -#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \ - typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] - -#define LOG_EVERY_N(severity, n) \ - GOOGLE_GLOG_COMPILE_ASSERT(google::GLOG_ ## severity < \ - google::NUM_SEVERITIES, \ - INVALID_REQUESTED_LOG_SEVERITY); \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define SYSLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) - -#define PLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_FIRST_N(severity, n) \ - SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_IF_EVERY_N(severity, condition, n) \ - SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) - -// We want the special COUNTER value available for LOG_EVERY_X()'ed messages -enum PRIVATE_Counter {COUNTER}; - -#ifdef GLOG_NO_ABBREVIATED_SEVERITIES -// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets -// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us -// to keep using this syntax, we define this macro to do the same thing -// as COMPACT_GOOGLE_LOG_ERROR. -#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR -#define SYSLOG_0 SYSLOG_ERROR -#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR -// Needed for LOG_IS_ON(ERROR). -const LogSeverity GLOG_0 = GLOG_ERROR; -#else -// Users may include windows.h after logging.h without -// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN. -// For this case, we cannot detect if ERROR is defined before users -// actually use ERROR. Let's make an undefined symbol to warn users. -# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail -# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG -# define SYSLOG_0 GLOG_ERROR_MSG -# define LOG_TO_STRING_0 GLOG_ERROR_MSG -# define GLOG_0 GLOG_ERROR_MSG -#endif - -// Plus some debug-logging macros that get compiled to nothing for production - -#ifndef NDEBUG - -#define DLOG(severity) LOG(severity) -#define DVLOG(verboselevel) VLOG(verboselevel) -#define DLOG_IF(severity, condition) LOG_IF(severity, condition) -#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) -#define DLOG_IF_EVERY_N(severity, condition, n) \ - LOG_IF_EVERY_N(severity, condition, n) -#define DLOG_ASSERT(condition) LOG_ASSERT(condition) - -// debug-only checking. not executed in NDEBUG mode. -#define DCHECK(condition) CHECK(condition) -#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) -#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) -#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) -#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) -#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) -#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) -#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val) -#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) -#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) -#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) -#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) - -#else // NDEBUG - -#define DLOG(severity) \ - true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DVLOG(verboselevel) \ - (true || !VLOG_IS_ON(verboselevel)) ?\ - (void) 0 : google::LogMessageVoidify() & LOG(INFO) - -#define DLOG_IF(severity, condition) \ - (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_EVERY_N(severity, n) \ - true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_IF_EVERY_N(severity, condition, n) \ - (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_ASSERT(condition) \ - true ? (void) 0 : LOG_ASSERT(condition) - -// MSVC warning C4127: conditional expression is constant -#define DCHECK(condition) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK(condition) - -#define DCHECK_EQ(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2) - -#define DCHECK_NE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2) - -#define DCHECK_LE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2) - -#define DCHECK_LT(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2) - -#define DCHECK_GE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2) - -#define DCHECK_GT(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2) - -// You may see warnings in release mode if you don't use the return -// value of DCHECK_NOTNULL. Please just use DCHECK for such cases. -#define DCHECK_NOTNULL(val) (val) - -#define DCHECK_STREQ(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2) - -#define DCHECK_STRCASEEQ(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2) - -#define DCHECK_STRNE(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2) - -#define DCHECK_STRCASENE(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2) - -#endif // NDEBUG - -// Log only in verbose mode. - -#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) - -#define VLOG_IF(verboselevel, condition) \ - LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) - -#define VLOG_EVERY_N(verboselevel, n) \ - LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) - -#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ - LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) - -namespace base_logging { - -// LogMessage::LogStream is a std::ostream backed by this streambuf. -// This class ignores overflow and leaves two bytes at the end of the -// buffer to allow for a '\n' and '\0'. -class LogStreamBuf : public std::streambuf { - public: - // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'. - LogStreamBuf(char *buf, int len) { - setp(buf, buf + len - 2); - } - // This effectively ignores overflow. - virtual int_type overflow(int_type ch) { - return ch; - } - - // Legacy public ostrstream method. - size_t pcount() const { return pptr() - pbase(); } - char* pbase() const { return std::streambuf::pbase(); } -}; - -} // namespace base_logging - -// -// This class more or less represents a particular log message. You -// create an instance of LogMessage and then stream stuff to it. -// When you finish streaming to it, ~LogMessage is called and the -// full message gets streamed to the appropriate destination. -// -// You shouldn't actually use LogMessage's constructor to log things, -// though. You should use the LOG() macro (and variants thereof) -// above. -class GOOGLE_GLOG_DLL_DECL LogMessage { -public: - enum { - // Passing kNoLogPrefix for the line number disables the - // log-message prefix. Useful for using the LogMessage - // infrastructure as a printing utility. See also the --log_prefix - // flag for controlling the log-message prefix on an - // application-wide basis. - kNoLogPrefix = -1 - }; - - // LogStream inherit from non-DLL-exported class (std::ostrstream) - // and VC++ produces a warning for this situation. - // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ - // 2005 if you are deriving from a type in the Standard C++ Library" - // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx - // Let's just ignore the warning. -#ifdef _MSC_VER -# pragma warning(disable: 4275) -#endif - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { -#ifdef _MSC_VER -# pragma warning(default: 4275) -#endif - public: - LogStream(char *buf, int len, int ctr) - : std::ostream(NULL), - streambuf_(buf, len), - ctr_(ctr), - self_(this) { - rdbuf(&streambuf_); - } - - int ctr() const { return ctr_; } - void set_ctr(int ctr) { ctr_ = ctr; } - LogStream* self() const { return self_; } - - // Legacy std::streambuf methods. - size_t pcount() const { return streambuf_.pcount(); } - char* pbase() const { return streambuf_.pbase(); } - char* str() const { return pbase(); } - - private: - base_logging::LogStreamBuf streambuf_; - int ctr_; // Counter hack (for the LOG_EVERY_X() macro) - LogStream *self_; // Consistency check hack - }; - -public: - // icc 8 requires this typedef to avoid an internal compiler error. - typedef void (LogMessage::*SendMethod)(); - - LogMessage(const char* file, int line, LogSeverity severity, int ctr, - SendMethod send_method); - - // Two special constructors that generate reduced amounts of code at - // LOG call sites for common cases. - - // Used for LOG(INFO): Implied are: - // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. - // - // Using this constructor instead of the more complex constructor above - // saves 19 bytes per call site. - LogMessage(const char* file, int line); - - // Used for LOG(severity) where severity != INFO. Implied - // are: ctr = 0, send_method = &LogMessage::SendToLog - // - // Using this constructor instead of the more complex constructor above - // saves 17 bytes per call site. - LogMessage(const char* file, int line, LogSeverity severity); - - // Constructor to log this message to a specified sink (if not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if - // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. - LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, - bool also_send_to_log); - - // Constructor where we also give a vector pointer - // for storing the messages (if the pointer is not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::vector* outvec); - - // Constructor where we also give a string pointer for storing the - // message (if the pointer is not NULL). Implied are: ctr = 0, - // send_method = &LogMessage::WriteToStringAndLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::string* message); - - // A special constructor used for check failures - LogMessage(const char* file, int line, const CheckOpString& result); - - ~LogMessage(); - - // Flush a buffered message to the sink set in the constructor. Always - // called by the destructor, it may also be called from elsewhere if - // needed. Only the first call is actioned; any later ones are ignored. - void Flush(); - - // An arbitrary limit on the length of a single log message. This - // is so that streaming can be done more efficiently. - static const size_t kMaxLogMessageLen; - - // Theses should not be called directly outside of logging.*, - // only passed as SendMethod arguments to other LogMessage methods: - void SendToLog(); // Actually dispatch to the logs - void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs - - // Call abort() or similar to perform LOG(FATAL) crash. - static void Fail() -#ifdef HAVE___ATTRIBUTE__ - __attribute__((noreturn)); -#else - ; -#endif - - std::ostream& stream(); - - int preserved_errno() const; - - // Must be called without the log_mutex held. (L < log_mutex) - static int64 num_messages(int severity); - - struct LogMessageData; - -private: - // Fully internal SendMethod cases: - void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs - void SendToSink(); // Send to sink if provided, do nothing otherwise. - - // Write to string if provided and dispatch to the logs. - void WriteToStringAndLog(); - - void SaveOrSendToLog(); // Save to stringvec if provided, else to logs - - void Init(const char* file, int line, LogSeverity severity, - void (LogMessage::*send_method)()); - - // Used to fill in crash information during LOG(FATAL) failures. - void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); - - // Counts of messages sent at each priority: - static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex - - // We keep the data in a separate struct so that each instance of - // LogMessage uses less stack space. - LogMessageData* allocated_; - LogMessageData* data_; - - friend class LogDestination; - - LogMessage(const LogMessage&); - void operator=(const LogMessage&); -}; - -// This class happens to be thread-hostile because all instances share -// a single data buffer, but since it can only be created just before -// the process dies, we don't worry so much. -class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { - public: - LogMessageFatal(const char* file, int line); - LogMessageFatal(const char* file, int line, const CheckOpString& result); - ~LogMessageFatal() -#ifdef HAVE___ATTRIBUTE__ - __attribute__((noreturn)); -#else - ; -#endif -}; - -// A non-macro interface to the log facility; (useful -// when the logging level is not a compile-time constant). -inline void LogAtLevel(int const severity, std::string const &msg) { - LogMessage(__FILE__, __LINE__, severity).stream() << msg; -} - -// A macro alternative of LogAtLevel. New code may want to use this -// version since there are two advantages: 1. this version outputs the -// file name and the line number where this macro is put like other -// LOG macros, 2. this macro can be used as C++ stream. -#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream() - -// A small helper for CHECK_NOTNULL(). -template -T* CheckNotNull(const char *file, int line, const char *names, T* t) { - if (t == NULL) { - LogMessageFatal(file, line, new std::string(names)); - } - return t; -} - -// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This -// only works if ostream is a LogStream. If the ostream is not a -// LogStream you'll get an assert saying as much at runtime. -GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, - const PRIVATE_Counter&); - - -// Derived class for PLOG*() above. -class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { - public: - - ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, - void (LogMessage::*send_method)()); - - // Postpends ": strerror(errno) [errno]". - ~ErrnoLogMessage(); - - private: - ErrnoLogMessage(const ErrnoLogMessage&); - void operator=(const ErrnoLogMessage&); -}; - - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-safe. -GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-hostile because it ignores -// locking -- used for catastrophic failures. -GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); - -// -// Set the destination to which a particular severity level of log -// messages is sent. If base_filename is "", it means "don't log this -// severity". Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, - const char* base_filename); - -// -// Set the basename of the symlink to the latest log file at a given -// severity. If symlink_basename is empty, do not make a symlink. If -// you don't call this function, the symlink basename is the -// invocation name of the program. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - -// -// Used to send logs to some other kind of destination -// Users should subclass LogSink and override send to do whatever they want. -// Implementations must be thread-safe because a shared instance will -// be called from whichever thread ran the LOG(XXX) line. -class GOOGLE_GLOG_DLL_DECL LogSink { - public: - virtual ~LogSink(); - - // Sink's logging logic (message_len is such as to exclude '\n' at the end). - // This method can't use LOG() or CHECK() as logging system mutex(s) are held - // during this call. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) = 0; - - // Redefine this to implement waiting for - // the sink's logging logic to complete. - // It will be called after each send() returns, - // but before that LogMessage exits or crashes. - // By default this function does nothing. - // Using this function one can implement complex logic for send() - // that itself involves logging; and do all this w/o causing deadlocks and - // inconsistent rearrangement of log messages. - // E.g. if a LogSink has thread-specific actions, the send() method - // can simply add the message to a queue and wake up another thread that - // handles real logging while itself making some LOG() calls; - // WaitTillSent() can be implemented to wait for that logic to complete. - // See our unittest for an example. - virtual void WaitTillSent(); - - // Returns the normal text output of the log message. - // Can be useful to implement send(). - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len); -}; - -// Add or remove a LogSink as a consumer of logging data. Thread-safe. -GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); -GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); - -// -// Specify an "extension" added to the filename specified via -// SetLogDestination. This applies to all severity levels. It's -// often used to append the port we're listening on to the logfile -// name. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( - const char* filename_extension); - -// -// Make it so that all log messages of at least a particular severity -// are logged to stderr (in addition to logging to the usual log -// file(s)). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); - -// -// Make it so that all log messages go only to stderr. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void LogToStderr(); - -// -// Make it so that all log messages of at least a particular severity are -// logged via email to a list of addresses (in addition to logging to the -// usual log file(s)). The list of addresses is just a string containing -// the email addresses to send to (separated by spaces, say). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, - const char* addresses); - -// A simple function that sends email. dest is a commma-separated -// list of addressess. Thread-safe. -GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, - const char *subject, const char *body); - -GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); - -// For tests only: Clear the internal [cached] list of logging directories to -// force a refresh the next time GetLoggingDirectories is called. -// Thread-hostile. -void TestOnly_ClearLoggingDirectoriesList(); - -// Returns a set of existing temporary directories, which will be a -// subset of the directories returned by GetLogginDirectories(). -// Thread-safe. -GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( - std::vector* list); - -// Print any fatal message again -- useful to call from signal handler -// so that the last thing in the output is the fatal message. -// Thread-hostile, but a race is unlikely. -GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); - -// Truncate a log file that may be the append-only output of multiple -// processes and hence can't simply be renamed/reopened (typically a -// stdout/stderr). If the file "path" is > "limit" bytes, copy the -// last "keep" bytes to offset 0 and truncate the rest. Since we could -// be racing with other writers, this approach has the potential to -// lose very small amounts of data. For security, only follow symlinks -// if the path is /proc/self/fd/* -GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, - int64 limit, int64 keep); - -// Truncate stdout and stderr if they are over the value specified by -// --max_log_size; keep the final 1MB. This function has the same -// race condition as TruncateLogFile. -GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); - -// Return the string representation of the provided LogSeverity level. -// Thread-safe. -GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); - -// --------------------------------------------------------------------- -// Implementation details that are not useful to most clients -// --------------------------------------------------------------------- - -// A Logger is the interface used by logging modules to emit entries -// to a log. A typical implementation will dump formatted data to a -// sequence of files. We also provide interfaces that will forward -// the data to another thread so that the invoker never blocks. -// Implementations should be thread-safe since the logging system -// will write to them from multiple threads. - -namespace base { - -class GOOGLE_GLOG_DLL_DECL Logger { - public: - virtual ~Logger(); - - // Writes "message[0,message_len-1]" corresponding to an event that - // occurred at "timestamp". If "force_flush" is true, the log file - // is flushed immediately. - // - // The input message has already been formatted as deemed - // appropriate by the higher level logging facility. For example, - // textual log messages already contain timestamps, and the - // file:linenumber header. - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) = 0; - - // Flush any buffered messages - virtual void Flush() = 0; - - // Get the current LOG file size. - // The returned value is approximate since some - // logged data may not have been flushed to disk yet. - virtual uint32 LogSize() = 0; -}; - -// Get the logger for the specified severity level. The logger -// remains the property of the logging module and should not be -// deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); - -// Set the logger for the specified severity level. The logger -// becomes the property of the logging module and should not -// be deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); - -} - -// glibc has traditionally implemented two incompatible versions of -// strerror_r(). There is a poorly defined convention for picking the -// version that we want, but it is not clear whether it even works with -// all versions of glibc. -// So, instead, we provide this wrapper that automatically detects the -// version that is in use, and then implements POSIX semantics. -// N.B. In addition to what POSIX says, we also guarantee that "buf" will -// be set to an empty string, if this function failed. This means, in most -// cases, you do not need to check the error code and you can directly -// use the value of "buf". It will never have an undefined value. -GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); - - -// A class for which we define operator<<, which does nothing. -class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { - public: - // Initialize the LogStream so the messages can be written somewhere - // (they'll never be actually displayed). This will be needed if a - // NullStream& is implicitly converted to LogStream&, in which case - // the overloaded NullStream::operator<< will not be invoked. - NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream(const char* /*file*/, int /*line*/, - const CheckOpString& /*result*/) : - LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream &stream() { return *this; } - private: - // A very short buffer for messages (which we discard anyway). This - // will be needed if NullStream& converted to LogStream& (e.g. as a - // result of a conditional expression). - char message_buffer_[2]; -}; - -// Do nothing. This operator is inline, allowing the message to be -// compiled away. The message will not be compiled away if we do -// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when -// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly -// converted to LogStream and the message will be computed and then -// quietly discarded. -template -inline NullStream& operator<<(NullStream &str, const T &) { return str; } - -// Similar to NullStream, but aborts the program (without stack -// trace), like LogMessageFatal. -class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { - public: - NullStreamFatal() { } - NullStreamFatal(const char* file, int line, const CheckOpString& result) : - NullStream(file, line, result) { } -#ifdef HAVE___ATTRIBUTE__ - __attribute__((noreturn)) ~NullStreamFatal() { _exit(1); } -#else - ~NullStreamFatal() { _exit(1); } -#endif -}; - -// Install a signal handler that will dump signal information and a stack -// trace when the program crashes on certain signals. We'll install the -// signal handler for the following signals. -// -// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. -// -// By default, the signal handler will write the failure dump to the -// standard error. You can customize the destination by installing your -// own writer function by InstallFailureWriter() below. -// -// Note on threading: -// -// The function should be called before threads are created, if you want -// to use the failure signal handler for all threads. The stack trace -// will be shown only for the thread that receives the signal. In other -// words, stack traces of other threads won't be shown. -GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); - -// Installs a function that is used for writing the failure dump. "data" -// is the pointer to the beginning of a message to be written, and "size" -// is the size of the message. You should not expect the data is -// terminated with '\0'. -GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( - void (*writer)(const char* data, int size)); - -} - -#endif // _LOGGING_H_ diff --git a/third_party/src/glog/src/glog/raw_logging.h b/third_party/src/glog/src/glog/raw_logging.h deleted file mode 100644 index bbda44fb..00000000 --- a/third_party/src/glog/src/glog/raw_logging.h +++ /dev/null @@ -1,191 +0,0 @@ -// 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: Maxim Lifantsev -// -// Thread-safe logging routines that do not allocate any memory or -// acquire any locks, and can therefore be used by low-level memory -// allocation and synchronization code. - -#ifndef BASE_RAW_LOGGING_H_ -#define BASE_RAW_LOGGING_H_ - -#include "glog/config.h" - -#include - -namespace google { - -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// This is similar to LOG(severity) << format... and VLOG(level) << format.., -// but -// * it is to be used ONLY by low-level modules that can't use normal LOG() -// * it is desiged to be a low-level logger that does not allocate any -// memory and does not need any locks, hence: -// * it logs straight and ONLY to STDERR w/o buffering -// * it uses an explicit format and arguments list -// * it will silently chop off really long message strings -// Usage example: -// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); -// RAW_VLOG(3, "status is %i", status); -// These will print an almost standard log lines like this to stderr only: -// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file -// I0821 211317 file.cc:142] RAW: status is 20 -#define RAW_LOG(severity, ...) \ - do { \ - switch (google::GLOG_ ## severity) { \ - case 0: \ - RAW_LOG_INFO(__VA_ARGS__); \ - break; \ - case 1: \ - RAW_LOG_WARNING(__VA_ARGS__); \ - break; \ - case 2: \ - RAW_LOG_ERROR(__VA_ARGS__); \ - break; \ - case 3: \ - RAW_LOG_FATAL(__VA_ARGS__); \ - break; \ - default: \ - break; \ - } \ - } while (0) - -// The following STRIP_LOG testing is performed in the header file so that it's -// possible to completely compile out the logging code and the log messages. -#if STRIP_LOG == 0 -#define RAW_VLOG(verboselevel, ...) \ - do { \ - if (VLOG_IS_ON(verboselevel)) { \ - RAW_LOG_INFO(__VA_ARGS__); \ - } \ - } while (0) -#else -#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG == 0 -#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG <= 1 -#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 1 - -#if STRIP_LOG <= 2 -#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 2 - -#if STRIP_LOG <= 3 -#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_FATAL(...) \ - do { \ - google::RawLogStub__(0, __VA_ARGS__); \ - exit(1); \ - } while (0) -#endif // STRIP_LOG <= 3 - -// Similar to CHECK(condition) << message, -// but for low-level modules: we use only RAW_LOG that does not allocate memory. -// We do not want to provide args list here to encourage this usage: -// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); -// so that the args are not computed when not needed. -#define RAW_CHECK(condition, message) \ - do { \ - if (!(condition)) { \ - RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ - } \ - } while (0) - -// Debug versions of RAW_LOG and RAW_CHECK -#ifndef NDEBUG - -#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) - -#else // NDEBUG - -#define RAW_DLOG(severity, ...) \ - while (false) \ - RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) \ - while (false) \ - RAW_CHECK(condition, message) - -#endif // NDEBUG - -// Stub log function used to work around for unused variable warnings when -// building with STRIP_LOG > 0. -static inline void RawLogStub__(int /* ignored */, ...) { -} - -// Helper function to implement RAW_LOG and RAW_VLOG -// Logs format... at "severity" level, reporting it -// as called from file:line. -// This does not allocate memory or acquire locks. -GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, - const char* file, - int line, - const char* format, ...) -#ifdef HAVE___ATTRIBUTE__ - __attribute__((__format__ (__printf__, 4, 5))); -#else - ; -#endif - -// Hack to propagate time information into this module so that -// this module does not have to directly call localtime_r(), -// which could allocate memory. -GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs); - -} - -#endif // BASE_RAW_LOGGING_H_ diff --git a/third_party/src/glog/src/glog/stl_logging.h b/third_party/src/glog/src/glog/stl_logging.h deleted file mode 100644 index 14d68ca3..00000000 --- a/third_party/src/glog/src/glog/stl_logging.h +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) 2003, 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. -// -// Stream output operators for STL containers; to be used for logging *only*. -// Inclusion of this file lets you do: -// -// list x; -// LOG(INFO) << "data: " << x; -// vector v1, v2; -// CHECK_EQ(v1, v2); - -#ifndef UTIL_GTL_STL_LOGGING_INL_H_ -#define UTIL_GTL_STL_LOGGING_INL_H_ - -#if !1 -# error We do not support stl_logging for this compiler -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -# include -# include -# include -#endif - -// Forward declare these two, and define them after all the container streams -// operators so that we can recurse from pair -> container -> container -> pair -// properly. -template -std::ostream& operator<<(std::ostream& out, const std::pair& p); - -namespace google { - -template -void PrintSequence(std::ostream& out, Iter begin, Iter end); - -} - -#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_TWO_ARG_CONTAINER(std::vector) -OUTPUT_TWO_ARG_CONTAINER(std::deque) -OUTPUT_TWO_ARG_CONTAINER(std::list) -#ifdef __GNUC__ -OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist) -#endif - -#undef OUTPUT_TWO_ARG_CONTAINER - -#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_THREE_ARG_CONTAINER(std::set) -OUTPUT_THREE_ARG_CONTAINER(std::multiset) - -#undef OUTPUT_THREE_ARG_CONTAINER - -#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_FOUR_ARG_CONTAINER(std::map) -OUTPUT_FOUR_ARG_CONTAINER(std::multimap) -#ifdef __GNUC__ -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set) -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset) -#endif - -#undef OUTPUT_FOUR_ARG_CONTAINER - -#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -#ifdef __GNUC__ -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map) -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap) -#endif - -#undef OUTPUT_FIVE_ARG_CONTAINER - -template -inline std::ostream& operator<<(std::ostream& out, - const std::pair& p) { - out << '(' << p.first << ", " << p.second << ')'; - return out; -} - -namespace google { - -template -inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { - // Output at most 100 elements -- appropriate if used for logging. - for (int i = 0; begin != end && i < 100; ++i, ++begin) { - if (i > 0) out << ' '; - out << *begin; - } - if (begin != end) { - out << " ..."; - } -} - -} - -// Note that this is technically undefined behavior! We are adding things into -// the std namespace for a reason though -- we are providing new operations on -// types which are themselves defined with this namespace. Without this, these -// operator overloads cannot be found via ADL. If these definitions are not -// found via ADL, they must be #included before they're used, which requires -// this header to be included before apparently independent other headers. -// -// For example, base/logging.h defines various template functions to implement -// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails. -// It does so via the function template MakeCheckOpValueString: -// template -// void MakeCheckOpValueString(strstream* ss, const T& v) { -// (*ss) << v; -// } -// Because 'glog/logging.h' is included before 'glog/stl_logging.h', -// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only -// find these operator definitions via ADL. -// -// Even this solution has problems -- it may pull unintended operators into the -// namespace as well, allowing them to also be found via ADL, and creating code -// that only works with a particular order of includes. Long term, we need to -// move all of the *definitions* into namespace std, bet we need to ensure no -// one references them first. This lets us take that step. We cannot define them -// in both because that would create ambiguous overloads when both are found. -namespace std { using ::operator<<; } - -#endif // UTIL_GTL_STL_LOGGING_INL_H_ diff --git a/third_party/src/glog/src/glog/vlog_is_on.h b/third_party/src/glog/src/glog/vlog_is_on.h deleted file mode 100644 index 02b0b867..00000000 --- a/third_party/src/glog/src/glog/vlog_is_on.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 1999, 2007, 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: Ray Sidney and many others -// -// Defines the VLOG_IS_ON macro that controls the variable-verbosity -// conditional logging. -// -// It's used by VLOG and VLOG_IF in logging.h -// and by RAW_VLOG in raw_logging.h to trigger the logging. -// -// It can also be used directly e.g. like this: -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished e.g. via just VLOG(2) << ...; -// } -// -// The truth value that VLOG_IS_ON(level) returns is determined by -// the three verbosity level flags: -// --v= Gives the default maximal active V-logging level; -// 0 is the default. -// Normally positive values are used for V-logging levels. -// --vmodule= Gives the per-module maximal V-logging levels to override -// the value given by --v. -// E.g. "my_module=2,foo*=3" would change the logging level -// for all code in source files "my_module.*" and "foo*.*" -// ("-inl" suffixes are also disregarded for this matching). -// -// SetVLOGLevel helper function is provided to do limited dynamic control over -// V-logging by overriding the per-module settings given via --vmodule flag. -// -// CAVEAT: --vmodule functionality is not available in non gcc compilers. -// - -#ifndef BASE_VLOG_IS_ON_H_ -#define BASE_VLOG_IS_ON_H_ - -#include "glog/log_severity.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -#if defined(__GNUC__) -// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. -// (Normally) the first time every VLOG_IS_ON(n) site is hit, -// we determine what variable will dynamically control logging at this site: -// it's either FLAGS_v or an appropriate internal variable -// matching the current source file that represents results of -// parsing of --vmodule flag and/or SetVLOGLevel calls. -#define VLOG_IS_ON(verboselevel) \ - __extension__ \ - ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ - google::int32 verbose_level__ = (verboselevel); \ - (*vlocal__ >= verbose_level__) && \ - ((vlocal__ != &google::kLogSiteUninitialized) || \ - (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ - __FILE__, verbose_level__))); }) -#else -// GNU extensions not available, so we do not support --vmodule. -// Dynamic value of FLAGS_v always controls the logging level. -#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) -#endif - -// Set VLOG(_IS_ON) level for module_pattern to log_level. -// This lets us dynamically control what is normally set by the --vmodule flag. -// Returns the level that previously applied to module_pattern. -// NOTE: To change the log level for VLOG(_IS_ON) sites -// that have already executed after/during InitGoogleLogging, -// one needs to supply the exact --vmodule pattern that applied to them. -// (If no --vmodule pattern applied to them -// the value of FLAGS_v will continue to control them.) -extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, - int log_level); - -// Various declarations needed for VLOG_IS_ON above: ========================= - -// Special value used to indicate that a VLOG_IS_ON site has not been -// initialized. We make this a large value, so the common-case check -// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition -// passes in such cases and InitVLOG3__ is then triggered. -extern google::int32 kLogSiteUninitialized; - -// Helper routine which determines the logging info for a particalur VLOG site. -// site_flag is the address of the site-local pointer to the controlling -// verbosity level -// site_default is the default to use for *site_flag -// fname is the current source file name -// verbose_level is the argument to VLOG_IS_ON -// We will return the return value for VLOG_IS_ON -// and if possible set *site_flag appropriately. -extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( - google::int32** site_flag, - google::int32* site_default, - const char* fname, - google::int32 verbose_level); - -#endif // BASE_VLOG_IS_ON_H_ diff --git a/third_party/src/glog/src/googletest.h b/third_party/src/glog/src/googletest.h deleted file mode 100644 index b3e26c4d..00000000 --- a/third_party/src/glog/src/googletest.h +++ /dev/null @@ -1,604 +0,0 @@ -// Copyright (c) 2009, 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: Shinichiro Hamaji -// (based on googletest: http://code.google.com/p/googletest/) - -#ifdef GOOGLETEST_H__ -#error You must not include this file twice. -#endif -#define GOOGLETEST_H__ - -#include "utilities.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "base/commandlineflags.h" - -using std::map; -using std::string; -using std::vector; - -_START_GOOGLE_NAMESPACE_ - -extern GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)(); - -_END_GOOGLE_NAMESPACE_ - -#undef GOOGLE_GLOG_DLL_DECL -#define GOOGLE_GLOG_DLL_DECL - -static inline string GetTempDir() { -#ifndef OS_WINDOWS - return "/tmp"; -#else - char tmp[MAX_PATH]; - GetTempPathA(MAX_PATH, tmp); - return tmp; -#endif -} - -#ifdef OS_WINDOWS -// The test will run in glog/vsproject/ -// (e.g., glog/vsproject/logging_unittest). -static const char TEST_SRC_DIR[] = "../.."; -#elif !defined(TEST_SRC_DIR) -# warning TEST_SRC_DIR should be defined in config.h -static const char TEST_SRC_DIR[] = "."; -#endif - -DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files"); -DEFINE_string(test_srcdir, TEST_SRC_DIR, - "Source-dir root, needed to find glog_unittest_flagfile"); -DEFINE_bool(run_benchmark, false, "If true, run benchmarks"); -#ifdef NDEBUG -DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark"); -#else -DEFINE_int32(benchmark_iters, 100000, "Number of iterations per benchmark"); -#endif - -#ifdef HAVE_LIB_GTEST -# include -// Use our ASSERT_DEATH implementation. -# undef ASSERT_DEATH -# undef ASSERT_DEBUG_DEATH -using testing::InitGoogleTest; -#else - -_START_GOOGLE_NAMESPACE_ - -void InitGoogleTest(int*, char**) {} - -// The following is some bare-bones testing infrastructure - -#define EXPECT_TRUE(cond) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "Check failed: %s\n", #cond); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond)) - -#define EXPECT_OP(op, val1, val2) \ - do { \ - if (!((val1) op (val2))) { \ - fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2) -#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2) -#define EXPECT_GT(val1, val2) EXPECT_OP(>, val1, val2) -#define EXPECT_LT(val1, val2) EXPECT_OP(<, val1, val2) - -#define EXPECT_NAN(arg) \ - do { \ - if (!isnan(arg)) { \ - fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_INF(arg) \ - do { \ - if (!isinf(arg)) { \ - fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_DOUBLE_EQ(val1, val2) \ - do { \ - if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) { \ - fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2); \ - exit(1); \ - } \ - } while (0) - -#define EXPECT_STREQ(val1, val2) \ - do { \ - if (strcmp((val1), (val2)) != 0) { \ - fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \ - exit(1); \ - } \ - } while (0) - -vector g_testlist; // the tests to run - -#define TEST(a, b) \ - struct Test_##a##_##b { \ - Test_##a##_##b() { g_testlist.push_back(&Run); } \ - static void Run() { FlagSaver fs; RunTest(); } \ - static void RunTest(); \ - }; \ - static Test_##a##_##b g_test_##a##_##b; \ - void Test_##a##_##b::RunTest() - - -static inline int RUN_ALL_TESTS() { - vector::const_iterator it; - for (it = g_testlist.begin(); it != g_testlist.end(); ++it) { - (*it)(); - } - fprintf(stderr, "Passed %d tests\n\nPASS\n", (int)g_testlist.size()); - return 0; -} - -_END_GOOGLE_NAMESPACE_ - -#endif // ! HAVE_LIB_GTEST - -_START_GOOGLE_NAMESPACE_ - -static bool g_called_abort; -static jmp_buf g_jmp_buf; -static inline void CalledAbort() { - g_called_abort = true; - longjmp(g_jmp_buf, 1); -} - -#ifdef OS_WINDOWS -// TODO(hamaji): Death test somehow doesn't work in Windows. -#define ASSERT_DEATH(fn, msg) -#else -#define ASSERT_DEATH(fn, msg) \ - do { \ - g_called_abort = false; \ - /* in logging.cc */ \ - void (*original_logging_fail_func)() = g_logging_fail_func; \ - g_logging_fail_func = &CalledAbort; \ - if (!setjmp(g_jmp_buf)) fn; \ - /* set back to their default */ \ - g_logging_fail_func = original_logging_fail_func; \ - if (!g_called_abort) { \ - fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \ - exit(1); \ - } \ - } while (0) -#endif - -#ifdef NDEBUG -#define ASSERT_DEBUG_DEATH(fn, msg) -#else -#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg) -#endif // NDEBUG - -// Benchmark tools. - -#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n); - -map g_benchlist; // the benchmarks to run - -class BenchmarkRegisterer { - public: - BenchmarkRegisterer(const char* name, void (*function)(int iters)) { - EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second); - } -}; - -static inline void RunSpecifiedBenchmarks() { - if (!FLAGS_run_benchmark) { - return; - } - - int iter_cnt = FLAGS_benchmark_iters; - puts("Benchmark\tTime(ns)\tIterations"); - for (map::const_iterator iter = g_benchlist.begin(); - iter != g_benchlist.end(); - ++iter) { - clock_t start = clock(); - iter->second(iter_cnt); - double elapsed_ns = - ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000; - printf("%s\t%8.2lf\t%10d\n", - iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt); - } - puts(""); -} - -// ---------------------------------------------------------------------- -// Golden file functions -// ---------------------------------------------------------------------- - -class CapturedStream { - public: - CapturedStream(int fd, const string & filename) : - fd_(fd), - uncaptured_fd_(-1), - filename_(filename) { - Capture(); - } - - ~CapturedStream() { - if (uncaptured_fd_ != -1) { - CHECK(close(uncaptured_fd_) != -1); - } - } - - // Start redirecting output to a file - void Capture() { - // Keep original stream for later - CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!"; - uncaptured_fd_ = dup(fd_); - CHECK(uncaptured_fd_ != -1); - - // Open file to save stream to - int cap_fd = open(filename_.c_str(), - O_CREAT | O_TRUNC | O_WRONLY, - S_IRUSR | S_IWUSR); - CHECK(cap_fd != -1); - - // Send stdout/stderr to this file - fflush(NULL); - CHECK(dup2(cap_fd, fd_) != -1); - CHECK(close(cap_fd) != -1); - } - - // Remove output redirection - void StopCapture() { - // Restore original stream - if (uncaptured_fd_ != -1) { - fflush(NULL); - CHECK(dup2(uncaptured_fd_, fd_) != -1); - } - } - - const string & filename() const { return filename_; } - - private: - int fd_; // file descriptor being captured - int uncaptured_fd_; // where the stream was originally being sent to - string filename_; // file where stream is being saved -}; -static CapturedStream * s_captured_streams[STDERR_FILENO+1]; -// Redirect a file descriptor to a file. -// fd - Should be STDOUT_FILENO or STDERR_FILENO -// filename - File where output should be stored -static inline void CaptureTestOutput(int fd, const string & filename) { - CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO)); - CHECK(s_captured_streams[fd] == NULL); - s_captured_streams[fd] = new CapturedStream(fd, filename); -} -static inline void CaptureTestStderr() { - CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err"); -} -// Return the size (in bytes) of a file -static inline size_t GetFileSize(FILE * file) { - fseek(file, 0, SEEK_END); - return static_cast(ftell(file)); -} -// Read the entire content of a file as a string -static inline string ReadEntireFile(FILE * file) { - const size_t file_size = GetFileSize(file); - char * const buffer = new char[file_size]; - - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far - - fseek(file, 0, SEEK_SET); - - // Keep reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); - - const string content = string(buffer, buffer+bytes_read); - delete[] buffer; - - return content; -} -// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when -// fd is STDERR_FILENO) as a string -static inline string GetCapturedTestOutput(int fd) { - CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO); - CapturedStream * const cap = s_captured_streams[fd]; - CHECK(cap) - << ": did you forget CaptureTestStdout() or CaptureTestStderr()?"; - - // Make sure everything is flushed. - cap->StopCapture(); - - // Read the captured file. - FILE * const file = fopen(cap->filename().c_str(), "r"); - const string content = ReadEntireFile(file); - fclose(file); - - delete cap; - s_captured_streams[fd] = NULL; - - return content; -} -// Get the captured stderr of a test as a string. -static inline string GetCapturedTestStderr() { - return GetCapturedTestOutput(STDERR_FILENO); -} - -// Check if the string is [IWEF](\d{4}|DATE) -static inline bool IsLoggingPrefix(const string& s) { - if (s.size() != 5) return false; - if (!strchr("IWEF", s[0])) return false; - for (int i = 1; i <= 4; ++i) { - if (!isdigit(s[i]) && s[i] != "DATE"[i-1]) return false; - } - return true; -} - -// Convert log output into normalized form. -// -// Example: -// I0102 030405 logging_unittest.cc:345] RAW: vlog -1 -// => IDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1 -static inline string MungeLine(const string& line) { - std::istringstream iss(line); - string before, logcode_date, time, thread_lineinfo; - iss >> logcode_date; - while (!IsLoggingPrefix(logcode_date)) { - before += " " + logcode_date; - if (!(iss >> logcode_date)) { - // We cannot find the header of log output. - return before; - } - } - if (!before.empty()) before += " "; - iss >> time; - iss >> thread_lineinfo; - CHECK(!thread_lineinfo.empty()); - if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') { - // We found thread ID. - string tmp; - iss >> tmp; - CHECK(!tmp.empty()); - CHECK_EQ(']', tmp[tmp.size() - 1]); - thread_lineinfo = "THREADID " + tmp; - } - size_t index = thread_lineinfo.find(':'); - CHECK_NE(string::npos, index); - thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]"; - string rest; - std::getline(iss, rest); - return (before + logcode_date[0] + "DATE TIME__ " + thread_lineinfo + - MungeLine(rest)); -} - -static inline void StringReplace(string* str, - const string& oldsub, - const string& newsub) { - size_t pos = str->find(oldsub); - if (pos != string::npos) { - str->replace(pos, oldsub.size(), newsub.c_str()); - } -} - -static inline string Munge(const string& filename) { - FILE* fp = fopen(filename.c_str(), "rb"); - CHECK(fp != NULL) << filename << ": couldn't open"; - char buf[4096]; - string result; - while (fgets(buf, 4095, fp)) { - string line = MungeLine(buf); - char null_str[256]; - sprintf(null_str, "%p", static_cast(NULL)); - StringReplace(&line, "__NULLP__", null_str); - // Remove 0x prefix produced by %p. VC++ doesn't put the prefix. - StringReplace(&line, " 0x", " "); - - char errmsg_buf[100]; - posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf)); - if (*errmsg_buf == '\0') { - // MacOSX 10.4 and FreeBSD return empty string for errno=0. - // In such case, the we need to remove an extra space. - StringReplace(&line, "__SUCCESS__ ", ""); - } else { - StringReplace(&line, "__SUCCESS__", errmsg_buf); - } - StringReplace(&line, "__ENOENT__", strerror(ENOENT)); - StringReplace(&line, "__EINTR__", strerror(EINTR)); - StringReplace(&line, "__ENXIO__", strerror(ENXIO)); - StringReplace(&line, "__ENOEXEC__", strerror(ENOEXEC)); - result += line + "\n"; - } - fclose(fp); - return result; -} - -static inline void WriteToFile(const string& body, const string& file) { - FILE* fp = fopen(file.c_str(), "wb"); - fwrite(body.data(), 1, body.size(), fp); - fclose(fp); -} - -static inline bool MungeAndDiffTestStderr(const string& golden_filename) { - CapturedStream* cap = s_captured_streams[STDERR_FILENO]; - CHECK(cap) << ": did you forget CaptureTestStderr()?"; - - cap->StopCapture(); - - // Run munge - const string captured = Munge(cap->filename()); - const string golden = Munge(golden_filename); - if (captured != golden) { - fprintf(stderr, - "Test with golden file failed. We'll try to show the diff:\n"); - string munged_golden = golden_filename + ".munged"; - WriteToFile(golden, munged_golden); - string munged_captured = cap->filename() + ".munged"; - WriteToFile(captured, munged_captured); - string diffcmd("diff -u " + munged_golden + " " + munged_captured); - if (system(diffcmd.c_str()) != 0) { - fprintf(stderr, "diff command was failed.\n"); - } - unlink(munged_golden.c_str()); - unlink(munged_captured.c_str()); - return false; - } - LOG(INFO) << "Diff was successful"; - return true; -} - -// Save flags used from logging_unittest.cc. -#ifndef HAVE_LIB_GFLAGS -struct FlagSaver { - FlagSaver() - : v_(FLAGS_v), - stderrthreshold_(FLAGS_stderrthreshold), - logtostderr_(FLAGS_logtostderr), - alsologtostderr_(FLAGS_alsologtostderr) {} - ~FlagSaver() { - FLAGS_v = v_; - FLAGS_stderrthreshold = stderrthreshold_; - FLAGS_logtostderr = logtostderr_; - FLAGS_alsologtostderr = alsologtostderr_; - } - int v_; - int stderrthreshold_; - bool logtostderr_; - bool alsologtostderr_; -}; -#endif - -class Thread { - public: - virtual ~Thread() {} - - void SetJoinable(bool) {} -#if defined(OS_WINDOWS) || defined(OS_CYGWIN) - void Start() { - handle_ = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE)&Thread::InvokeThread, - (LPVOID)this, - 0, - &th_); - CHECK(handle_) << "CreateThread"; - } - void Join() { - WaitForSingleObject(handle_, INFINITE); - } -#elif defined(HAVE_PTHREAD) - void Start() { - pthread_create(&th_, NULL, &Thread::InvokeThread, this); - } - void Join() { - pthread_join(th_, NULL); - } -#else -# error No thread implementation. -#endif - - protected: - virtual void Run() = 0; - - private: - static void* InvokeThread(void* self) { - ((Thread*)self)->Run(); - return NULL; - } - -#if defined(OS_WINDOWS) || defined(OS_CYGWIN) - HANDLE handle_; - DWORD th_; -#else - pthread_t th_; -#endif -}; - -static inline void SleepForMilliseconds(int t) { -#ifndef OS_WINDOWS - usleep(t * 1000); -#else - Sleep(t); -#endif -} - -// Add hook for operator new to ensure there are no memory allocation. - -void (*g_new_hook)() = NULL; - -_END_GOOGLE_NAMESPACE_ - -void* operator new(size_t size) throw(std::bad_alloc) { - if (GOOGLE_NAMESPACE::g_new_hook) { - GOOGLE_NAMESPACE::g_new_hook(); - } - return malloc(size); -} - -void* operator new[](size_t size) throw(std::bad_alloc) { - return ::operator new(size); -} - -void operator delete(void* p) throw() { - free(p); -} - -void operator delete[](void* p) throw() { - ::operator delete(p); -} diff --git a/third_party/src/glog/src/logging.cc b/third_party/src/glog/src/logging.cc deleted file mode 100644 index ec334a90..00000000 --- a/third_party/src/glog/src/logging.cc +++ /dev/null @@ -1,2049 +0,0 @@ -// Copyright (c) 1999, 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. - -#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite() - -#include "utilities.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include // For _exit. -#endif -#include -#include -#include -#ifdef HAVE_SYS_UTSNAME_H -# include // For uname. -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_PWD_H -# include -#endif -#ifdef HAVE_SYSLOG_H -# include -#endif -#include -#include // for errno -#include -#include "base/commandlineflags.h" // to get the program name -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -using std::string; -using std::vector; -using std::setw; -using std::setfill; -using std::hex; -using std::dec; -using std::min; -using std::ostream; -using std::ostringstream; - -using std::FILE; -using std::fwrite; -using std::fclose; -using std::fflush; -using std::fprintf; -using std::perror; - -#ifdef __QNX__ -using std::fdopen; -#endif - -// There is no thread annotation support. -#define EXCLUSIVE_LOCKS_REQUIRED(mu) - -static bool BoolFromEnv(const char *varname, bool defval) { - const char* const valstr = getenv(varname); - if (!valstr) { - return defval; - } - return memchr("tTyY1\0", valstr[0], 6) != NULL; -} - -GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), - "log messages go to stderr instead of logfiles"); -GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), - "log messages go to stderr in addition to logfiles"); -GLOG_DEFINE_bool(colorlogtostderr, false, - "color messages logged to stderr (if supported by terminal)"); -#ifdef OS_LINUX -GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " - "Logs can grow very quickly and they are rarely read before they " - "need to be evicted from memory. Instead, drop them from memory " - "as soon as they are flushed to disk."); -_START_GOOGLE_NAMESPACE_ -namespace logging { -static const int64 kPageSize = getpagesize(); -} -_END_GOOGLE_NAMESPACE_ -#endif - -// By default, errors (including fatal errors) get logged to stderr as -// well as the file. -// -// The default is ERROR instead of FATAL so that users can see problems -// when they run a program without having to look in another file. -DEFINE_int32(stderrthreshold, - GOOGLE_NAMESPACE::GLOG_ERROR, - "log messages at or above this level are copied to stderr in " - "addition to logfiles. This flag obsoletes --alsologtostderr."); - -GLOG_DEFINE_string(alsologtoemail, "", - "log messages go to these email addresses " - "in addition to logfiles"); -GLOG_DEFINE_bool(log_prefix, true, - "Prepend the log prefix to the start of each log line"); -GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " - "actually get logged anywhere"); -GLOG_DEFINE_int32(logbuflevel, 0, - "Buffer log messages logged at this level or lower" - " (-1 means don't buffer; 0 means buffer INFO only;" - " ...)"); -GLOG_DEFINE_int32(logbufsecs, 30, - "Buffer log messages for at most this many seconds"); -GLOG_DEFINE_int32(logemaillevel, 999, - "Email log messages logged at this level or higher" - " (0 means email all; 3 means email FATAL only;" - " ...)"); -GLOG_DEFINE_string(logmailer, "/bin/mail", - "Mailer used to send logging email"); - -// Compute the default value for --log_dir -static const char* DefaultLogDir() { - const char* env; - env = getenv("GOOGLE_LOG_DIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - env = getenv("TEST_TMPDIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - return ""; -} - -GLOG_DEFINE_string(log_dir, DefaultLogDir(), - "If specified, logfiles are written into this directory instead " - "of the default logging directory."); -GLOG_DEFINE_string(log_link, "", "Put additional links to the log " - "files in this directory"); - -GLOG_DEFINE_int32(max_log_size, 1800, - "approx. maximum log file size (in MB). A value of 0 will " - "be silently overridden to 1."); - -GLOG_DEFINE_bool(stop_logging_if_full_disk, false, - "Stop attempting to log to disk if the disk is full."); - -GLOG_DEFINE_string(log_backtrace_at, "", - "Emit a backtrace when logging at file:linenum."); - -// TODO(hamaji): consider windows -#define PATH_SEPARATOR '/' - -static void GetHostName(string* hostname) { -#if defined(HAVE_SYS_UTSNAME_H) - struct utsname buf; - if (0 != uname(&buf)) { - // ensure null termination on failure - *buf.nodename = '\0'; - } - *hostname = buf.nodename; -#elif defined(OS_WINDOWS) - char buf[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD len = MAX_COMPUTERNAME_LENGTH + 1; - if (GetComputerNameA(buf, &len)) { - *hostname = buf; - } else { - hostname->clear(); - } -#else -# warning There is no way to retrieve the host name. - *hostname = "(unknown)"; -#endif -} - -// Returns true iff terminal supports using colors in output. -static bool TerminalSupportsColor() { - bool term_supports_color = false; -#ifdef OS_WINDOWS - // on Windows TERM variable is usually not set, but the console does - // support colors. - term_supports_color = true; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = getenv("TERM"); - if (term != NULL && term[0] != '\0') { - term_supports_color = - !strcmp(term, "xterm") || - !strcmp(term, "xterm-color") || - !strcmp(term, "xterm-256color") || - !strcmp(term, "screen") || - !strcmp(term, "linux") || - !strcmp(term, "cygwin"); - } -#endif - return term_supports_color; -} - -_START_GOOGLE_NAMESPACE_ - -enum GLogColor { - COLOR_DEFAULT, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW -}; - -static GLogColor SeverityToColor(LogSeverity severity) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - GLogColor color = COLOR_DEFAULT; - switch (severity) { - case GLOG_INFO: - color = COLOR_DEFAULT; - break; - case GLOG_WARNING: - color = COLOR_YELLOW; - break; - case GLOG_ERROR: - case GLOG_FATAL: - color = COLOR_RED; - break; - default: - // should never get here. - assert(false); - } - return color; -} - -#ifdef OS_WINDOWS - -// Returns the character attribute for the given color. -WORD GetColorAttribute(GLogColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; - } -} - -#else - -// Returns the ANSI color code for the given color. -const char* GetAnsiColorCode(GLogColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - case COLOR_DEFAULT: return ""; - }; - return NULL; // stop warning about return type. -} - -#endif // OS_WINDOWS - -// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 -static int32 MaxLogSize() { - return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); -} - -struct LogMessage::LogMessageData { - LogMessageData() {}; - - int preserved_errno_; // preserved errno - char* buf_; // buffer space for non FATAL messages - char* message_text_; // Complete message text (points to selected buffer) - LogStream* stream_alloc_; - LogStream* stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - ~LogMessageData(); - - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); -}; - -// A mutex that allows only one thread to log at a time, to keep things from -// getting jumbled. Some other very uncommon logging operations (like -// changing the destination file for log messages of a given severity) also -// lock this mutex. Please be sure that anybody who might possibly need to -// lock it does so. -static Mutex log_mutex; - -// Number of messages sent at each severity. Under log_mutex. -int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; - -// Globally disable log writing (if disk is full) -static bool stop_writing = false; - -const char*const LogSeverityNames[NUM_SEVERITIES] = { - "INFO", "WARNING", "ERROR", "FATAL" -}; - -// Has the user called SetExitOnDFatal(true)? -static bool exit_on_dfatal = true; - -const char* GetLogSeverityName(LogSeverity severity) { - return LogSeverityNames[severity]; -} - -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging); - -base::Logger::~Logger() { -} - -namespace { - -// Encapsulates all file-system related state -class LogFileObject : public base::Logger { - public: - LogFileObject(LogSeverity severity, const char* base_filename); - ~LogFileObject(); - - virtual void Write(bool force_flush, // Should we force a flush here? - time_t timestamp, // Timestamp for this entry - const char* message, - int message_len); - - // Configuration options - void SetBasename(const char* basename); - void SetExtension(const char* ext); - void SetSymlinkBasename(const char* symlink_basename); - - // Normal flushing routine - virtual void Flush(); - - // It is the actual file length for the system loggers, - // i.e., INFO, ERROR, etc. - virtual uint32 LogSize() { - MutexLock l(&lock_); - return file_length_; - } - - // Internal flush routine. Exposed so that FlushLogFilesUnsafe() - // can avoid grabbing a lock. Usually Flush() calls it after - // acquiring lock_. - void FlushUnlocked(); - - private: - static const uint32 kRolloverAttemptFrequency = 0x20; - - Mutex lock_; - bool base_filename_selected_; - string base_filename_; - string symlink_basename_; - string filename_extension_; // option users can specify (eg to add port#) - FILE* file_; - LogSeverity severity_; - uint32 bytes_since_flush_; - uint32 file_length_; - unsigned int rollover_attempt_; - int64 next_flush_time_; // cycle count at which to flush log - - // Actually create a logfile using the value of base_filename_ and the - // supplied argument time_pid_string - // REQUIRES: lock_ is held - bool CreateLogfile(const string& time_pid_string); -}; - -} // namespace - -class LogDestination { - public: - friend class LogMessage; - friend void ReprintFatalMessage(); - friend base::Logger* base::GetLogger(LogSeverity); - friend void base::SetLogger(LogSeverity, base::Logger*); - - // These methods are just forwarded to by their global versions. - static void SetLogDestination(LogSeverity severity, - const char* base_filename); - static void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - static void AddLogSink(LogSink *destination); - static void RemoveLogSink(LogSink *destination); - static void SetLogFilenameExtension(const char* filename_extension); - static void SetStderrLogging(LogSeverity min_severity); - static void SetEmailLogging(LogSeverity min_severity, const char* addresses); - static void LogToStderr(); - // Flush all log files that are at least at the given severity level - static void FlushLogFiles(int min_severity); - static void FlushLogFilesUnsafe(int min_severity); - - // we set the maximum size of our packet to be 1400, the logic being - // to prevent fragmentation. - // Really this number is arbitrary. - static const int kNetworkBytes = 1400; - - static const string& hostname(); - static const bool& terminal_supports_color() { - return terminal_supports_color_; - } - - static void DeleteLogDestinations(); - - private: - LogDestination(LogSeverity severity, const char* base_filename); - ~LogDestination() { } - - // Take a log message of a particular severity and log it to stderr - // iff it's of a high enough severity to deserve it. - static void MaybeLogToStderr(LogSeverity severity, const char* message, - size_t len); - - // Take a log message of a particular severity and log it to email - // iff it's of a high enough severity to deserve it. - static void MaybeLogToEmail(LogSeverity severity, const char* message, - size_t len); - // Take a log message of a particular severity and log it to a file - // iff the base filename is not "" (which means "don't log to me") - static void MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - // Take a log message of a particular severity and log it to the file - // for that severity and also for all files with severity less than - // this severity. - static void LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - - // Send logging info to all registered sinks. - static void LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len); - - // Wait for all registered sinks via WaitTillSent - // including the optional one in "data". - static void WaitForSinks(LogMessage::LogMessageData* data); - - static LogDestination* log_destination(LogSeverity severity); - - LogFileObject fileobject_; - base::Logger* logger_; // Either &fileobject_, or wrapper around it - - static LogDestination* log_destinations_[NUM_SEVERITIES]; - static LogSeverity email_logging_severity_; - static string addresses_; - static string hostname_; - static bool terminal_supports_color_; - - // arbitrary global logging destinations. - static vector* sinks_; - - // Protects the vector sinks_, - // but not the LogSink objects its elements reference. - static Mutex sink_mutex_; - - // Disallow - LogDestination(const LogDestination&); - LogDestination& operator=(const LogDestination&); -}; - -// Errors do not get logged to email by default. -LogSeverity LogDestination::email_logging_severity_ = 99999; - -string LogDestination::addresses_; -string LogDestination::hostname_; - -vector* LogDestination::sinks_ = NULL; -Mutex LogDestination::sink_mutex_; -bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); - -/* static */ -const string& LogDestination::hostname() { - if (hostname_.empty()) { - GetHostName(&hostname_); - if (hostname_.empty()) { - hostname_ = "(unknown)"; - } - } - return hostname_; -} - -LogDestination::LogDestination(LogSeverity severity, - const char* base_filename) - : fileobject_(severity, base_filename), - logger_(&fileobject_) { -} - -inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { - // assume we have the log_mutex or we simply don't care - // about it - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destination(i); - if (log != NULL) { - // Flush the base fileobject_ logger directly instead of going - // through any wrappers to reduce chance of deadlock. - log->fileobject_.FlushUnlocked(); - } - } -} - -inline void LogDestination::FlushLogFiles(int min_severity) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destination(i); - if (log != NULL) { - log->logger_->Flush(); - } - } -} - -inline void LogDestination::SetLogDestination(LogSeverity severity, - const char* base_filename) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetBasename(base_filename); -} - -inline void LogDestination::SetLogSymlink(LogSeverity severity, - const char* symlink_basename) { - CHECK_GE(severity, 0); - CHECK_LT(severity, NUM_SEVERITIES); - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); -} - -inline void LogDestination::AddLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - if (!sinks_) sinks_ = new vector; - sinks_->push_back(destination); -} - -inline void LogDestination::RemoveLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - // This doesn't keep the sinks in order, but who cares? - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - if ((*sinks_)[i] == destination) { - (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; - sinks_->pop_back(); - break; - } - } - } -} - -inline void LogDestination::SetLogFilenameExtension(const char* ext) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { - log_destination(severity)->fileobject_.SetExtension(ext); - } -} - -inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - FLAGS_stderrthreshold = min_severity; -} - -inline void LogDestination::LogToStderr() { - // *Don't* put this stuff in a mutex lock, since SetStderrLogging & - // SetLogDestination already do the locking! - SetStderrLogging(0); // thus everything is "also" logged to stderr - for ( int i = 0; i < NUM_SEVERITIES; ++i ) { - SetLogDestination(i, ""); // "" turns off logging to a logfile - } -} - -inline void LogDestination::SetEmailLogging(LogSeverity min_severity, - const char* addresses) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - LogDestination::email_logging_severity_ = min_severity; - LogDestination::addresses_ = addresses; -} - -static void ColoredWriteToStderr(LogSeverity severity, - const char* message, size_t len) { - const GLogColor color = - (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ? - SeverityToColor(severity) : COLOR_DEFAULT; - - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - if (COLOR_DEFAULT == color) { - fwrite(message, len, 1, stderr); - return; - } -#ifdef OS_WINDOWS - const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stderr_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stderr); - SetConsoleTextAttribute(stderr_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - fwrite(message, len, 1, stderr); - fflush(stderr); - // Restores the text color. - SetConsoleTextAttribute(stderr_handle, old_color_attrs); -#else - fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color)); - fwrite(message, len, 1, stderr); - fprintf(stderr, "\033[m"); // Resets the terminal to default. -#endif // OS_WINDOWS -} - -static void WriteToStderr(const char* message, size_t len) { - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - fwrite(message, len, 1, stderr); -} - -inline void LogDestination::MaybeLogToStderr(LogSeverity severity, - const char* message, size_t len) { - if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { - ColoredWriteToStderr(severity, message, len); -#ifdef OS_WINDOWS - // On Windows, also output to the debugger - ::OutputDebugStringA(string(message,len).c_str()); -#endif - } -} - - -inline void LogDestination::MaybeLogToEmail(LogSeverity severity, - const char* message, size_t len) { - if (severity >= email_logging_severity_ || - severity >= FLAGS_logemaillevel) { - string to(FLAGS_alsologtoemail); - if (!addresses_.empty()) { - if (!to.empty()) { - to += ","; - } - to += addresses_; - } - const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + - glog_internal_namespace_::ProgramInvocationShortName()); - string body(hostname()); - body += "\n\n"; - body.append(message, len); - - // should NOT use SendEmail(). The caller of this function holds the - // log_mutex and SendEmail() calls LOG/VLOG which will block trying to - // acquire the log_mutex object. Use SendEmailInternal() and set - // use_logging to false. - SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); - } -} - - -inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - const bool should_flush = severity > FLAGS_logbuflevel; - LogDestination* destination = log_destination(severity); - destination->logger_->Write(should_flush, timestamp, message, len); -} - -inline void LogDestination::LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - - if ( FLAGS_logtostderr ) { // global flag: never log to file - ColoredWriteToStderr(severity, message, len); - } else { - for (int i = severity; i >= 0; --i) - LogDestination::MaybeLogToLogfile(i, timestamp, message, len); - } -} - -inline void LogDestination::LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->send(severity, full_filename, base_filename, - line, tm_time, message, message_len); - } - } -} - -inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->WaitTillSent(); - } - } - const bool send_to_sink = - (data->send_method_ == &LogMessage::SendToSink) || - (data->send_method_ == &LogMessage::SendToSinkAndLog); - if (send_to_sink && data->sink_ != NULL) { - data->sink_->WaitTillSent(); - } -} - -LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; - -inline LogDestination* LogDestination::log_destination(LogSeverity severity) { - assert(severity >=0 && severity < NUM_SEVERITIES); - if (!log_destinations_[severity]) { - log_destinations_[severity] = new LogDestination(severity, NULL); - } - return log_destinations_[severity]; -} - -void LogDestination::DeleteLogDestinations() { - for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { - delete log_destinations_[severity]; - log_destinations_[severity] = NULL; - } -} - -namespace { - -LogFileObject::LogFileObject(LogSeverity severity, - const char* base_filename) - : base_filename_selected_(base_filename != NULL), - base_filename_((base_filename != NULL) ? base_filename : ""), - symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), - filename_extension_(), - file_(NULL), - severity_(severity), - bytes_since_flush_(0), - file_length_(0), - rollover_attempt_(kRolloverAttemptFrequency-1), - next_flush_time_(0) { - assert(severity >= 0); - assert(severity < NUM_SEVERITIES); -} - -LogFileObject::~LogFileObject() { - MutexLock l(&lock_); - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -void LogFileObject::SetBasename(const char* basename) { - MutexLock l(&lock_); - base_filename_selected_ = true; - if (base_filename_ != basename) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - base_filename_ = basename; - } -} - -void LogFileObject::SetExtension(const char* ext) { - MutexLock l(&lock_); - if (filename_extension_ != ext) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - filename_extension_ = ext; - } -} - -void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { - MutexLock l(&lock_); - symlink_basename_ = symlink_basename; -} - -void LogFileObject::Flush() { - MutexLock l(&lock_); - FlushUnlocked(); -} - -void LogFileObject::FlushUnlocked(){ - if (file_ != NULL) { - fflush(file_); - bytes_since_flush_ = 0; - } - // Figure out when we are due for another flush. - const int64 next = (FLAGS_logbufsecs - * static_cast(1000000)); // in usec - next_flush_time_ = CycleClock_Now() + UsecToCycles(next); -} - -bool LogFileObject::CreateLogfile(const string& time_pid_string) { - string string_filename = base_filename_+filename_extension_+ - time_pid_string; - const char* filename = string_filename.c_str(); - int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664); - if (fd == -1) return false; -#ifdef HAVE_FCNTL - // Mark the file close-on-exec. We don't really care if this fails - fcntl(fd, F_SETFD, FD_CLOEXEC); -#endif - - file_ = fdopen(fd, "a"); // Make a FILE*. - if (file_ == NULL) { // Man, we're screwed! - close(fd); - unlink(filename); // Erase the half-baked evidence: an unusable log file - return false; - } - - // We try to create a symlink called ., - // which is easier to use. (Every time we create a new logfile, - // we destroy the old symlink and create a new one, so it always - // points to the latest logfile.) If it fails, we're sad but it's - // no error. - if (!symlink_basename_.empty()) { - // take directory from filename - const char* slash = strrchr(filename, PATH_SEPARATOR); - const string linkname = - symlink_basename_ + '.' + LogSeverityNames[severity_]; - string linkpath; - if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname - linkpath += linkname; - unlink(linkpath.c_str()); // delete old one if it exists - - // We must have unistd.h. -#ifdef HAVE_UNISTD_H - // Make the symlink be relative (in the same dir) so that if the - // entire log directory gets relocated the link is still valid. - const char *linkdest = slash ? (slash + 1) : filename; - if (symlink(linkdest, linkpath.c_str()) != 0) { - // silently ignore failures - } - - // Make an additional link to the log file in a place specified by - // FLAGS_log_link, if indicated - if (!FLAGS_log_link.empty()) { - linkpath = FLAGS_log_link + "/" + linkname; - unlink(linkpath.c_str()); // delete old one if it exists - if (symlink(filename, linkpath.c_str()) != 0) { - // silently ignore failures - } - } -#endif - } - - return true; // Everything worked -} - -void LogFileObject::Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) { - MutexLock l(&lock_); - - // We don't log if the base_name_ is "" (which means "don't write") - if (base_filename_selected_ && base_filename_.empty()) { - return; - } - - if (static_cast(file_length_ >> 20) >= MaxLogSize() || - PidHasChanged()) { - if (file_ != NULL) fclose(file_); - file_ = NULL; - file_length_ = bytes_since_flush_ = 0; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - - // If there's no destination file, make one before outputting - if (file_ == NULL) { - // Try to rollover the log file every 32 log messages. The only time - // this could matter would be when we have trouble creating the log - // file. If that happens, we'll lose lots of log messages, of course! - if (++rollover_attempt_ != kRolloverAttemptFrequency) return; - rollover_attempt_ = 0; - - struct ::tm tm_time; - localtime_r(×tamp, &tm_time); - - // The logfile's filename will have the date/time & pid in it - ostringstream time_pid_stream; - time_pid_stream.fill('0'); - time_pid_stream << 1900+tm_time.tm_year - << setw(2) << 1+tm_time.tm_mon - << setw(2) << tm_time.tm_mday - << '-' - << setw(2) << tm_time.tm_hour - << setw(2) << tm_time.tm_min - << setw(2) << tm_time.tm_sec - << '.' - << GetMainThreadPid(); - const string& time_pid_string = time_pid_stream.str(); - - if (base_filename_selected_) { - if (!CreateLogfile(time_pid_string)) { - perror("Could not create log file"); - fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", - time_pid_string.c_str()); - return; - } - } else { - // If no base filename for logs of this severity has been set, use a - // default base filename of - // "...log..". So - // logfiles will have names like - // webserver.examplehost.root.log.INFO.19990817-150000.4354, where - // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), - // and 4354 is the pid of the logging process. The date & time reflect - // when the file was created for output. - // - // Where does the file get put? Successively try the directories - // "/tmp", and "." - string stripped_filename( - glog_internal_namespace_::ProgramInvocationShortName()); - string hostname; - GetHostName(&hostname); - - string uidname = MyUserName(); - // We should not call CHECK() here because this function can be - // called after holding on to log_mutex. We don't want to - // attempt to hold on to the same mutex, and get into a - // deadlock. Simply use a name like invalid-user. - if (uidname.empty()) uidname = "invalid-user"; - - stripped_filename = stripped_filename+'.'+hostname+'.' - +uidname+".log." - +LogSeverityNames[severity_]+'.'; - // We're going to (potentially) try to put logs in several different dirs - const vector & log_dirs = GetLoggingDirectories(); - - // Go through the list of dirs, and try to create the log file in each - // until we succeed or run out of options - bool success = false; - for (vector::const_iterator dir = log_dirs.begin(); - dir != log_dirs.end(); - ++dir) { - base_filename_ = *dir + "/" + stripped_filename; - if ( CreateLogfile(time_pid_string) ) { - success = true; - break; - } - } - // If we never succeeded, we have to give up - if ( success == false ) { - perror("Could not create logging file"); - fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", - time_pid_string.c_str()); - return; - } - } - - // Write a header message into the log file - ostringstream file_header_stream; - file_header_stream.fill('0'); - file_header_stream << "Log file created at: " - << 1900+tm_time.tm_year << '/' - << setw(2) << 1+tm_time.tm_mon << '/' - << setw(2) << tm_time.tm_mday - << ' ' - << setw(2) << tm_time.tm_hour << ':' - << setw(2) << tm_time.tm_min << ':' - << setw(2) << tm_time.tm_sec << '\n' - << "Running on machine: " - << LogDestination::hostname() << '\n' - << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " - << "threadid file:line] msg" << '\n'; - const string& file_header_string = file_header_stream.str(); - - const int header_len = file_header_string.size(); - fwrite(file_header_string.data(), 1, header_len, file_); - file_length_ += header_len; - bytes_since_flush_ += header_len; - } - - // Write to LOG file - if ( !stop_writing ) { - // fwrite() doesn't return an error when the disk is full, for - // messages that are less than 4096 bytes. When the disk is full, - // it returns the message length for messages that are less than - // 4096 bytes. fwrite() returns 4096 for message lengths that are - // greater than 4096, thereby indicating an error. - errno = 0; - fwrite(message, 1, message_len, file_); - if ( FLAGS_stop_logging_if_full_disk && - errno == ENOSPC ) { // disk full, stop writing to disk - stop_writing = true; // until the disk is - return; - } else { - file_length_ += message_len; - bytes_since_flush_ += message_len; - } - } else { - if ( CycleClock_Now() >= next_flush_time_ ) - stop_writing = false; // check to see if disk has free space. - return; // no need to flush - } - - // See important msgs *now*. Also, flush logs at least every 10^6 chars, - // or every "FLAGS_logbufsecs" seconds. - if ( force_flush || - (bytes_since_flush_ >= 1000000) || - (CycleClock_Now() >= next_flush_time_) ) { - FlushUnlocked(); -#ifdef OS_LINUX - if (FLAGS_drop_log_memory) { - if (file_length_ >= logging::kPageSize) { - // don't evict the most recent page - uint32 len = file_length_ & ~(logging::kPageSize - 1); - posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED); - } - } -#endif - } -} - -} // namespace - -// An arbitrary limit on the length of a single log message. This -// is so that streaming can be done more efficiently. -const size_t LogMessage::kMaxLogMessageLen = 30000; - -// Static log data space to avoid alloc failures in a LOG(FATAL) -// -// Since multiple threads may call LOG(FATAL), and we want to preserve -// the data from the first call, we allocate two sets of space. One -// for exclusive use by the first thread, and one for shared use by -// all other threads. -static Mutex fatal_msg_lock; -static CrashReason crash_reason; -static bool fatal_msg_exclusive = true; -static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1]; -static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1]; -static LogMessage::LogStream fatal_msg_stream_exclusive( - fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0); -static LogMessage::LogStream fatal_msg_stream_shared( - fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0); -static LogMessage::LogMessageData fatal_msg_data_exclusive; -static LogMessage::LogMessageData fatal_msg_data_shared; - -LogMessage::LogMessageData::~LogMessageData() { - delete[] buf_; - delete stream_alloc_; -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - int ctr, void (LogMessage::*send_method)()) - : allocated_(NULL) { - Init(file, line, severity, send_method); - data_->stream_->set_ctr(ctr); -} - -LogMessage::LogMessage(const char* file, int line, - const CheckOpString& result) - : allocated_(NULL) { - Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); - stream() << "Check failed: " << (*result.str_) << " "; -} - -LogMessage::LogMessage(const char* file, int line) - : allocated_(NULL) { - Init(file, line, GLOG_INFO, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - LogSink* sink, bool also_send_to_log) - : allocated_(NULL) { - Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : - &LogMessage::SendToSink); - data_->sink_ = sink; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - vector *outvec) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SaveOrSendToLog); - data_->outvec_ = outvec; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - string *message) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::WriteToStringAndLog); - data_->message_ = message; // override Init()'s setting to NULL -} - -void LogMessage::Init(const char* file, - int line, - LogSeverity severity, - void (LogMessage::*send_method)()) { - allocated_ = NULL; - if (severity != GLOG_FATAL || !exit_on_dfatal) { - allocated_ = new LogMessageData(); - data_ = allocated_; - data_->buf_ = new char[kMaxLogMessageLen+1]; - data_->message_text_ = data_->buf_; - data_->stream_alloc_ = - new LogStream(data_->message_text_, kMaxLogMessageLen, 0); - data_->stream_ = data_->stream_alloc_; - data_->first_fatal_ = false; - } else { - MutexLock l(&fatal_msg_lock); - if (fatal_msg_exclusive) { - fatal_msg_exclusive = false; - data_ = &fatal_msg_data_exclusive; - data_->message_text_ = fatal_msg_buf_exclusive; - data_->stream_ = &fatal_msg_stream_exclusive; - data_->first_fatal_ = true; - } else { - data_ = &fatal_msg_data_shared; - data_->message_text_ = fatal_msg_buf_shared; - data_->stream_ = &fatal_msg_stream_shared; - data_->first_fatal_ = false; - } - data_->stream_alloc_ = NULL; - } - - stream().fill('0'); - data_->preserved_errno_ = errno; - data_->severity_ = severity; - data_->line_ = line; - data_->send_method_ = send_method; - data_->sink_ = NULL; - data_->outvec_ = NULL; - WallTime now = WallTime_Now(); - data_->timestamp_ = static_cast(now); - localtime_r(&data_->timestamp_, &data_->tm_time_); - int usecs = static_cast((now - data_->timestamp_) * 1000000); - RawLog__SetLastTime(data_->tm_time_, usecs); - - data_->num_chars_to_log_ = 0; - data_->num_chars_to_syslog_ = 0; - data_->basename_ = const_basename(file); - data_->fullname_ = file; - data_->has_been_flushed_ = false; - - // If specified, prepend a prefix to each line. For example: - // I1018 160715 f5d4fbb0 logging.cc:1153] - // (log level, GMT month, date, time, thread_id, file basename, line) - // We exclude the thread_id for the default thread. - if (FLAGS_log_prefix && (line != kNoLogPrefix)) { - stream() << LogSeverityNames[severity][0] - << setw(2) << 1+data_->tm_time_.tm_mon - << setw(2) << data_->tm_time_.tm_mday - << ' ' - << setw(2) << data_->tm_time_.tm_hour << ':' - << setw(2) << data_->tm_time_.tm_min << ':' - << setw(2) << data_->tm_time_.tm_sec << "." - << setw(6) << usecs - << ' ' - << setfill(' ') << setw(5) - << static_cast(GetTID()) << setfill('0') - << ' ' - << data_->basename_ << ':' << data_->line_ << "] "; - } - data_->num_prefix_chars_ = data_->stream_->pcount(); - - if (!FLAGS_log_backtrace_at.empty()) { - char fileline[128]; - snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); -#ifdef HAVE_STACKTRACE - if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { - string stacktrace; - DumpStackTraceToString(&stacktrace); - stream() << " (stacktrace:\n" << stacktrace << ") "; - } -#endif - } -} - -LogMessage::~LogMessage() { - Flush(); - delete allocated_; -} - -int LogMessage::preserved_errno() const { - return data_->preserved_errno_; -} - -ostream& LogMessage::stream() { - return *(data_->stream_); -} - -// Flush buffered message, called by the destructor, or any other function -// that needs to synchronize the log. -void LogMessage::Flush() { - if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) - return; - - data_->num_chars_to_log_ = data_->stream_->pcount(); - data_->num_chars_to_syslog_ = - data_->num_chars_to_log_ - data_->num_prefix_chars_; - - // Do we need to add a \n to the end of this message? - bool append_newline = - (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); - char original_final_char = '\0'; - - // If we do need to add a \n, we'll do it by violating the memory of the - // ostrstream buffer. This is quick, and we'll make sure to undo our - // modification before anything else is done with the ostrstream. It - // would be preferable not to do things this way, but it seems to be - // the best way to deal with this. - if (append_newline) { - original_final_char = data_->message_text_[data_->num_chars_to_log_]; - data_->message_text_[data_->num_chars_to_log_++] = '\n'; - } - - // Prevent any subtle race conditions by wrapping a mutex lock around - // the actual logging action per se. - { - MutexLock l(&log_mutex); - (this->*(data_->send_method_))(); - ++num_messages_[static_cast(data_->severity_)]; - } - LogDestination::WaitForSinks(data_); - - if (append_newline) { - // Fix the ostrstream back how it was before we screwed with it. - // It's 99.44% certain that we don't need to worry about doing this. - data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; - } - - // If errno was already set before we enter the logging call, we'll - // set it back to that value when we return from the logging call. - // It happens often that we log an error message after a syscall - // failure, which can potentially set the errno to some other - // values. We would like to preserve the original errno. - if (data_->preserved_errno_ != 0) { - errno = data_->preserved_errno_; - } - - // Note that this message is now safely logged. If we're asked to flush - // again, as a result of destruction, say, we'll do nothing on future calls. - data_->has_been_flushed_ = true; -} - -// Copy of first FATAL log message so that we can print it out again -// after all the stack traces. To preserve legacy behavior, we don't -// use fatal_msg_buf_exclusive. -static time_t fatal_time; -static char fatal_message[256]; - -void ReprintFatalMessage() { - if (fatal_message[0]) { - const int n = strlen(fatal_message); - if (!FLAGS_logtostderr) { - // Also write to stderr (don't color to avoid terminal checks) - WriteToStderr(fatal_message, n); - } - LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - static bool already_warned_before_initgoogle = false; - - log_mutex.AssertHeld(); - - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - - // Messages of a given severity get logged to lower severity logs, too - - if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { - const char w[] = "WARNING: Logging before InitGoogleLogging() is " - "written to STDERR\n"; - WriteToStderr(w, strlen(w)); - already_warned_before_initgoogle = true; - } - - // global flag: never log to file if set. Also -- don't log to a - // file if we haven't parsed the command line flags to get the - // program name. - if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { - ColoredWriteToStderr(data_->severity_, - data_->message_text_, data_->num_chars_to_log_); - - // this could be protected by a flag if necessary. - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - } else { - - // log this message to all log files of severity <= severity_ - LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, - data_->message_text_, - data_->num_chars_to_log_); - - LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - // NOTE: -1 removes trailing \n - } - - // If we log a FATAL message, flush all the log destinations, then toss - // a signal for others to catch. We leave the logs in a state that - // someone else can use them (as long as they flush afterwards) - if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) { - if (data_->first_fatal_) { - // Store crash information so that it is accessible from within signal - // handlers that may be invoked later. - RecordCrashReason(&crash_reason); - SetCrashReason(&crash_reason); - - // Store shortened fatal message for other logs and GWQ status - const int copy = min(data_->num_chars_to_log_, - sizeof(fatal_message)-1); - memcpy(fatal_message, data_->message_text_, copy); - fatal_message[copy] = '\0'; - fatal_time = data_->timestamp_; - } - - if (!FLAGS_logtostderr) { - for (int i = 0; i < NUM_SEVERITIES; ++i) { - if ( LogDestination::log_destinations_[i] ) - LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); - } - } - - // release the lock that our caller (directly or indirectly) - // LogMessage::~LogMessage() grabbed so that signal handlers - // can use the logging facility. Alternately, we could add - // an entire unsafe logging interface to bypass locking - // for signal handlers but this seems simpler. - log_mutex.Unlock(); - LogDestination::WaitForSinks(data_); - - const char* message = "*** Check failure stack trace: ***\n"; - if (write(STDERR_FILENO, message, strlen(message)) < 0) { - // Ignore errors. - } - Fail(); - } -} - -void LogMessage::RecordCrashReason( - glog_internal_namespace_::CrashReason* reason) { - reason->filename = fatal_msg_data_exclusive.fullname_; - reason->line_number = fatal_msg_data_exclusive.line_; - reason->message = fatal_msg_buf_exclusive + - fatal_msg_data_exclusive.num_prefix_chars_; -#ifdef HAVE_STACKTRACE - // Retrieve the stack trace, omitting the logging frames that got us here. - reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); -#else - reason->depth = 0; -#endif -} - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NORETURN __attribute__((noreturn)) -#else -# define ATTRIBUTE_NORETURN -#endif - -static void logging_fail() ATTRIBUTE_NORETURN; - -static void logging_fail() { -#if defined(_DEBUG) && defined(_MSC_VER) - // When debugging on windows, avoid the obnoxious dialog and make - // it possible to continue past a LOG(FATAL) in the debugger - _asm int 3 -#else - abort(); -#endif -} - -typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN; - -GOOGLE_GLOG_DLL_DECL -logging_fail_func_t g_logging_fail_func = &logging_fail; - -void InstallFailureFunction(void (*fail_func)()) { - g_logging_fail_func = (logging_fail_func_t)fail_func; -} - -void LogMessage::Fail() { - g_logging_fail_func(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->sink_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - SendToSink(); - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->outvec_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when recording in outvec_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->outvec_->push_back(string(start, len)); - } else { - SendToLog(); - } -} - -void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->message_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when writing to message_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->message_->assign(start, len); - } - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSyslogAndLog() { -#ifdef HAVE_SYSLOG_H - // Before any calls to syslog(), make a single call to openlog() - static bool openlog_already_called = false; - if (!openlog_already_called) { - openlog(glog_internal_namespace_::ProgramInvocationShortName(), - LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_USER); - openlog_already_called = true; - } - - // This array maps Google severity levels to syslog levels - const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; - syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast(data_->severity_)], "%.*s", - int(data_->num_chars_to_syslog_), - data_->message_text_ + data_->num_prefix_chars_); - SendToLog(); -#else - LOG(ERROR) << "No syslog support: message=" << data_->message_text_; -#endif -} - -base::Logger* base::GetLogger(LogSeverity severity) { - MutexLock l(&log_mutex); - return LogDestination::log_destination(severity)->logger_; -} - -void base::SetLogger(LogSeverity severity, base::Logger* logger) { - MutexLock l(&log_mutex); - LogDestination::log_destination(severity)->logger_ = logger; -} - -// L < log_mutex. Acquires and releases mutex_. -int64 LogMessage::num_messages(int severity) { - MutexLock l(&log_mutex); - return num_messages_[severity]; -} - -// Output the COUNTER value. This is only valid if ostream is a -// LogStream. -ostream& operator<<(ostream &os, const PRIVATE_Counter&) { -#ifdef DISABLE_RTTI - LogMessage::LogStream *log = static_cast(&os); -#else - LogMessage::LogStream *log = dynamic_cast(&os); -#endif - CHECK(log && log == log->self()) - << "You must not use COUNTER with non-glog ostream"; - os << log->ctr(); - return os; -} - -ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, - LogSeverity severity, int ctr, - void (LogMessage::*send_method)()) - : LogMessage(file, line, severity, ctr, send_method) { -} - -ErrnoLogMessage::~ErrnoLogMessage() { - // Don't access errno directly because it may have been altered - // while streaming the message. - char buf[100]; - posix_strerror_r(preserved_errno(), buf, sizeof(buf)); - stream() << ": " << buf << " [" << preserved_errno() << "]"; -} - -void FlushLogFiles(LogSeverity min_severity) { - LogDestination::FlushLogFiles(min_severity); -} - -void FlushLogFilesUnsafe(LogSeverity min_severity) { - LogDestination::FlushLogFilesUnsafe(min_severity); -} - -void SetLogDestination(LogSeverity severity, const char* base_filename) { - LogDestination::SetLogDestination(severity, base_filename); -} - -void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { - LogDestination::SetLogSymlink(severity, symlink_basename); -} - -LogSink::~LogSink() { -} - -void LogSink::WaitTillSent() { - // noop default -} - -string LogSink::ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - ostringstream stream(string(message, message_len)); - stream.fill('0'); - - // FIXME(jrvb): Updating this to use the correct value for usecs - // requires changing the signature for both this method and - // LogSink::send(). This change needs to be done in a separate CL - // so subclasses of LogSink can be updated at the same time. - int usecs = 0; - - stream << LogSeverityNames[severity][0] - << setw(2) << 1+tm_time->tm_mon - << setw(2) << tm_time->tm_mday - << ' ' - << setw(2) << tm_time->tm_hour << ':' - << setw(2) << tm_time->tm_min << ':' - << setw(2) << tm_time->tm_sec << '.' - << setw(6) << usecs - << ' ' - << setfill(' ') << setw(5) << GetTID() << setfill('0') - << ' ' - << file << ':' << line << "] "; - - stream << string(message, message_len); - return stream.str(); -} - -void AddLogSink(LogSink *destination) { - LogDestination::AddLogSink(destination); -} - -void RemoveLogSink(LogSink *destination) { - LogDestination::RemoveLogSink(destination); -} - -void SetLogFilenameExtension(const char* ext) { - LogDestination::SetLogFilenameExtension(ext); -} - -void SetStderrLogging(LogSeverity min_severity) { - LogDestination::SetStderrLogging(min_severity); -} - -void SetEmailLogging(LogSeverity min_severity, const char* addresses) { - LogDestination::SetEmailLogging(min_severity, addresses); -} - -void LogToStderr() { - LogDestination::LogToStderr(); -} - -namespace base { -namespace internal { - -bool GetExitOnDFatal() { - MutexLock l(&log_mutex); - return exit_on_dfatal; -} - -// Determines whether we exit the program for a LOG(DFATAL) message in -// debug mode. It does this by skipping the call to Fail/FailQuietly. -// This is intended for testing only. -// -// This can have some effects on LOG(FATAL) as well. Failure messages -// are always allocated (rather than sharing a buffer), the crash -// reason is not recorded, the "gwq" status message is not updated, -// and the stack trace is not recorded. The LOG(FATAL) *will* still -// exit the program. Since this function is used only in testing, -// these differences are acceptable. -void SetExitOnDFatal(bool value) { - MutexLock l(&log_mutex); - exit_on_dfatal = value; -} - -} // namespace internal -} // namespace base - -// use_logging controls whether the logging functions LOG/VLOG are used -// to log errors. It should be set to false when the caller holds the -// log_mutex. -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging) { - if (dest && *dest) { - if ( use_logging ) { - VLOG(1) << "Trying to send TITLE:" << subject - << " BODY:" << body << " to " << dest; - } else { - fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", - subject, body, dest); - } - - string cmd = - FLAGS_logmailer + " -s\"" + subject + "\" " + dest; - FILE* pipe = popen(cmd.c_str(), "w"); - if (pipe != NULL) { - // Add the body if we have one - if (body) - fwrite(body, sizeof(char), strlen(body), pipe); - bool ok = pclose(pipe) != -1; - if ( !ok ) { - if ( use_logging ) { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf; - } else { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf); - } - } - return ok; - } else { - if ( use_logging ) { - LOG(ERROR) << "Unable to send mail to " << dest; - } else { - fprintf(stderr, "Unable to send mail to %s\n", dest); - } - } - } - return false; -} - -bool SendEmail(const char*dest, const char *subject, const char*body){ - return SendEmailInternal(dest, subject, body, true); -} - -static void GetTempDirectories(vector* list) { - list->clear(); -#ifdef OS_WINDOWS - // On windows we'll try to find a directory in this order: - // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) - // C:/TMP/ - // C:/TEMP/ - // C:/WINDOWS/ or C:/WINNT/ - // . - char tmp[MAX_PATH]; - if (GetTempPathA(MAX_PATH, tmp)) - list->push_back(tmp); - list->push_back("C:\\tmp\\"); - list->push_back("C:\\temp\\"); -#else - // Directories, in order of preference. If we find a dir that - // exists, we stop adding other less-preferred dirs - const char * candidates[] = { - // Non-null only during unittest/regtest - getenv("TEST_TMPDIR"), - - // Explicitly-supplied temp dirs - getenv("TMPDIR"), getenv("TMP"), - - // If all else fails - "/tmp", - }; - - for (size_t i = 0; i < ARRAYSIZE(candidates); i++) { - const char *d = candidates[i]; - if (!d) continue; // Empty env var - - // Make sure we don't surprise anyone who's expecting a '/' - string dstr = d; - if (dstr[dstr.size() - 1] != '/') { - dstr += "/"; - } - list->push_back(dstr); - - struct stat statbuf; - if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { - // We found a dir that exists - we're done. - return; - } - } - -#endif -} - -static vector* logging_directories_list; - -const vector& GetLoggingDirectories() { - // Not strictly thread-safe but we're called early in InitGoogle(). - if (logging_directories_list == NULL) { - logging_directories_list = new vector; - - if ( !FLAGS_log_dir.empty() ) { - // A dir was specified, we should use it - logging_directories_list->push_back(FLAGS_log_dir.c_str()); - } else { - GetTempDirectories(logging_directories_list); -#ifdef OS_WINDOWS - char tmp[MAX_PATH]; - if (GetWindowsDirectoryA(tmp, MAX_PATH)) - logging_directories_list->push_back(tmp); - logging_directories_list->push_back(".\\"); -#else - logging_directories_list->push_back("./"); -#endif - } - } - return *logging_directories_list; -} - -void TestOnly_ClearLoggingDirectoriesList() { - fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " - "called from test code.\n"); - delete logging_directories_list; - logging_directories_list = NULL; -} - -void GetExistingTempDirectories(vector* list) { - GetTempDirectories(list); - vector::iterator i_dir = list->begin(); - while( i_dir != list->end() ) { - // zero arg to access means test for existence; no constant - // defined on windows - if ( access(i_dir->c_str(), 0) ) { - i_dir = list->erase(i_dir); - } else { - ++i_dir; - } - } -} - -void TruncateLogFile(const char *path, int64 limit, int64 keep) { -#ifdef HAVE_UNISTD_H - struct stat statbuf; - const int kCopyBlockSize = 8 << 10; - char copybuf[kCopyBlockSize]; - int64 read_offset, write_offset; - // Don't follow symlinks unless they're our own fd symlinks in /proc - int flags = O_RDWR; - const char *procfd_prefix = "/proc/self/fd/"; - if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; - - int fd = open(path, flags); - if (fd == -1) { - if (errno == EFBIG) { - // The log file in question has got too big for us to open. The - // real fix for this would be to compile logging.cc (or probably - // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's - // rather scary. - // Instead just truncate the file to something we can manage - if (truncate(path, 0) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } else { - LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; - } - } else { - PLOG(ERROR) << "Unable to open " << path; - } - return; - } - - if (fstat(fd, &statbuf) == -1) { - PLOG(ERROR) << "Unable to fstat()"; - goto out_close_fd; - } - - // See if the path refers to a regular file bigger than the - // specified limit - if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; - if (statbuf.st_size <= limit) goto out_close_fd; - if (statbuf.st_size <= keep) goto out_close_fd; - - // This log file is too large - we need to truncate it - LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; - - // Copy the last "keep" bytes of the file to the beginning of the file - read_offset = statbuf.st_size - keep; - write_offset = 0; - int bytesin, bytesout; - while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { - bytesout = pwrite(fd, copybuf, bytesin, write_offset); - if (bytesout == -1) { - PLOG(ERROR) << "Unable to write to " << path; - break; - } else if (bytesout != bytesin) { - LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; - } - read_offset += bytesin; - write_offset += bytesout; - } - if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; - - // Truncate the remainder of the file. If someone else writes to the - // end of the file after our last read() above, we lose their latest - // data. Too bad ... - if (ftruncate(fd, write_offset) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } - - out_close_fd: - close(fd); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - -void TruncateStdoutStderr() { -#ifdef HAVE_UNISTD_H - int64 limit = MaxLogSize() << 20; - int64 keep = 1 << 20; - TruncateLogFile("/proc/self/fd/1", limit, keep); - TruncateLogFile("/proc/self/fd/2", limit, keep); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - - -// Helper functions for string comparisons. -#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ - string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* names) { \ - bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ - if (equal == expected) return NULL; \ - else { \ - ostringstream ss; \ - if (!s1) s1 = ""; \ - if (!s2) s2 = ""; \ - ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ - return new string(ss.str()); \ - } \ - } -DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) -#undef DEFINE_CHECK_STROP_IMPL - -int posix_strerror_r(int err, char *buf, size_t len) { - // Sanity check input parameters - if (buf == NULL || len <= 0) { - errno = EINVAL; - return -1; - } - - // Reset buf and errno, and try calling whatever version of strerror_r() - // is implemented by glibc - buf[0] = '\000'; - int old_errno = errno; - errno = 0; - char *rc = reinterpret_cast(strerror_r(err, buf, len)); - - // Both versions set errno on failure - if (errno) { - // Should already be there, but better safe than sorry - buf[0] = '\000'; - return -1; - } - errno = old_errno; - - // POSIX is vague about whether the string will be terminated, although - // is indirectly implies that typically ERANGE will be returned, instead - // of truncating the string. This is different from the GNU implementation. - // We play it safe by always terminating the string explicitly. - buf[len-1] = '\000'; - - // If the function succeeded, we can use its exit code to determine the - // semantics implemented by glibc - if (!rc) { - return 0; - } else { - // GNU semantics detected - if (rc == buf) { - return 0; - } else { - buf[0] = '\000'; -#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) - if (reinterpret_cast(rc) < sys_nerr) { - // This means an error on MacOSX or FreeBSD. - return -1; - } -#endif - strncat(buf, rc, len-1); - return 0; - } - } -} - -LogMessageFatal::LogMessageFatal(const char* file, int line) : - LogMessage(file, line, GLOG_FATAL) {} - -LogMessageFatal::LogMessageFatal(const char* file, int line, - const CheckOpString& result) : - LogMessage(file, line, result) {} - -LogMessageFatal::~LogMessageFatal() { - Flush(); - LogMessage::Fail(); -} - -namespace base { - -CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext) - : stream_(new ostringstream) { - *stream_ << exprtext << " ("; -} - -CheckOpMessageBuilder::~CheckOpMessageBuilder() { - delete stream_; -} - -ostream* CheckOpMessageBuilder::ForVar2() { - *stream_ << " vs. "; - return stream_; -} - -string* CheckOpMessageBuilder::NewString() { - *stream_ << ")"; - return new string(stream_->str()); -} - -} // namespace base - -template <> -void MakeCheckOpValueString(std::ostream* os, const char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const signed char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "signed char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "unsigned char value " << (unsigned short)v; - } -} - -void InitGoogleLogging(const char* argv0) { - glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); -} - -void ShutdownGoogleLogging() { - glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); - LogDestination::DeleteLogDestinations(); - delete logging_directories_list; - logging_directories_list = NULL; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/logging_striplog_test.sh b/third_party/src/glog/src/logging_striplog_test.sh deleted file mode 100644 index 73492bda..00000000 --- a/third_party/src/glog/src/logging_striplog_test.sh +++ /dev/null @@ -1,79 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2007, 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: Sergey Ioffe - -get_strings () { - if test -e ".libs/$1"; then - binary=".libs/$1" - elif test -e "$1.exe"; then - binary="$1.exe" - else - echo "We coundn't find $1 binary." - exit 1 - fi - - strings -n 10 $binary | sort | awk '/TESTMESSAGE/ {printf "%s ", $2}' -} - -# Die if "$1" != "$2", print $3 as death reason -check_eq () { - if [ "$1" != "$2" ]; then - echo "Check failed: '$1' == '$2' ${3:+ ($3)}" - exit 1 - fi -} - -die () { - echo $1 - exit 1 -} - -# Check that the string literals are appropriately stripped. This will -# not be the case in debug mode. - -mode=`GLOG_check_mode=1 ./logging_striptest0 2> /dev/null` -if [ "$mode" = "opt" ]; -then - echo "In OPT mode" - check_eq "`get_strings logging_striptest0`" "COND ERROR FATAL INFO USAGE WARNING " - check_eq "`get_strings logging_striptest2`" "COND ERROR FATAL USAGE " - check_eq "`get_strings logging_striptest10`" "" -else - echo "In DBG mode; not checking strings" -fi - -# Check that LOG(FATAL) aborts even for large STRIP_LOG - -./logging_striptest2 2>/dev/null && die "Did not abort for STRIP_LOG=2" -./logging_striptest10 2>/dev/null && die "Did not abort for STRIP_LOG=10" - -echo "PASS" diff --git a/third_party/src/glog/src/logging_striptest10.cc b/third_party/src/glog/src/logging_striptest10.cc deleted file mode 100644 index f6e1078f..00000000 --- a/third_party/src/glog/src/logging_striptest10.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2007, 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: Sergey Ioffe - -#define GOOGLE_STRIP_LOG 10 - -// Include the actual test. -#include "logging_striptest_main.cc" diff --git a/third_party/src/glog/src/logging_striptest2.cc b/third_party/src/glog/src/logging_striptest2.cc deleted file mode 100644 index a64685c9..00000000 --- a/third_party/src/glog/src/logging_striptest2.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2007, 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: Sergey Ioffe - -#define GOOGLE_STRIP_LOG 2 - -// Include the actual test. -#include "logging_striptest_main.cc" diff --git a/third_party/src/glog/src/logging_striptest_main.cc b/third_party/src/glog/src/logging_striptest_main.cc deleted file mode 100644 index 2fb91272..00000000 --- a/third_party/src/glog/src/logging_striptest_main.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2007, 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: Sergey Ioffe - -// The common part of the striplog tests. - -#include -#include -#include -#include "glog/logging.h" -#include "base/commandlineflags.h" -#include "config.h" - -DECLARE_bool(logtostderr); -GLOG_DEFINE_bool(check_mode, false, "Prints 'opt' or 'dbg'"); - -using std::string; -using namespace GOOGLE_NAMESPACE; - -int CheckNoReturn(bool b) { - string s; - if (b) { - LOG(FATAL) << "Fatal"; - } else { - return 0; - } -} - -struct A { }; -std::ostream &operator<<(std::ostream &str, const A&) {return str;} - -int main(int, char* argv[]) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - if (FLAGS_check_mode) { - printf("%s\n", DEBUG_MODE ? "dbg" : "opt"); - return 0; - } - LOG(INFO) << "TESTMESSAGE INFO"; - LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING" - << 1 << 'c' << A() << std::endl; - LOG(ERROR) << "TESTMESSAGE ERROR"; - bool flag = true; - (flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND"; - LOG(FATAL) << "TESTMESSAGE FATAL"; -} diff --git a/third_party/src/glog/src/logging_unittest.cc b/third_party/src/glog/src/logging_unittest.cc deleted file mode 100644 index d7e95cf7..00000000 --- a/third_party/src/glog/src/logging_unittest.cc +++ /dev/null @@ -1,1215 +0,0 @@ -// Copyright (c) 2002, 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: Ray Sidney - -#include "config_for_unittests.h" -#include "utilities.h" - -#include -#ifdef HAVE_GLOB_H -# include -#endif -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "googletest.h" - -DECLARE_string(log_backtrace_at); // logging.cc - -#ifdef HAVE_LIB_GFLAGS -#include -#endif - -#ifdef HAVE_LIB_GMOCK -#include -#include "mock-log.h" -// Introduce several symbols from gmock. -using testing::_; -using testing::AnyNumber; -using testing::HasSubstr; -using testing::AllOf; -using testing::StrNe; -using testing::StrictMock; -using testing::InitGoogleMock; -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -#endif - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -// Some non-advertised functions that we want to test or use. -_START_GOOGLE_NAMESPACE_ -namespace base { -namespace internal { -bool GetExitOnDFatal(); -void SetExitOnDFatal(bool value); -} // namespace internal -} // namespace base -_END_GOOGLE_NAMESPACE_ - -static void TestLogging(bool check_counts); -static void TestRawLogging(); -static void LogWithLevels(int v, int severity, bool err, bool alsoerr); -static void TestLoggingLevels(); -static void TestLogString(); -static void TestLogSink(); -static void TestLogToString(); -static void TestLogSinkWaitTillSent(); -static void TestCHECK(); -static void TestDCHECK(); -static void TestSTREQ(); -static void TestBasename(); -static void TestSymlink(); -static void TestExtension(); -static void TestWrapper(); -static void TestErrno(); -static void TestTruncate(); - -static int x = -1; -static void BM_Check1(int n) { - while (n-- > 0) { - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - CHECK_GE(n, x); - } -} -BENCHMARK(BM_Check1); - -static void CheckFailure(int a, int b, const char* file, int line, const char* msg); -static void BM_Check3(int n) { - while (n-- > 0) { - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x"); - } -} -BENCHMARK(BM_Check3); - -static void BM_Check2(int n) { - if (n == 17) { - x = 5; - } - while (n-- > 0) { - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - CHECK(n >= x); - } -} -BENCHMARK(BM_Check2); - -static void CheckFailure(int, int, const char* /* file */, int /* line */, - const char* /* msg */) { -} - -static void BM_logspeed(int n) { - while (n-- > 0) { - LOG(INFO) << "test message"; - } -} -BENCHMARK(BM_logspeed); - -static void BM_vlog(int n) { - while (n-- > 0) { - VLOG(1) << "test message"; - } -} -BENCHMARK(BM_vlog); - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - // Make sure stderr is not buffered as stderr seems to be buffered - // on recent windows. - setbuf(stderr, NULL); - - // Test some basics before InitGoogleLogging: - CaptureTestStderr(); - LogWithLevels(FLAGS_v, FLAGS_stderrthreshold, - FLAGS_logtostderr, FLAGS_alsologtostderr); - LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors" - const string early_stderr = GetCapturedTestStderr(); - - InitGoogleLogging(argv[0]); - - RunSpecifiedBenchmarks(); - - FLAGS_logtostderr = true; - - InitGoogleTest(&argc, argv); -#ifdef HAVE_LIB_GMOCK - InitGoogleMock(&argc, argv); -#endif - - // so that death tests run before we use threads - CHECK_EQ(RUN_ALL_TESTS(), 0); - - CaptureTestStderr(); - - // re-emit early_stderr - LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr; - - TestLogging(true); - TestRawLogging(); - TestLoggingLevels(); - TestLogString(); - TestLogSink(); - TestLogToString(); - TestLogSinkWaitTillSent(); - TestCHECK(); - TestDCHECK(); - TestSTREQ(); - - // TODO: The golden test portion of this test is very flakey. - EXPECT_TRUE( - MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err")); - - FLAGS_logtostderr = false; - - TestBasename(); - TestSymlink(); - TestExtension(); - TestWrapper(); - TestErrno(); - TestTruncate(); - - ShutdownGoogleLogging(); - - fprintf(stdout, "PASS\n"); - return 0; -} - -void TestLogging(bool check_counts) { - int64 base_num_infos = LogMessage::num_messages(GLOG_INFO); - int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING); - int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR); - - LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4; - for ( int i = 0; i < 10; ++i ) { - int old_errno = errno; - errno = i; - PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER; - errno = old_errno; - - LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl; - LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl; - - LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER; - LOG_IF_EVERY_N(WARNING, false, 3) - << "Log if every 3, iteration " << COUNTER; - LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER; - LOG_IF_EVERY_N(ERROR, (i < 3), 2) - << "Log if less than 3 every 2, iteration " << COUNTER; - } - LOG_IF(WARNING, true) << "log_if this"; - LOG_IF(WARNING, false) << "don't log_if this"; - - char s[] = "array"; - LOG(INFO) << s; - const char const_s[] = "const array"; - LOG(INFO) << const_s; - int j = 1000; - LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " " - << setw(1) << hex << j; - - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix"; - - if (check_counts) { - CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(GLOG_INFO)); - CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING)); - CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(GLOG_ERROR)); - } -} - -static void NoAllocNewHook() { - CHECK(false) << "unexpected new"; -} - -struct NewHook { - NewHook() { - g_new_hook = &NoAllocNewHook; - } - ~NewHook() { - g_new_hook = NULL; - } -}; - -TEST(DeathNoAllocNewHook, logging) { - // tests that NewHook used below works - NewHook new_hook; - ASSERT_DEATH({ - new int; - }, "unexpected new"); -} - -void TestRawLogging() { - string* foo = new string("foo "); - string huge_str(50000, 'a'); - - FlagSaver saver; - - // Check that RAW loggging does not use mallocs. - NewHook new_hook; - - RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4); - char s[] = "array"; - RAW_LOG(WARNING, "%s", s); - const char const_s[] = "const array"; - RAW_LOG(INFO, "%s", const_s); - void* p = reinterpret_cast(0x12345678); - RAW_LOG(INFO, "ptr %p", p); - p = NULL; - RAW_LOG(INFO, "ptr %p", p); - int j = 1000; - RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j); - RAW_VLOG(0, "foo %d", j); - -#ifdef NDEBUG - RAW_LOG(INFO, "foo %d", j); // so that have same stderr to compare -#else - RAW_DLOG(INFO, "foo %d", j); // test RAW_DLOG in debug mode -#endif - - // test how long messages are chopped: - RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str()); - RAW_VLOG(0, "Huge string: %s", huge_str.c_str()); - - FLAGS_v = 0; - RAW_LOG(INFO, "log"); - RAW_VLOG(0, "vlog 0 on"); - RAW_VLOG(1, "vlog 1 off"); - RAW_VLOG(2, "vlog 2 off"); - RAW_VLOG(3, "vlog 3 off"); - FLAGS_v = 2; - RAW_LOG(INFO, "log"); - RAW_VLOG(1, "vlog 1 on"); - RAW_VLOG(2, "vlog 2 on"); - RAW_VLOG(3, "vlog 3 off"); - -#ifdef NDEBUG - RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode"); -#endif - - RAW_CHECK(1 == 1, "should be ok"); - RAW_DCHECK(true, "should be ok"); - - delete foo; -} - -void LogWithLevels(int v, int severity, bool err, bool alsoerr) { - RAW_LOG(INFO, - "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d", - v, severity, err, alsoerr); - - FlagSaver saver; - - FLAGS_v = v; - FLAGS_stderrthreshold = severity; - FLAGS_logtostderr = err; - FLAGS_alsologtostderr = alsoerr; - - RAW_VLOG(-1, "vlog -1"); - RAW_VLOG(0, "vlog 0"); - RAW_VLOG(1, "vlog 1"); - RAW_LOG(INFO, "log info"); - RAW_LOG(WARNING, "log warning"); - RAW_LOG(ERROR, "log error"); - - VLOG(-1) << "vlog -1"; - VLOG(0) << "vlog 0"; - VLOG(1) << "vlog 1"; - LOG(INFO) << "log info"; - LOG(WARNING) << "log warning"; - LOG(ERROR) << "log error"; - - VLOG_IF(-1, true) << "vlog_if -1"; - VLOG_IF(-1, false) << "don't vlog_if -1"; - VLOG_IF(0, true) << "vlog_if 0"; - VLOG_IF(0, false) << "don't vlog_if 0"; - VLOG_IF(1, true) << "vlog_if 1"; - VLOG_IF(1, false) << "don't vlog_if 1"; - LOG_IF(INFO, true) << "log_if info"; - LOG_IF(INFO, false) << "don't log_if info"; - LOG_IF(WARNING, true) << "log_if warning"; - LOG_IF(WARNING, false) << "don't log_if warning"; - LOG_IF(ERROR, true) << "log_if error"; - LOG_IF(ERROR, false) << "don't log_if error"; - - int c; - c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1); - c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1); - c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1); - c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1); - c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0); - c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0); - - c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr"; - EXPECT_EQ(c, -1); - c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr"; - EXPECT_EQ(c, -1); - c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr"; - EXPECT_EQ(c, 0); - c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr"; - EXPECT_EQ(c, 0); - c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr"; - EXPECT_EQ(c, 1); - c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr"; - EXPECT_EQ(c, 1); - c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr"; - EXPECT_EQ(c, 0); - c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr"; - EXPECT_EQ(c, 0); -} - -void TestLoggingLevels() { - LogWithLevels(0, GLOG_INFO, false, false); - LogWithLevels(1, GLOG_INFO, false, false); - LogWithLevels(-1, GLOG_INFO, false, false); - LogWithLevels(0, GLOG_WARNING, false, false); - LogWithLevels(0, GLOG_ERROR, false, false); - LogWithLevels(0, GLOG_FATAL, false, false); - LogWithLevels(0, GLOG_FATAL, true, false); - LogWithLevels(0, GLOG_FATAL, false, true); - LogWithLevels(1, GLOG_WARNING, false, false); - LogWithLevels(1, GLOG_FATAL, false, true); -} - -TEST(DeathRawCHECK, logging) { - ASSERT_DEATH(RAW_CHECK(false, "failure 1"), - "RAW: Check false failed: failure 1"); - ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"), - "RAW: Check 1 == 2 failed: failure 2"); -} - -void TestLogString() { - vector errors; - vector *no_errors = NULL; - - LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info"; - LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning"; - LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error"; - - LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info"; - LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning"; - LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error"; - - for (size_t i = 0; i < errors.size(); ++i) { - LOG(INFO) << "Captured by LOG_STRING: " << errors[i]; - } -} - -void TestLogToString() { - string error; - string* no_error = NULL; - - LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info"; - LOG(INFO) << "Captured by LOG_TO_STRING: " << error; - LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning"; - LOG(INFO) << "Captured by LOG_TO_STRING: " << error; - LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error"; - LOG(INFO) << "Captured by LOG_TO_STRING: " << error; - - LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info"; - LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning"; - LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error"; -} - -class TestLogSinkImpl : public LogSink { - public: - vector errors; - virtual void send(LogSeverity severity, const char* /* full_filename */, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) { - errors.push_back( - ToString(severity, base_filename, line, tm_time, message, message_len)); - } -}; - -void TestLogSink() { - TestLogSinkImpl sink; - LogSink *no_sink = NULL; - - LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info"; - LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning"; - LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error"; - - LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info"; - LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning"; - LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error"; - - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info"; - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning"; - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error"; - - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info"; - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning"; - LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR) - << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error"; - - LOG(INFO) << "Captured by LOG_TO_SINK:"; - for (size_t i = 0; i < sink.errors.size(); ++i) { - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() - << sink.errors[i]; - } -} - -// For testing using CHECK*() on anonymous enums. -enum { - CASE_A, - CASE_B -}; - -void TestCHECK() { - // Tests using CHECK*() on int values. - CHECK(1 == 1); - CHECK_EQ(1, 1); - CHECK_NE(1, 2); - CHECK_GE(1, 1); - CHECK_GE(2, 1); - CHECK_LE(1, 1); - CHECK_LE(1, 2); - CHECK_GT(2, 1); - CHECK_LT(1, 2); - - // Tests using CHECK*() on anonymous enums. - // Apple's GCC doesn't like this. -#if !defined(OS_MACOSX) - CHECK_EQ(CASE_A, CASE_A); - CHECK_NE(CASE_A, CASE_B); - CHECK_GE(CASE_A, CASE_A); - CHECK_GE(CASE_B, CASE_A); - CHECK_LE(CASE_A, CASE_A); - CHECK_LE(CASE_A, CASE_B); - CHECK_GT(CASE_B, CASE_A); - CHECK_LT(CASE_A, CASE_B); -#endif -} - -void TestDCHECK() { -#ifdef NDEBUG - DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode"; -#endif - DCHECK( 1 == 1 ); - DCHECK_EQ(1, 1); - DCHECK_NE(1, 2); - DCHECK_GE(1, 1); - DCHECK_GE(2, 1); - DCHECK_LE(1, 1); - DCHECK_LE(1, 2); - DCHECK_GT(2, 1); - DCHECK_LT(1, 2); - - auto_ptr sptr(new int64); - int64* ptr = DCHECK_NOTNULL(sptr.get()); - CHECK_EQ(ptr, sptr.get()); -} - -void TestSTREQ() { - CHECK_STREQ("this", "this"); - CHECK_STREQ(NULL, NULL); - CHECK_STRCASEEQ("this", "tHiS"); - CHECK_STRCASEEQ(NULL, NULL); - CHECK_STRNE("this", "tHiS"); - CHECK_STRNE("this", NULL); - CHECK_STRCASENE("this", "that"); - CHECK_STRCASENE(NULL, "that"); - CHECK_STREQ((string("a")+"b").c_str(), "ab"); - CHECK_STREQ(string("test").c_str(), - (string("te") + string("st")).c_str()); -} - -TEST(DeathSTREQ, logging) { - ASSERT_DEATH(CHECK_STREQ(NULL, "this"), ""); - ASSERT_DEATH(CHECK_STREQ("this", "siht"), ""); - ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), ""); - ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), ""); - ASSERT_DEATH(CHECK_STRNE(NULL, NULL), ""); - ASSERT_DEATH(CHECK_STRNE("this", "this"), ""); - ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), ""); -} - -TEST(CheckNOTNULL, Simple) { - int64 t; - void *ptr = static_cast(&t); - void *ref = CHECK_NOTNULL(ptr); - EXPECT_EQ(ptr, ref); - CHECK_NOTNULL(reinterpret_cast(ptr)); - CHECK_NOTNULL(reinterpret_cast(ptr)); - CHECK_NOTNULL(reinterpret_cast(ptr)); - CHECK_NOTNULL(reinterpret_cast(ptr)); -} - -TEST(DeathCheckNN, Simple) { - ASSERT_DEATH(CHECK_NOTNULL(static_cast(NULL)), ""); -} - -// Get list of file names that match pattern -static void GetFiles(const string& pattern, vector* files) { - files->clear(); -#if defined(HAVE_GLOB_H) - glob_t g; - const int r = glob(pattern.c_str(), 0, NULL, &g); - CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern; - for (size_t i = 0; i < g.gl_pathc; i++) { - files->push_back(string(g.gl_pathv[i])); - } - globfree(&g); -#elif defined(OS_WINDOWS) - WIN32_FIND_DATAA data; - HANDLE handle = FindFirstFileA(pattern.c_str(), &data); - size_t index = pattern.rfind('\\'); - if (index == string::npos) { - LOG(FATAL) << "No directory separator."; - } - const string dirname = pattern.substr(0, index + 1); - if (FAILED(handle)) { - // Finding no files is OK. - return; - } - do { - files->push_back(dirname + data.cFileName); - } while (FindNextFileA(handle, &data)); - LOG_SYSRESULT(FindClose(handle)); -#else -# error There is no way to do glob. -#endif -} - -// Delete files patching pattern -static void DeleteFiles(const string& pattern) { - vector files; - GetFiles(pattern, &files); - for (size_t i = 0; i < files.size(); i++) { - CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno); - } -} - -static void CheckFile(const string& name, const string& expected_string) { - vector files; - GetFiles(name + "*", &files); - CHECK_EQ(files.size(), 1UL); - - FILE* file = fopen(files[0].c_str(), "r"); - CHECK(file != NULL) << ": could not open " << files[0]; - char buf[1000]; - while (fgets(buf, sizeof(buf), file) != NULL) { - if (strstr(buf, expected_string.c_str()) != NULL) { - fclose(file); - return; - } - } - fclose(file); - LOG(FATAL) << "Did not find " << expected_string << " in " << files[0]; -} - -static void TestBasename() { - fprintf(stderr, "==== Test setting log file basename\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename"; - DeleteFiles(dest + "*"); - - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base"; - FlushLogFiles(GLOG_INFO); - - CheckFile(dest, "message to new base"); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -static void TestSymlink() { -#ifndef OS_WINDOWS - fprintf(stderr, "==== Test setting log file symlink\n"); - string dest = FLAGS_test_tmpdir + "/logging_test_symlink"; - string sym = FLAGS_test_tmpdir + "/symlinkbase"; - DeleteFiles(dest + "*"); - DeleteFiles(sym + "*"); - - SetLogSymlink(GLOG_INFO, "symlinkbase"); - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new symlink"; - FlushLogFiles(GLOG_INFO); - CheckFile(sym, "message to new symlink"); - - DeleteFiles(dest + "*"); - DeleteFiles(sym + "*"); -#endif -} - -static void TestExtension() { - fprintf(stderr, "==== Test setting log file extension\n"); - string dest = FLAGS_test_tmpdir + "/logging_test_extension"; - DeleteFiles(dest + "*"); - - SetLogDestination(GLOG_INFO, dest.c_str()); - SetLogFilenameExtension("specialextension"); - LOG(INFO) << "message to new extension"; - FlushLogFiles(GLOG_INFO); - CheckFile(dest, "message to new extension"); - - // Check that file name ends with extension - vector filenames; - GetFiles(dest + "*", &filenames); - CHECK_EQ(filenames.size(), 1UL); - CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -struct MyLogger : public base::Logger { - string data; - - virtual void Write(bool /* should_flush */, - time_t /* timestamp */, - const char* message, - int length) { - data.append(message, length); - } - - virtual void Flush() { } - - virtual uint32 LogSize() { return data.length(); } -}; - -static void TestWrapper() { - fprintf(stderr, "==== Test log wrapper\n"); - - MyLogger my_logger; - base::Logger* old_logger = base::GetLogger(GLOG_INFO); - base::SetLogger(GLOG_INFO, &my_logger); - LOG(INFO) << "Send to wrapped logger"; - FlushLogFiles(GLOG_INFO); - base::SetLogger(GLOG_INFO, old_logger); - - CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL); -} - -static void TestErrno() { - fprintf(stderr, "==== Test errno preservation\n"); - - errno = ENOENT; - TestLogging(false); - CHECK_EQ(errno, ENOENT); -} - -static void TestOneTruncate(const char *path, int64 limit, int64 keep, - int64 dsize, int64 ksize, int64 expect) { - int fd; - CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)); - - const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!"; - - // Fill the file with the requested data; first discard data, then kept data - int64 written = 0; - while (written < dsize) { - int bytes = min(dsize - written, strlen(discardstr)); - CHECK_ERR(write(fd, discardstr, bytes)); - written += bytes; - } - written = 0; - while (written < ksize) { - int bytes = min(ksize - written, strlen(keepstr)); - CHECK_ERR(write(fd, keepstr, bytes)); - written += bytes; - } - - TruncateLogFile(path, limit, keep); - - // File should now be shorter - struct stat statbuf; - CHECK_ERR(fstat(fd, &statbuf)); - CHECK_EQ(statbuf.st_size, expect); - CHECK_ERR(lseek(fd, 0, SEEK_SET)); - - // File should contain the suffix of the original file - const size_t buf_size = statbuf.st_size + 1; - char* buf = new char[buf_size]; - memset(buf, 0, buf_size); - CHECK_ERR(read(fd, buf, buf_size)); - - const char *p = buf; - int64 checked = 0; - while (checked < expect) { - int bytes = min(expect - checked, strlen(keepstr)); - CHECK(!memcmp(p, keepstr, bytes)); - checked += bytes; - } - close(fd); - delete[] buf; -} - -static void TestTruncate() { -#ifdef HAVE_UNISTD_H - fprintf(stderr, "==== Test log truncation\n"); - string path = FLAGS_test_tmpdir + "/truncatefile"; - - // Test on a small file - TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10); - - // And a big file (multiple blocks to copy) - TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10); - - // Check edge-case limits - TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20); - TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0); - TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10); - TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30); - - // MacOSX 10.4 doesn't fail in this case. - // Windows doesn't have symlink. - // Let's just ignore this test for these cases. -#if !defined(OS_MACOSX) && !defined(OS_WINDOWS) - // Through a symlink should fail to truncate - string linkname = path + ".link"; - unlink(linkname.c_str()); - CHECK_ERR(symlink(path.c_str(), linkname.c_str())); - TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30); -#endif - - // The /proc/self path makes sense only for linux. -#if defined(OS_LINUX) - // Through an open fd symlink should work - int fd; - CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY)); - char fdpath[64]; - snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd); - TestOneTruncate(fdpath, 10, 10, 10, 10, 10); -#endif - -#endif -} - -_START_GOOGLE_NAMESPACE_ -namespace glog_internal_namespace_ { -extern // in logging.cc -bool SafeFNMatch_(const char* pattern, size_t patt_len, - const char* str, size_t str_len); -} // namespace glog_internal_namespace_ -using glog_internal_namespace_::SafeFNMatch_; -_END_GOOGLE_NAMESPACE_ - -static bool WrapSafeFNMatch(string pattern, string str) { - pattern += "abc"; - str += "defgh"; - return SafeFNMatch_(pattern.data(), pattern.size() - 3, - str.data(), str.size() - 5); -} - -TEST(SafeFNMatch, logging) { - CHECK(WrapSafeFNMatch("foo", "foo")); - CHECK(!WrapSafeFNMatch("foo", "bar")); - CHECK(!WrapSafeFNMatch("foo", "fo")); - CHECK(!WrapSafeFNMatch("foo", "foo2")); - CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext")); - CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo")); - CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip")); - CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext")); - CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext")); - CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext")); - CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2")); - CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2")); - CHECK(WrapSafeFNMatch("ba?/*", "bar/")); - CHECK(!WrapSafeFNMatch("ba?/?", "bar/")); - CHECK(!WrapSafeFNMatch("ba?/*", "bar")); -} - -// TestWaitingLogSink will save messages here -// No lock: Accessed only by TestLogSinkWriter thread -// and after its demise by its creator. -static vector global_messages; - -// helper for TestWaitingLogSink below. -// Thread that does the logic of TestWaitingLogSink -// It's free to use LOG() itself. -class TestLogSinkWriter : public Thread { - public: - - TestLogSinkWriter() : should_exit_(false) { - SetJoinable(true); - Start(); - } - - // Just buffer it (can't use LOG() here). - void Buffer(const string& message) { - mutex_.Lock(); - RAW_LOG(INFO, "Buffering"); - messages_.push(message); - mutex_.Unlock(); - RAW_LOG(INFO, "Buffered"); - } - - // Wait for the buffer to clear (can't use LOG() here). - void Wait() { - RAW_LOG(INFO, "Waiting"); - mutex_.Lock(); - while (!NoWork()) { - mutex_.Unlock(); - SleepForMilliseconds(1); - mutex_.Lock(); - } - RAW_LOG(INFO, "Waited"); - mutex_.Unlock(); - } - - // Trigger thread exit. - void Stop() { - MutexLock l(&mutex_); - should_exit_ = true; - } - - private: - - // helpers --------------- - - // For creating a "Condition". - bool NoWork() { return messages_.empty(); } - bool HaveWork() { return !messages_.empty() || should_exit_; } - - // Thread body; CAN use LOG() here! - virtual void Run() { - while (1) { - mutex_.Lock(); - while (!HaveWork()) { - mutex_.Unlock(); - SleepForMilliseconds(1); - mutex_.Lock(); - } - if (should_exit_ && messages_.empty()) { - mutex_.Unlock(); - break; - } - // Give the main thread time to log its message, - // so that we get a reliable log capture to compare to golden file. - // Same for the other sleep below. - SleepForMilliseconds(20); - RAW_LOG(INFO, "Sink got a messages"); // only RAW_LOG under mutex_ here - string message = messages_.front(); - messages_.pop(); - // Normally this would be some more real/involved logging logic - // where LOG() usage can't be eliminated, - // e.g. pushing the message over with an RPC: - int messages_left = messages_.size(); - mutex_.Unlock(); - SleepForMilliseconds(20); - // May not use LOG while holding mutex_, because Buffer() - // acquires mutex_, and Buffer is called from LOG(), - // which has its own internal mutex: - // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer() - LOG(INFO) << "Sink is sending out a message: " << message; - LOG(INFO) << "Have " << messages_left << " left"; - global_messages.push_back(message); - } - } - - // data --------------- - - Mutex mutex_; - bool should_exit_; - queue messages_; // messages to be logged -}; - -// A log sink that exercises WaitTillSent: -// it pushes data to a buffer and wakes up another thread to do the logging -// (that other thread can than use LOG() itself), -class TestWaitingLogSink : public LogSink { - public: - - TestWaitingLogSink() { - tid_ = pthread_self(); // for thread-specific behavior - AddLogSink(this); - } - ~TestWaitingLogSink() { - RemoveLogSink(this); - writer_.Stop(); - writer_.Join(); - } - - // (re)define LogSink interface - - virtual void send(LogSeverity severity, const char* /* full_filename */, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) { - // Push it to Writer thread if we are the original logging thread. - // Note: Something like ThreadLocalLogSink is a better choice - // to do thread-specific LogSink logic for real. - if (pthread_equal(tid_, pthread_self())) { - writer_.Buffer(ToString(severity, base_filename, line, - tm_time, message, message_len)); - } - } - virtual void WaitTillSent() { - // Wait for Writer thread if we are the original logging thread. - if (pthread_equal(tid_, pthread_self())) writer_.Wait(); - } - - private: - - pthread_t tid_; - TestLogSinkWriter writer_; -}; - -// Check that LogSink::WaitTillSent can be used in the advertised way. -// We also do golden-stderr comparison. -static void TestLogSinkWaitTillSent() { - { TestWaitingLogSink sink; - // Sleeps give the sink threads time to do all their work, - // so that we get a reliable log capture to compare to the golden file. - LOG(INFO) << "Message 1"; - SleepForMilliseconds(60); - LOG(ERROR) << "Message 2"; - SleepForMilliseconds(60); - LOG(WARNING) << "Message 3"; - SleepForMilliseconds(60); - } - for (size_t i = 0; i < global_messages.size(); ++i) { - LOG(INFO) << "Sink capture: " << global_messages[i]; - } - CHECK_EQ(global_messages.size(), 3UL); -} - -TEST(Strerror, logging) { - int errcode = EINTR; - char *msg = strdup(strerror(errcode)); - const size_t buf_size = strlen(msg) + 1; - char *buf = new char[buf_size]; - CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1); - buf[0] = 'A'; - CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1); - CHECK_EQ(buf[0], 'A'); - CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1); -#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) - // MacOSX or FreeBSD considers this case is an error since there is - // no enough space. - CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1); -#else - CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0); -#endif - CHECK_STREQ(buf, ""); - CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0); - CHECK_STREQ(buf, msg); - free(msg); - delete[] buf; -} - -// Simple routines to look at the sizes of generated code for LOG(FATAL) and -// CHECK(..) via objdump -void MyFatal() { - LOG(FATAL) << "Failed"; -} -void MyCheck(bool a, bool b) { - CHECK_EQ(a, b); -} - -#ifdef HAVE_LIB_GMOCK - -TEST(DVLog, Basic) { - ScopedMockLog log; - -#if NDEBUG - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); -#else - EXPECT_CALL(log, Log(INFO, __FILE__, "debug log")); -#endif - - FLAGS_v = 1; - DVLOG(1) << "debug log"; -} - -TEST(DVLog, V0) { - ScopedMockLog log; - - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); - - FLAGS_v = 0; - DVLOG(1) << "debug log"; -} - -TEST(LogAtLevel, Basic) { - ScopedMockLog log; - - // The function version outputs "logging.h" as a file name. - EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(INFO, __FILE__, "macro version")); - - int severity = WARNING; - LogAtLevel(severity, "function version"); - - severity = INFO; - // We can use the macro version as a C++ stream. - LOG_AT_LEVEL(severity) << "macro" << ' ' << "version"; -} - -TEST(TestExitOnDFatal, ToBeOrNotToBe) { - // Check the default setting... - EXPECT_TRUE(base::internal::GetExitOnDFatal()); - - // Turn off... - base::internal::SetExitOnDFatal(false); - EXPECT_FALSE(base::internal::GetExitOnDFatal()); - - // We don't die. - { - ScopedMockLog log; - //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); - // LOG(DFATAL) has severity FATAL if debugging, but is - // downgraded to ERROR if not debugging. - const LogSeverity severity = -#ifdef NDEBUG - ERROR; -#else - FATAL; -#endif - EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal")); - LOG(DFATAL) << "This should not be fatal"; - } - - // Turn back on... - base::internal::SetExitOnDFatal(true); - EXPECT_TRUE(base::internal::GetExitOnDFatal()); - -#ifdef GTEST_HAS_DEATH_TEST - // Death comes on little cats' feet. - EXPECT_DEBUG_DEATH({ - LOG(DFATAL) << "This should be fatal in debug mode"; - }, "This should be fatal in debug mode"); -#endif -} - -#ifdef HAVE_STACKTRACE - -static void BacktraceAtHelper() { - LOG(INFO) << "Not me"; - -// The vertical spacing of the next 3 lines is significant. - LOG(INFO) << "Backtrace me"; -} -static int kBacktraceAtLine = __LINE__ - 2; // The line of the LOG(INFO) above - -TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) { - StrictMock log; - - FLAGS_log_backtrace_at = ""; - - EXPECT_CALL(log, Log(_, _, "Backtrace me")); - EXPECT_CALL(log, Log(_, _, "Not me")); - - BacktraceAtHelper(); -} - -TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) { - StrictMock log; - - char where[100]; - snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine); - FLAGS_log_backtrace_at = where; - - // The LOG at the specified line should include a stacktrace which includes - // the name of the containing function, followed by the log message. - // We use HasSubstr()s instead of ContainsRegex() for environments - // which don't have regexp. - EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"), - HasSubstr("BacktraceAtHelper"), - HasSubstr("main"), - HasSubstr("Backtrace me")))); - // Other LOGs should not include a backtrace. - EXPECT_CALL(log, Log(_, _, "Not me")); - - BacktraceAtHelper(); -} - -#endif // HAVE_STACKTRACE - -#endif // HAVE_LIB_GMOCK - -struct UserDefinedClass { - bool operator==(const UserDefinedClass&) const { return true; } -}; - -inline ostream& operator<<(ostream& out, const UserDefinedClass&) { - out << "OK"; - return out; -} - -TEST(UserDefinedClass, logging) { - UserDefinedClass u; - vector buf; - LOG_STRING(INFO, &buf) << u; - CHECK_EQ(1UL, buf.size()); - CHECK(buf[0].find("OK") != string::npos); - - // We must be able to compile this. - CHECK_EQ(u, u); -} diff --git a/third_party/src/glog/src/logging_unittest.err b/third_party/src/glog/src/logging_unittest.err deleted file mode 100644 index 4f80bf5d..00000000 --- a/third_party/src/glog/src/logging_unittest.err +++ /dev/null @@ -1,305 +0,0 @@ -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WARNING: Logging before InitGoogleLogging() is written to STDERR -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0] -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1 -WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2] -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4] -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5 -WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6] -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8] -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9 -EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10 -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this -IDATE TIME__ THREADID logging_unittest.cc:LINE] array -IDATE TIME__ THREADID logging_unittest.cc:LINE] const array -EDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 0000001000 3e8 -no prefix -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000 -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr 0x12345678 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__ -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK: -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error -IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info -WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning -EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error -IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 diff --git a/third_party/src/glog/src/mock-log.h b/third_party/src/glog/src/mock-log.h deleted file mode 100644 index 5b218115..00000000 --- a/third_party/src/glog/src/mock-log.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2007, 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: Zhanyong Wan -// -// Defines the ScopedMockLog class (using Google C++ Mocking -// Framework), which is convenient for testing code that uses LOG(). - -#ifndef GLOG_SRC_MOCK_LOG_H_ -#define GLOG_SRC_MOCK_LOG_H_ - -// For GOOGLE_NAMESPACE. This must go first so we get _XOPEN_SOURCE. -#include "utilities.h" - -#include - -#include - -#include "glog/logging.h" - -_START_GOOGLE_NAMESPACE_ -namespace glog_testing { - -// A ScopedMockLog object intercepts LOG() messages issued during its -// lifespan. Using this together with Google C++ Mocking Framework, -// it's very easy to test how a piece of code calls LOG(). The -// typical usage: -// -// TEST(FooTest, LogsCorrectly) { -// ScopedMockLog log; -// -// // We expect the WARNING "Something bad!" exactly twice. -// EXPECT_CALL(log, Log(WARNING, _, "Something bad!")) -// .Times(2); -// -// // We allow foo.cc to call LOG(INFO) any number of times. -// EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _)) -// .Times(AnyNumber()); -// -// Foo(); // Exercises the code under test. -// } -class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink { - public: - // When a ScopedMockLog object is constructed, it starts to - // intercept logs. - ScopedMockLog() { AddLogSink(this); } - - // When the object is destructed, it stops intercepting logs. - virtual ~ScopedMockLog() { RemoveLogSink(this); } - - // Implements the mock method: - // - // void Log(LogSeverity severity, const string& file_path, - // const string& message); - // - // The second argument to Send() is the full path of the source file - // in which the LOG() was issued. - // - // Note, that in a multi-threaded environment, all LOG() messages from a - // single thread will be handled in sequence, but that cannot be guaranteed - // for messages from different threads. In fact, if the same or multiple - // expectations are matched on two threads concurrently, their actions will - // be executed concurrently as well and may interleave. - MOCK_METHOD3(Log, void(GOOGLE_NAMESPACE::LogSeverity severity, - const std::string& file_path, - const std::string& message)); - - private: - // Implements the send() virtual function in class LogSink. - // Whenever a LOG() statement is executed, this function will be - // invoked with information presented in the LOG(). - // - // The method argument list is long and carries much information a - // test usually doesn't care about, so we trim the list before - // forwarding the call to Log(), which is much easier to use in - // tests. - // - // We still cannot call Log() directly, as it may invoke other LOG() - // messages, either due to Invoke, or due to an error logged in - // Google C++ Mocking Framework code, which would trigger a deadlock - // since a lock is held during send(). - // - // Hence, we save the message for WaitTillSent() which will be called after - // the lock on send() is released, and we'll call Log() inside - // WaitTillSent(). Since while a single send() call may be running at a - // time, multiple WaitTillSent() calls (along with the one send() call) may - // be running simultaneously, we ensure thread-safety of the exchange between - // send() and WaitTillSent(), and that for each message, LOG(), send(), - // WaitTillSent() and Log() are executed in the same thread. - virtual void send(GOOGLE_NAMESPACE::LogSeverity severity, - const char* full_filename, - const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - message_info_.severity = severity; - message_info_.file_path = full_filename; - message_info_.message = std::string(message, message_len); - } - - // Implements the WaitTillSent() virtual function in class LogSink. - // It will be executed after send() and after the global logging lock is - // released, so calls within it (or rather within the Log() method called - // within) may also issue LOG() statements. - // - // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for - // a given log message. - virtual void WaitTillSent() { - // First, and very importantly, we save a copy of the message being - // processed before calling Log(), since Log() may indirectly call send() - // and WaitTillSent() in the same thread again. - MessageInfo message_info = message_info_; - Log(message_info.severity, message_info.file_path, message_info.message); - } - - // All relevant information about a logged message that needs to be passed - // from send() to WaitTillSent(). - struct MessageInfo { - GOOGLE_NAMESPACE::LogSeverity severity; - std::string file_path; - std::string message; - }; - MessageInfo message_info_; -}; - -} // namespace glog_testing -_END_GOOGLE_NAMESPACE_ - -#endif // GLOG_SRC_MOCK_LOG_H_ diff --git a/third_party/src/glog/src/mock-log_test.cc b/third_party/src/glog/src/mock-log_test.cc deleted file mode 100644 index 7d58a307..00000000 --- a/third_party/src/glog/src/mock-log_test.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2007, 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: Zhanyong Wan - -// Tests the ScopedMockLog class. - -#include "mock-log.h" - -#include - -#include -#include - -namespace { - -using GOOGLE_NAMESPACE::INFO; -using GOOGLE_NAMESPACE::WARNING; -using GOOGLE_NAMESPACE::ERROR; -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using std::string; -using testing::_; -using testing::HasSubstr; -using testing::InSequence; -using testing::InvokeWithoutArgs; - -// Tests that ScopedMockLog intercepts LOG()s when it's alive. -TEST(ScopedMockLogTest, InterceptsLog) { - ScopedMockLog log; - - InSequence s; - EXPECT_CALL(log, Log(WARNING, HasSubstr("/mock-log_test.cc"), "Fishy.")); - EXPECT_CALL(log, Log(INFO, _, "Working...")) - .Times(2); - EXPECT_CALL(log, Log(ERROR, _, "Bad!!")); - - LOG(WARNING) << "Fishy."; - LOG(INFO) << "Working..."; - LOG(INFO) << "Working..."; - LOG(ERROR) << "Bad!!"; -} - -void LogBranch() { - LOG(INFO) << "Logging a branch..."; -} - -void LogTree() { - LOG(INFO) << "Logging the whole tree..."; -} - -void LogForest() { - LOG(INFO) << "Logging the entire forest."; - LOG(INFO) << "Logging the entire forest.."; - LOG(INFO) << "Logging the entire forest..."; -} - -// The purpose of the following test is to verify that intercepting logging -// continues to work properly if a LOG statement is executed within the scope -// of a mocked call. -TEST(ScopedMockLogTest, LogDuringIntercept) { - ScopedMockLog log; - InSequence s; - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging a branch...")) - .WillOnce(InvokeWithoutArgs(LogTree)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the whole tree...")) - .WillOnce(InvokeWithoutArgs(LogForest)); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest.")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest..")); - EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest...")); - LogBranch(); -} - -} // namespace - -int main(int argc, char **argv) { - GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]); - testing::InitGoogleMock(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/third_party/src/glog/src/raw_logging.cc b/third_party/src/glog/src/raw_logging.cc deleted file mode 100644 index 7a7409bb..00000000 --- a/third_party/src/glog/src/raw_logging.cc +++ /dev/null @@ -1,172 +0,0 @@ -// 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: Maxim Lifantsev -// -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include // for close() and write() -#endif -#include // for open() -#include -#include "config.h" -#include "glog/logging.h" // To pick up flag settings etc. -#include "glog/raw_logging.h" -#include "base/commandlineflags.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -#if defined(HAVE_SYSCALL_H) -#include // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include // for syscall() -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H) -# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len) -#else - // Not so safe, but what can you do? -# define safe_write(fd, s, len) write(fd, s, len) -#endif - -_START_GOOGLE_NAMESPACE_ - -// Data for RawLog__ below. We simply pick up the latest -// time data created by a normal log message to avoid calling -// localtime_r which can allocate memory. -static struct ::tm last_tm_time_for_raw_log; -static int last_usecs_for_raw_log; - -void RawLog__SetLastTime(const struct ::tm& t, int usecs) { - memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log)); - last_usecs_for_raw_log = usecs; -} - -// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths -// that invoke malloc() and getenv() that might acquire some locks. -// If this becomes a problem we should reimplement a subset of vsnprintf -// that does not need locks and malloc. - -// Helper for RawLog__ below. -// *DoRawLog writes to *buf of *size and move them past the written portion. -// It returns true iff there was no overflow or error. -static bool DoRawLog(char** buf, int* size, const char* format, ...) { - va_list ap; - va_start(ap, format); - int n = vsnprintf(*buf, *size, format, ap); - va_end(ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -// Helper for RawLog__ below. -inline static bool VADoRawLog(char** buf, int* size, - const char* format, va_list ap) { - int n = vsnprintf(*buf, *size, format, ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -static const int kLogBufSize = 3000; -static bool crashed = false; -static CrashReason crash_reason; -static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0' - -void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) { - if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold || - FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) { - return; // this stderr log message is suppressed - } - // can't call localtime_r here: it can allocate - struct ::tm& t = last_tm_time_for_raw_log; - char buffer[kLogBufSize]; - char* buf = buffer; - int size = sizeof(buffer); - - // NOTE: this format should match the specification in base/logging.h - DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ", - LogSeverityNames[severity][0], - 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, - last_usecs_for_raw_log, - static_cast(GetTID()), - const_basename(const_cast(file)), line); - - // Record the position and size of the buffer after the prefix - const char* msg_start = buf; - const int msg_size = size; - - va_list ap; - va_start(ap, format); - bool no_chop = VADoRawLog(&buf, &size, format, ap); - va_end(ap); - if (no_chop) { - DoRawLog(&buf, &size, "\n"); - } else { - DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n"); - } - // We make a raw syscall to write directly to the stderr file descriptor, - // avoiding FILE buffering (to avoid invoking malloc()), and bypassing - // libc (to side-step any libc interception). - // We write just once to avoid races with other invocations of RawLog__. - safe_write(STDERR_FILENO, buffer, strlen(buffer)); - if (severity == GLOG_FATAL) { - if (!sync_val_compare_and_swap(&crashed, false, true)) { - crash_reason.filename = file; - crash_reason.line_number = line; - memcpy(crash_buf, msg_start, msg_size); // Don't include prefix - crash_reason.message = crash_buf; -#ifdef HAVE_STACKTRACE - crash_reason.depth = - GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1); -#else - crash_reason.depth = 0; -#endif - SetCrashReason(&crash_reason); - } - LogMessage::Fail(); // abort() - } -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/signalhandler.cc b/third_party/src/glog/src/signalhandler.cc deleted file mode 100644 index d6c203b5..00000000 --- a/third_party/src/glog/src/signalhandler.cc +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) 2008, 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 -// -// Implementation of InstallFailureSignalHandler(). - -#include "utilities.h" -#include "stacktrace.h" -#include "symbolize.h" -#include "glog/logging.h" - -#include -#include -#ifdef HAVE_UCONTEXT_H -# include -#endif -#ifdef HAVE_SYS_UCONTEXT_H -# include -#endif -#include - -_START_GOOGLE_NAMESPACE_ - -namespace { - -// We'll install the failure signal handler for these signals. We could -// use strsignal() to get signal names, but we don't use it to avoid -// introducing yet another #ifdef complication. -// -// The list should be synced with the comment in signalhandler.h. -const struct { - int number; - const char *name; -} kFailureSignals[] = { - { SIGSEGV, "SIGSEGV" }, - { SIGILL, "SIGILL" }, - { SIGFPE, "SIGFPE" }, - { SIGABRT, "SIGABRT" }, - { SIGBUS, "SIGBUS" }, - { SIGTERM, "SIGTERM" }, -}; - -// Returns the program counter from signal context, NULL if unknown. -void* GetPC(void* ucontext_in_void) { -#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT) - if (ucontext_in_void != NULL) { - ucontext_t *context = reinterpret_cast(ucontext_in_void); - return (void*)context->PC_FROM_UCONTEXT; - } -#endif - return NULL; -} - -// The class is used for formatting error messages. We don't use printf() -// as it's not async signal safe. -class MinimalFormatter { - public: - MinimalFormatter(char *buffer, int size) - : buffer_(buffer), - cursor_(buffer), - end_(buffer + size) { - } - - // Returns the number of bytes written in the buffer. - int num_bytes_written() const { return cursor_ - buffer_; } - - // Appends string from "str" and updates the internal cursor. - void AppendString(const char* str) { - int i = 0; - while (str[i] != '\0' && cursor_ + i < end_) { - cursor_[i] = str[i]; - ++i; - } - cursor_ += i; - } - - // Formats "number" in "radix" and updates the internal cursor. - // Lowercase letters are used for 'a' - 'z'. - void AppendUint64(uint64 number, int radix) { - int i = 0; - while (cursor_ + i < end_) { - const int tmp = number % radix; - number /= radix; - cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10); - ++i; - if (number == 0) { - break; - } - } - // Reverse the bytes written. - std::reverse(cursor_, cursor_ + i); - cursor_ += i; - } - - // Formats "number" as hexadecimal number, and updates the internal - // cursor. Padding will be added in front if needed. - void AppendHexWithPadding(uint64 number, int width) { - char* start = cursor_; - AppendString("0x"); - AppendUint64(number, 16); - // Move to right and add padding in front if needed. - if (cursor_ < start + width) { - const int64 delta = start + width - cursor_; - std::copy(start, cursor_, start + delta); - std::fill(start, start + delta, ' '); - cursor_ = start + width; - } - } - - private: - char *buffer_; - char *cursor_; - const char * const end_; -}; - -// Writes the given data with the size to the standard error. -void WriteToStderr(const char* data, int size) { - if (write(STDERR_FILENO, data, size) < 0) { - // Ignore errors. - } -} - -// The writer function can be changed by InstallFailureWriter(). -void (*g_failure_writer)(const char* data, int size) = WriteToStderr; - -// Dumps time information. We don't dump human-readable time information -// as localtime() is not guaranteed to be async signal safe. -void DumpTimeInfo() { - time_t time_in_sec = time(NULL); - char buf[256]; // Big enough for time info. - MinimalFormatter formatter(buf, sizeof(buf)); - formatter.AppendString("*** Aborted at "); - formatter.AppendUint64(time_in_sec, 10); - formatter.AppendString(" (unix time)"); - formatter.AppendString(" try \"date -d @"); - formatter.AppendUint64(time_in_sec, 10); - formatter.AppendString("\" if you are using GNU date ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// Dumps information about the signal to STDERR. -void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { - // Get the signal name. - const char* signal_name = NULL; - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - if (signal_number == kFailureSignals[i].number) { - signal_name = kFailureSignals[i].name; - } - } - - char buf[256]; // Big enough for signal info. - MinimalFormatter formatter(buf, sizeof(buf)); - - formatter.AppendString("*** "); - if (signal_name) { - formatter.AppendString(signal_name); - } else { - // Use the signal number if the name is unknown. The signal name - // should be known, but just in case. - formatter.AppendString("Signal "); - formatter.AppendUint64(signal_number, 10); - } - formatter.AppendString(" (@0x"); - formatter.AppendUint64(reinterpret_cast(siginfo->si_addr), 16); - formatter.AppendString(")"); - formatter.AppendString(" received by PID "); - formatter.AppendUint64(getpid(), 10); - formatter.AppendString(" (TID 0x"); - // We assume pthread_t is an integral number or a pointer, rather - // than a complex struct. In some environments, pthread_self() - // returns an uint64 but in some other environments pthread_self() - // returns a pointer. Hence we use C-style cast here, rather than - // reinterpret/static_cast, to support both types of environments. - formatter.AppendUint64((uintptr_t)pthread_self(), 16); - formatter.AppendString(") "); - // Only linux has the PID of the signal sender in si_pid. -#ifdef OS_LINUX - formatter.AppendString("from PID "); - formatter.AppendUint64(siginfo->si_pid, 10); - formatter.AppendString("; "); -#endif - formatter.AppendString("stack trace: ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// Dumps information about the stack frame to STDERR. -void DumpStackFrameInfo(const char* prefix, void* pc) { - // Get the symbol name. - const char *symbol = "(unknown)"; - char symbolized[1024]; // Big enough for a sane symbol. - // Symbolizes the previous address of pc because pc may be in the - // next function. - if (Symbolize(reinterpret_cast(pc) - 1, - symbolized, sizeof(symbolized))) { - symbol = symbolized; - } - - char buf[1024]; // Big enough for stack frame info. - MinimalFormatter formatter(buf, sizeof(buf)); - - formatter.AppendString(prefix); - formatter.AppendString("@ "); - const int width = 2 * sizeof(void*) + 2; // + 2 for "0x". - formatter.AppendHexWithPadding(reinterpret_cast(pc), width); - formatter.AppendString(" "); - formatter.AppendString(symbol); - formatter.AppendString("\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// Invoke the default signal handler. -void InvokeDefaultSignalHandler(int signal_number) { - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(signal_number, &sig_action, NULL); - kill(getpid(), signal_number); -} - -// This variable is used for protecting FailureSignalHandler() from -// dumping stuff while another thread is doing it. Our policy is to let -// the first thread dump stuff and let other threads wait. -// See also comments in FailureSignalHandler(). -static pthread_t* g_entered_thread_id_pointer = NULL; - -// Dumps signal and stack frame information, and invokes the default -// signal handler once our job is done. -void FailureSignalHandler(int signal_number, - siginfo_t *signal_info, - void *ucontext) { - // First check if we've already entered the function. We use an atomic - // compare and swap operation for platforms that support it. For other - // platforms, we use a naive method that could lead to a subtle race. - - // We assume pthread_self() is async signal safe, though it's not - // officially guaranteed. - pthread_t my_thread_id = pthread_self(); - // NOTE: We could simply use pthread_t rather than pthread_t* for this, - // if pthread_self() is guaranteed to return non-zero value for thread - // ids, but there is no such guarantee. We need to distinguish if the - // old value (value returned from __sync_val_compare_and_swap) is - // different from the original value (in this case NULL). - pthread_t* old_thread_id_pointer = - glog_internal_namespace_::sync_val_compare_and_swap( - &g_entered_thread_id_pointer, - static_cast(NULL), - &my_thread_id); - if (old_thread_id_pointer != NULL) { - // We've already entered the signal handler. What should we do? - if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) { - // It looks the current thread is reentering the signal handler. - // Something must be going wrong (maybe we are reentering by another - // type of signal?). Kill ourself by the default signal handler. - InvokeDefaultSignalHandler(signal_number); - } - // Another thread is dumping stuff. Let's wait until that thread - // finishes the job and kills the process. - while (true) { - sleep(1); - } - } - // This is the first time we enter the signal handler. We are going to - // do some interesting stuff from here. - // TODO(satorux): We might want to set timeout here using alarm(), but - // mixing alarm() and sleep() can be a bad idea. - - // First dump time info. - DumpTimeInfo(); - - // Get the program counter from ucontext. - void *pc = GetPC(ucontext); - DumpStackFrameInfo("PC: ", pc); - -#ifdef HAVE_STACKTRACE - // Get the stack traces. - void *stack[32]; - // +1 to exclude this function. - const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1); - DumpSignalInfo(signal_number, signal_info); - // Dump the stack traces. - for (int i = 0; i < depth; ++i) { - DumpStackFrameInfo(" ", stack[i]); - } -#endif - - // *** TRANSITION *** - // - // BEFORE this point, all code must be async-termination-safe! - // (See WARNING above.) - // - // AFTER this point, we do unsafe things, like using LOG()! - // The process could be terminated or hung at any time. We try to - // do more useful things first and riskier things later. - - // Flush the logs before we do anything in case 'anything' - // causes problems. - FlushLogFilesUnsafe(0); - - // Kill ourself by the default signal handler. - InvokeDefaultSignalHandler(signal_number); -} - -} // namespace - -void InstallFailureSignalHandler() { - // Build the sigaction struct. - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_flags |= SA_SIGINFO; - sig_action.sa_sigaction = &FailureSignalHandler; - - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); - } -} - -void InstallFailureWriter(void (*writer)(const char* data, int size)) { - g_failure_writer = writer; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/signalhandler_unittest.cc b/third_party/src/glog/src/signalhandler_unittest.cc deleted file mode 100644 index 1cd0fa01..00000000 --- a/third_party/src/glog/src/signalhandler_unittest.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2008, 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 -// -// This is a helper binary for testing signalhandler.cc. The actual test -// is done in signalhandler_unittest.sh. - -#include "utilities.h" - -#include -#include -#include -#include -#include -#include "glog/logging.h" - -using namespace GOOGLE_NAMESPACE; - -void* DieInThread(void*) { - // We assume pthread_t is an integral number or a pointer, rather - // than a complex struct. In some environments, pthread_self() - // returns an uint64 but in some other environments pthread_self() - // returns a pointer. Hence we use C-style cast here, rather than - // reinterpret/static_cast, to support both types of environments. - fprintf(stderr, "0x%lx is dying\n", (long)pthread_self()); - // Use volatile to prevent from these to be optimized away. - volatile int a = 0; - volatile int b = 1 / a; - fprintf(stderr, "We should have died: b=%d\n", b); - return NULL; -} - -void WriteToStdout(const char* data, int size) { - if (write(STDOUT_FILENO, data, size) < 0) { - // Ignore errors. - } -} - -int main(int argc, char **argv) { -#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE) - InitGoogleLogging(argv[0]); -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#endif - InstallFailureSignalHandler(); - const std::string command = argc > 1 ? argv[1] : "none"; - if (command == "segv") { - // We'll check if this is outputted. - LOG(INFO) << "create the log file"; - LOG(INFO) << "a message before segv"; - // We assume 0xDEAD is not writable. - int *a = (int*)0xDEAD; - *a = 0; - } else if (command == "loop") { - fprintf(stderr, "looping\n"); - while (true); - } else if (command == "die_in_thread") { - pthread_t thread; - pthread_create(&thread, NULL, &DieInThread, NULL); - pthread_join(thread, NULL); - } else if (command == "dump_to_stdout") { - InstallFailureWriter(WriteToStdout); - abort(); - } else { - // Tell the shell script - puts("OK"); - } -#endif - return 0; -} diff --git a/third_party/src/glog/src/signalhandler_unittest.sh b/third_party/src/glog/src/signalhandler_unittest.sh deleted file mode 100644 index 265cd458..00000000 --- a/third_party/src/glog/src/signalhandler_unittest.sh +++ /dev/null @@ -1,131 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 2008, 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 signalhandler.cc. - -die () { - echo $1 - exit 1 -} - -BINDIR=".libs" -LIBGLOG="$BINDIR/libglog.so" - -BINARY="$BINDIR/signalhandler_unittest" -LOG_INFO="./signalhandler_unittest.INFO" - -# Remove temporary files. -rm -f signalhandler.out* - -if test -e "$BINARY"; then - # We need shared object. - export LD_LIBRARY_PATH=$BINDIR - export DYLD_LIBRARY_PATH=$BINDIR -else - # For windows - BINARY="./signalhandler_unittest.exe" - if ! test -e "$BINARY"; then - echo "We coundn't find demangle_unittest binary." - exit 1 - fi -fi - -if [ x`$BINARY` != 'xOK' ]; then - echo "PASS (No stacktrace support. We don't run this test.)" - exit 0 -fi - -# The PC cannot be obtained in signal handlers on PowerPC correctly. -# We just skip the test for PowerPC. -if [ x`uname -p` = x"powerpc" ]; then - echo "PASS (We don't test the signal handler on PowerPC.)" - exit 0 -fi - -# Test for a case the program kills itself by SIGSEGV. -GOOGLE_LOG_DIR=. $BINARY segv 2> signalhandler.out1 -for pattern in SIGSEGV 0xdead main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out1; then - die "'$pattern' should appear in the output" - fi -done -if ! grep --quiet "a message before segv" $LOG_INFO; then - die "'a message before segv' should appear in the INFO log" -fi -rm -f $LOG_INFO - -# Test for a case the program is killed by this shell script. -# $! = the process id of the last command run in the background. -# $$ = the process id of this shell. -$BINARY loop 2> signalhandler.out2 & -# Wait until "looping" is written in the file. This indicates the program -# is ready to accept signals. -while true; do - if grep --quiet looping signalhandler.out2; then - break - fi -done -kill -TERM $! -wait $! - -from_pid='' -# Only linux has the process ID of the signal sender. -if [ x`uname` = "xLinux" ]; then - from_pid="from PID $$" -fi -for pattern in SIGTERM "by PID $!" "$from_pid" main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out2; then - die "'$pattern' should appear in the output" - fi -done - -# Test for a case the program dies in a non-main thread. -$BINARY die_in_thread 2> signalhandler.out3 -EXPECTED_TID="`sed 's/ .*//; q' signalhandler.out3`" - -for pattern in SIGFPE DieInThread "TID $EXPECTED_TID" "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out3; then - die "'$pattern' should appear in the output" - fi -done - -# Test for a case the program installs a custom failure writer that writes -# stuff to stdout instead of stderr. -$BINARY dump_to_stdout 1> signalhandler.out4 -for pattern in SIGABRT main "Aborted at [0-9]"; do - if ! grep --quiet "$pattern" signalhandler.out4; then - die "'$pattern' should appear in the output" - fi -done - -echo PASS diff --git a/third_party/src/glog/src/stacktrace.h b/third_party/src/glog/src/stacktrace.h deleted file mode 100644 index 8c3e8fe8..00000000 --- a/third_party/src/glog/src/stacktrace.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2000 - 2007, 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. -// -// Routines to extract the current stack trace. These functions are -// thread-safe. - -#ifndef BASE_STACKTRACE_H_ -#define BASE_STACKTRACE_H_ - -#include "config.h" - -_START_GOOGLE_NAMESPACE_ - -// This is similar to the GetStackFrames routine, except that it returns -// the stack trace only, and not the stack frame sizes as well. -// Example: -// main() { foo(); } -// foo() { bar(); } -// bar() { -// void* result[10]; -// int depth = GetStackFrames(result, 10, 1); -// } -// -// This produces: -// result[0] foo -// result[1] main -// .... ... -// -// "result" must not be NULL. -extern int GetStackTrace(void** result, int max_depth, int skip_count); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_STACKTRACE_H_ diff --git a/third_party/src/glog/src/stacktrace_generic-inl.h b/third_party/src/glog/src/stacktrace_generic-inl.h deleted file mode 100644 index fad81d3e..00000000 --- a/third_party/src/glog/src/stacktrace_generic-inl.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2000 - 2007, 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. -// -// Portable implementation - just use glibc -// -// Note: The glibc implementation may cause a call to malloc. -// This can cause a deadlock in HeapProfiler. -#include -#include -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - static const int kStackLength = 64; - void * stack[kStackLength]; - int size; - - size = backtrace(stack, kStackLength); - skip_count++; // we want to skip the current frame as well - int result_count = size - skip_count; - if (result_count < 0) - result_count = 0; - if (result_count > max_depth) - result_count = max_depth; - for (int i = 0; i < result_count; i++) - result[i] = stack[i + skip_count]; - - return result_count; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/stacktrace_libunwind-inl.h b/third_party/src/glog/src/stacktrace_libunwind-inl.h deleted file mode 100644 index 0dc14c65..00000000 --- a/third_party/src/glog/src/stacktrace_libunwind-inl.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2005 - 2007, 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: Arun Sharma -// -// Produce stack trace using libunwind - -#include "utilities.h" - -extern "C" { -#define UNW_LOCAL_ONLY -#include -} -#include "glog/raw_logging.h" -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Sometimes, we can try to get a stack trace from within a stack -// trace, because libunwind can call mmap (maybe indirectly via an -// internal mmap based memory allocator), and that mmap gets trapped -// and causes a stack-trace request. If were to try to honor that -// recursive request, we'd end up with infinite recursion or deadlock. -// Luckily, it's safe to ignore those subsequent traces. In such -// cases, we return 0 to indicate the situation. -static bool g_now_entering = false; - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void *ip; - int n = 0; - unw_cursor_t cursor; - unw_context_t uc; - - if (sync_val_compare_and_swap(&g_now_entering, false, true)) { - return 0; - } - - unw_getcontext(&uc); - RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed"); - skip_count++; // Do not include the "GetStackTrace" frame - - while (n < max_depth) { - int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip); - if (ret < 0) - break; - if (skip_count > 0) { - skip_count--; - } else { - result[n++] = ip; - } - ret = unw_step(&cursor); - if (ret <= 0) - break; - } - - g_now_entering = false; - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/stacktrace_powerpc-inl.h b/third_party/src/glog/src/stacktrace_powerpc-inl.h deleted file mode 100644 index 1090dded..00000000 --- a/third_party/src/glog/src/stacktrace_powerpc-inl.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2007, 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: Craig Silverstein -// -// Produce stack trace. I'm guessing (hoping!) the code is much like -// for x86. For apple machines, at least, it seems to be; see -// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html -// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK -// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 - -#include -#include // for uintptr_t -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Given a pointer to a stack frame, locate and return the calling -// stackframe, or return NULL if no stackframe can be found. Perform sanity -// checks (the strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template -static void **NextStackFrame(void **old_sp) { - void **new_sp = (void **) *old_sp; - - // Check that the transition from frame pointer old_sp to frame - // pointer new_sp isn't clearly bogus - if (STRICT_UNWINDING) { - // With the stack growing downwards, older stack frame must be - // at a greater address that the current one. - if (new_sp <= old_sp) return NULL; - // Assume stack frames larger than 100,000 bytes are bogus. - if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; - } else { - // In the non-strict mode, allow discontiguous stack frames. - // (alternate-signal-stacks for example). - if (new_sp == old_sp) return NULL; - // And allow frames upto about 1MB. - if ((new_sp > old_sp) - && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; - } - if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; - return new_sp; -} - -// This ensures that GetStackTrace stes up the Link Register properly. -void StacktracePowerPCDummyFunction() __attribute__((noinline)); -void StacktracePowerPCDummyFunction() { __asm__ volatile(""); } - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void **sp; - // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther) - // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a - // different asm syntax. I don't know quite the best way to discriminate - // systems using the old as from the new one; I've gone with __APPLE__. -#ifdef __APPLE__ - __asm__ volatile ("mr %0,r1" : "=r" (sp)); -#else - __asm__ volatile ("mr %0,1" : "=r" (sp)); -#endif - - // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack - // entry that holds the return address of the subroutine call (what - // instruction we run after our function finishes). This is the - // same as the stack-pointer of our parent routine, which is what we - // want here. While the compiler will always(?) set up LR for - // subroutine calls, it may not for leaf functions (such as this one). - // This routine forces the compiler (at least gcc) to push it anyway. - StacktracePowerPCDummyFunction(); - - // The LR save area is used by the callee, so the top entry is bogus. - skip_count++; - - int n = 0; - while (sp && n < max_depth) { - if (skip_count > 0) { - skip_count--; - } else { - // PowerPC has 3 main ABIs, which say where in the stack the - // Link Register is. For DARWIN and AIX (used by apple and - // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc), - // it's in sp[1]. -#if defined(_CALL_AIX) || defined(_CALL_DARWIN) - result[n++] = *(sp+2); -#elif defined(_CALL_SYSV) - result[n++] = *(sp+1); -#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__)) - // This check is in case the compiler doesn't define _CALL_AIX/etc. - result[n++] = *(sp+2); -#elif defined(__linux) - // This check is in case the compiler doesn't define _CALL_SYSV. - result[n++] = *(sp+1); -#else -#error Need to specify the PPC ABI for your archiecture. -#endif - } - // Use strict unwinding rules. - sp = NextStackFrame(sp); - } - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/stacktrace_unittest.cc b/third_party/src/glog/src/stacktrace_unittest.cc deleted file mode 100644 index c1b3b36f..00000000 --- a/third_party/src/glog/src/stacktrace_unittest.cc +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2004, 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. - -#include "utilities.h" - -#include -#include -#include "config.h" -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "stacktrace.h" - -#ifdef HAVE_EXECINFO_H -# include -#endif - -using namespace GOOGLE_NAMESPACE; - -#ifdef HAVE_STACKTRACE - -// Obtain a backtrace, verify that the expected callers are present in the -// backtrace, and maybe print the backtrace to stdout. - -// The sequence of functions whose return addresses we expect to see in the -// backtrace. -const int BACKTRACE_STEPS = 6; - -struct AddressRange { - const void *start, *end; -}; - -// Expected function [start,end] range. -AddressRange expected_range[BACKTRACE_STEPS]; - -#if __GNUC__ -// Using GCC extension: address of a label can be taken with '&&label'. -// Start should be a label somewhere before recursive call, end somewhere -// after it. -#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \ - do { \ - (prange)->start = &&start_label; \ - (prange)->end = &&end_label; \ - CHECK_LT((prange)->start, (prange)->end); \ - } while (0) -// This macro expands into "unmovable" code (opaque to GCC), and that -// prevents GCC from moving a_label up or down in the code. -// Without it, there is no code following the 'end' label, and GCC -// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before -// the recursive call. -#define DECLARE_ADDRESS_LABEL(a_label) \ - a_label: do { __asm__ __volatile__(""); } while (0) -// Gcc 4.4.0 may split function into multiple chunks, and the chunk -// performing recursive call may end up later in the code then the return -// instruction (this actually happens with FDO). -// Adjust function range from __builtin_return_address. -#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \ - do { \ - void *ra = __builtin_return_address(0); \ - CHECK_LT((prange)->start, ra); \ - if (ra > (prange)->end) { \ - printf("Adjusting range from %p..%p to %p..%p\n", \ - (prange)->start, (prange)->end, \ - (prange)->start, ra); \ - (prange)->end = ra; \ - } \ - } while (0) -#else -// Assume the Check* functions below are not longer than 256 bytes. -#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \ - do { \ - (prange)->start = reinterpret_cast(&fn); \ - (prange)->end = reinterpret_cast(&fn) + 256; \ - } while (0) -#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0) -#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0) -#endif // __GNUC__ - -//-----------------------------------------------------------------------// - -void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range) -{ - CHECK_GE(ret_addr, range.start); - CHECK_LE(ret_addr, range.end); -} - -//-----------------------------------------------------------------------// - -void ATTRIBUTE_NOINLINE CheckStackTrace(int); -void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) { - const int STACK_LEN = 10; - void *stack[STACK_LEN]; - int size; - - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]); - INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]); - DECLARE_ADDRESS_LABEL(start); - size = GetStackTrace(stack, STACK_LEN, 0); - printf("Obtained %d stack frames.\n", size); - CHECK_GE(size, 1); - CHECK_LE(size, STACK_LEN); - - if (1) { -#ifdef HAVE_EXECINFO_H - char **strings = backtrace_symbols(stack, size); - printf("Obtained %d stack frames.\n", size); - for (int i = 0; i < size; i++) - printf("%s %p\n", strings[i], stack[i]); - printf("CheckStackTrace() addr: %p\n", &CheckStackTrace); - free(strings); -#endif - } - for (int i = 0; i < BACKTRACE_STEPS; i++) { - printf("Backtrace %d: expected: %p..%p actual: %p ... ", - i, expected_range[i].start, expected_range[i].end, stack[i]); - fflush(stdout); - CheckRetAddrIsInFunction(stack[i], expected_range[i]); - printf("OK\n"); - } - DECLARE_ADDRESS_LABEL(end); -} - -//-----------------------------------------------------------------------// - -/* Dummy functions to make the backtrace more interesting. */ -void ATTRIBUTE_NOINLINE CheckStackTrace4(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]); - INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTraceLeaf(); - DECLARE_ADDRESS_LABEL(end); -} -void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]); - INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace4(j); - DECLARE_ADDRESS_LABEL(end); -} -void ATTRIBUTE_NOINLINE CheckStackTrace2(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]); - INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace3(j); - DECLARE_ADDRESS_LABEL(end); -} -void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) { - ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]); - INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace2(j); - DECLARE_ADDRESS_LABEL(end); -} -void ATTRIBUTE_NOINLINE CheckStackTrace(int i) { - INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]); - DECLARE_ADDRESS_LABEL(start); - for (int j = i; j >= 0; j--) - CheckStackTrace1(j); - DECLARE_ADDRESS_LABEL(end); -} - -//-----------------------------------------------------------------------// - -int main(int, char ** argv) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - - CheckStackTrace(0); - - printf("PASS\n"); - return 0; -} - -#else -int main() { - printf("PASS (no stacktrace support)\n"); - return 0; -} -#endif // HAVE_STACKTRACE diff --git a/third_party/src/glog/src/stacktrace_x86-inl.h b/third_party/src/glog/src/stacktrace_x86-inl.h deleted file mode 100644 index cfd31f78..00000000 --- a/third_party/src/glog/src/stacktrace_x86-inl.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2000 - 2007, 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. -// -// Produce stack trace - -#include // for uintptr_t - -#include "utilities.h" // for OS_* macros - -#if !defined(OS_WINDOWS) -#include -#include -#endif - -#include // for NULL -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -// Given a pointer to a stack frame, locate and return the calling -// stackframe, or return NULL if no stackframe can be found. Perform sanity -// checks (the strictness of which is controlled by the boolean parameter -// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. -template -static void **NextStackFrame(void **old_sp) { - void **new_sp = (void **) *old_sp; - - // Check that the transition from frame pointer old_sp to frame - // pointer new_sp isn't clearly bogus - if (STRICT_UNWINDING) { - // With the stack growing downwards, older stack frame must be - // at a greater address that the current one. - if (new_sp <= old_sp) return NULL; - // Assume stack frames larger than 100,000 bytes are bogus. - if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; - } else { - // In the non-strict mode, allow discontiguous stack frames. - // (alternate-signal-stacks for example). - if (new_sp == old_sp) return NULL; - // And allow frames upto about 1MB. - if ((new_sp > old_sp) - && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; - } - if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; -#ifdef __i386__ - // On 64-bit machines, the stack pointer can be very close to - // 0xffffffff, so we explicitly check for a pointer into the - // last two pages in the address space - if ((uintptr_t)new_sp >= 0xffffe000) return NULL; -#endif -#if !defined(OS_WINDOWS) - if (!STRICT_UNWINDING) { - // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test - // on AMD-based machines with VDSO-enabled kernels. - // Make an extra sanity check to insure new_sp is readable. - // Note: NextStackFrame() is only called while the program - // is already on its last leg, so it's ok to be slow here. - static int page_size = getpagesize(); - void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1)); - if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1) - return NULL; - } -#endif - return new_sp; -} - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - void **sp; -#ifdef __i386__ - // Stack frame format: - // sp[0] pointer to previous frame - // sp[1] caller address - // sp[2] first argument - // ... - sp = (void **)&result - 2; -#endif - -#ifdef __x86_64__ - // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8 - unsigned long rbp; - // Move the value of the register %rbp into the local variable rbp. - // We need 'volatile' to prevent this instruction from getting moved - // around during optimization to before function prologue is done. - // An alternative way to achieve this - // would be (before this __asm__ instruction) to call Noop() defined as - // static void Noop() __attribute__ ((noinline)); // prevent inlining - // static void Noop() { asm(""); } // prevent optimizing-away - __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp)); - // Arguments are passed in registers on x86-64, so we can't just - // offset from &result - sp = (void **) rbp; -#endif - - int n = 0; - while (sp && n < max_depth) { - if (*(sp+1) == (void *)0) { - // In 64-bit code, we often see a frame that - // points to itself and has a return address of 0. - break; - } - if (skip_count > 0) { - skip_count--; - } else { - result[n++] = *(sp+1); - } - // Use strict unwinding rules. - sp = NextStackFrame(sp); - } - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/stacktrace_x86_64-inl.h b/third_party/src/glog/src/stacktrace_x86_64-inl.h deleted file mode 100644 index c14482ed..00000000 --- a/third_party/src/glog/src/stacktrace_x86_64-inl.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2005 - 2007, 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: Arun Sharma -// -// Produce stack trace using libgcc - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - -extern "C" { -#include // for NULL -#include // ABI defined unwinder -} -#include "stacktrace.h" - -_START_GOOGLE_NAMESPACE_ - -typedef struct { - void **result; - int max_depth; - int skip_count; - int count; -} trace_arg_t; - - -// Workaround for the malloc() in _Unwind_Backtrace() issue. -static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) { - return _URC_NO_REASON; -} - - -// This code is not considered ready to run until -// static initializers run so that we are guaranteed -// that any malloc-related initialization is done. -static bool ready_to_run = false; -class StackTraceInit { - public: - StackTraceInit() { - // Extra call to force initialization - _Unwind_Backtrace(nop_backtrace, NULL); - ready_to_run = true; - } -}; - -static StackTraceInit module_initializer; // Force initialization - -static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) { - trace_arg_t *targ = (trace_arg_t *) opq; - - if (targ->skip_count > 0) { - targ->skip_count--; - } else { - targ->result[targ->count++] = (void *) _Unwind_GetIP(uc); - } - - if (targ->count == targ->max_depth) - return _URC_END_OF_STACK; - - return _URC_NO_REASON; -} - -// If you change this function, also change GetStackFrames below. -int GetStackTrace(void** result, int max_depth, int skip_count) { - if (!ready_to_run) - return 0; - - trace_arg_t targ; - - skip_count += 1; // Do not include the "GetStackTrace" frame - - targ.result = result; - targ.max_depth = max_depth; - targ.skip_count = skip_count; - targ.count = 0; - - _Unwind_Backtrace(GetOneFrame, &targ); - - return targ.count; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/stl_logging_unittest.cc b/third_party/src/glog/src/stl_logging_unittest.cc deleted file mode 100644 index 5dcbc447..00000000 --- a/third_party/src/glog/src/stl_logging_unittest.cc +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2003, 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. - -#include "config.h" - -#ifdef HAVE_USING_OPERATOR - -#include "glog/stl_logging.h" - -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -# include -# include -#endif - -#include "glog/logging.h" -#include "googletest.h" - -using namespace std; -#ifdef __GNUC__ -using namespace __gnu_cxx; -#endif - -struct user_hash { - size_t operator()(int x) const { return x; } -}; - -void TestSTLLogging() { - { - // Test a sequence. - vector v; - v.push_back(10); - v.push_back(20); - v.push_back(30); - ostringstream ss; - ss << v; - EXPECT_EQ(ss.str(), "10 20 30"); - vector copied_v(v); - CHECK_EQ(v, copied_v); // This must compile. - } - - { - // Test a sorted pair associative container. - map< int, string > m; - m[20] = "twenty"; - m[10] = "ten"; - m[30] = "thirty"; - ostringstream ss; - ss << m; - EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)"); - map< int, string > copied_m(m); - CHECK_EQ(m, copied_m); // This must compile. - } - -#ifdef __GNUC__ - { - // Test a hashed simple associative container. - hash_set hs; - hs.insert(10); - hs.insert(20); - hs.insert(30); - ostringstream ss; - ss << hs; - EXPECT_EQ(ss.str(), "10 20 30"); - hash_set copied_hs(hs); - CHECK_EQ(hs, copied_hs); // This must compile. - } -#endif - -#ifdef __GNUC__ - { - // Test a hashed pair associative container. - hash_map hm; - hm[10] = "ten"; - hm[20] = "twenty"; - hm[30] = "thirty"; - ostringstream ss; - ss << hm; - EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)"); - hash_map copied_hm(hm); - CHECK_EQ(hm, copied_hm); // this must compile - } -#endif - - { - // Test a long sequence. - vector v; - string expected; - for (int i = 0; i < 100; i++) { - v.push_back(i); - if (i > 0) expected += ' '; - char buf[256]; - sprintf(buf, "%d", i); - expected += buf; - } - v.push_back(100); - expected += " ..."; - ostringstream ss; - ss << v; - CHECK_EQ(ss.str(), expected.c_str()); - } - - { - // Test a sorted pair associative container. - // Use a non-default comparison functor. - map< int, string, greater > m; - m[20] = "twenty"; - m[10] = "ten"; - m[30] = "thirty"; - ostringstream ss; - ss << m; - EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)"); - map< int, string, greater > copied_m(m); - CHECK_EQ(m, copied_m); // This must compile. - } - -#ifdef __GNUC__ - { - // Test a hashed simple associative container. - // Use a user defined hash function. - hash_set hs; - hs.insert(10); - hs.insert(20); - hs.insert(30); - ostringstream ss; - ss << hs; - EXPECT_EQ(ss.str(), "10 20 30"); - hash_set copied_hs(hs); - CHECK_EQ(hs, copied_hs); // This must compile. - } -#endif -} - -int main(int, char**) { - TestSTLLogging(); - std::cout << "PASS\n"; - return 0; -} - -#else - -#include - -int main(int, char**) { - std::cout << "We don't support stl_logging for this compiler.\n" - << "(we need compiler support of 'using ::operator<<' " - << "for this feature.)\n"; - return 0; -} - -#endif // HAVE_USING_OPERATOR diff --git a/third_party/src/glog/src/symbolize.cc b/third_party/src/glog/src/symbolize.cc deleted file mode 100644 index 157c5253..00000000 --- a/third_party/src/glog/src/symbolize.cc +++ /dev/null @@ -1,681 +0,0 @@ -// 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 -// Stack-footprint reduction work done by Raksit Ashok -// -// Implementation note: -// -// We don't use heaps but only use stacks. We want to reduce the -// stack consumption so that the symbolizer can run on small stacks. -// -// Here are some numbers collected with GCC 4.1.0 on x86: -// - sizeof(Elf32_Sym) = 16 -// - sizeof(Elf32_Shdr) = 40 -// - sizeof(Elf64_Sym) = 24 -// - sizeof(Elf64_Shdr) = 64 -// -// This implementation is intended to be async-signal-safe but uses -// some functions which are not guaranteed to be so, such as memchr() -// and memmove(). We assume they are async-signal-safe. -// - -#include "utilities.h" - -#if defined(HAVE_SYMBOLIZE) - -#include - -#include "symbolize.h" -#include "demangle.h" - -_START_GOOGLE_NAMESPACE_ - -// We don't use assert() since it's not guaranteed to be -// async-signal-safe. Instead we define a minimal assertion -// macro. So far, we don't need pretty printing for __FILE__, etc. - -// A wrapper for abort() to make it callable in ? :. -static int AssertFail() { - abort(); - return 0; // Should not reach. -} - -#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail()) - -static SymbolizeCallback g_symbolize_callback = NULL; -void InstallSymbolizeCallback(SymbolizeCallback callback) { - g_symbolize_callback = callback; -} - -// This function wraps the Demangle function to provide an interface -// where the input symbol is demangled in-place. -// To keep stack consumption low, we would like this function to not -// get inlined. -static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) { - char demangled[256]; // Big enough for sane demangled symbols. - if (Demangle(out, demangled, sizeof(demangled))) { - // Demangling succeeded. Copy to out if the space allows. - size_t len = strlen(demangled); - if (len + 1 <= (size_t)out_size) { // +1 for '\0'. - SAFE_ASSERT(len < sizeof(demangled)); - memmove(out, demangled, len + 1); - } - } -} - -_END_GOOGLE_NAMESPACE_ - -#if defined(__ELF__) - -#include -#include -#include -#include -#include -#include // For ElfW() macro. -#include -#include -#include -#include -#include -#include -#include -#include - -#include "symbolize.h" -#include "config.h" -#include "glog/raw_logging.h" - -// Re-runs fn until it doesn't cause EINTR. -#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR) - -_START_GOOGLE_NAMESPACE_ - -// Read up to "count" bytes from file descriptor "fd" into the buffer -// starting at "buf" while handling short reads and EINTR. On -// success, return the number of bytes read. Otherwise, return -1. -static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) { - SAFE_ASSERT(fd >= 0); - SAFE_ASSERT(count >= 0 && count <= std::numeric_limits::max()); - char *buf0 = reinterpret_cast(buf); - ssize_t num_bytes = 0; - while (num_bytes < count) { - ssize_t len; - NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes)); - if (len < 0) { // There was an error other than EINTR. - return -1; - } - if (len == 0) { // Reached EOF. - break; - } - num_bytes += len; - } - SAFE_ASSERT(num_bytes <= count); - return num_bytes; -} - -// Read up to "count" bytes from "offset" in the file pointed by file -// descriptor "fd" into the buffer starting at "buf". On success, -// return the number of bytes read. Otherwise, return -1. -static ssize_t ReadFromOffset(const int fd, void *buf, - const size_t count, const off_t offset) { - off_t off = lseek(fd, offset, SEEK_SET); - if (off == (off_t)-1) { - return -1; - } - return ReadPersistent(fd, buf, count); -} - -// Try reading exactly "count" bytes from "offset" bytes in a file -// pointed by "fd" into the buffer starting at "buf" while handling -// short reads and EINTR. On success, return true. Otherwise, return -// false. -static bool ReadFromOffsetExact(const int fd, void *buf, - const size_t count, const off_t offset) { - ssize_t len = ReadFromOffset(fd, buf, count, offset); - return len == count; -} - -// Returns elf_header.e_type if the file pointed by fd is an ELF binary. -static int FileGetElfType(const int fd) { - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return -1; - } - if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) { - return -1; - } - return elf_header.e_type; -} - -// Read the section headers in the given ELF binary, and if a section -// of the specified type is found, set the output to this section header -// and return true. Otherwise, return false. -// To keep stack consumption low, we would like this function to not get -// inlined. -static ATTRIBUTE_NOINLINE bool -GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_t sh_offset, - ElfW(Word) type, ElfW(Shdr) *out) { - // Read at most 16 section headers at a time to save read calls. - ElfW(Shdr) buf[16]; - for (int i = 0; i < sh_num;) { - const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); - const ssize_t num_bytes_to_read = - (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf); - const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, - sh_offset + i * sizeof(buf[0])); - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_headers_in_buf = len / sizeof(buf[0]); - SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); - for (int j = 0; j < num_headers_in_buf; ++j) { - if (buf[j].sh_type == type) { - *out = buf[j]; - return true; - } - } - i += num_headers_in_buf; - } - return false; -} - -// There is no particular reason to limit section name to 63 characters, -// but there has (as yet) been no need for anything longer either. -const int kMaxSectionNameLen = 64; - -// name_len should include terminating '\0'. -bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, - ElfW(Shdr) *out) { - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return false; - } - - ElfW(Shdr) shstrtab; - off_t shstrtab_offset = (elf_header.e_shoff + - elf_header.e_shentsize * elf_header.e_shstrndx); - if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { - return false; - } - - for (int i = 0; i < elf_header.e_shnum; ++i) { - off_t section_header_offset = (elf_header.e_shoff + - elf_header.e_shentsize * i); - if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) { - return false; - } - char header_name[kMaxSectionNameLen]; - if (sizeof(header_name) < name_len) { - RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS"); " - "section will not be found (even if present).", name, name_len); - // No point in even trying. - return false; - } - off_t name_offset = shstrtab.sh_offset + out->sh_name; - ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset); - if (n_read == -1) { - return false; - } else if (n_read != name_len) { - // Short read -- name could be at end of file. - continue; - } - if (memcmp(header_name, name, name_len) == 0) { - return true; - } - } - return false; -} - -// Read a symbol table and look for the symbol containing the -// pc. Iterate over symbols in a symbol table and look for the symbol -// containing "pc". On success, return true and write the symbol name -// to out. Otherwise, return false. -// To keep stack consumption low, we would like this function to not get -// inlined. -static ATTRIBUTE_NOINLINE bool -FindSymbol(uint64_t pc, const int fd, char *out, int out_size, - uint64_t symbol_offset, const ElfW(Shdr) *strtab, - const ElfW(Shdr) *symtab) { - if (symtab == NULL) { - return false; - } - const int num_symbols = symtab->sh_size / symtab->sh_entsize; - for (int i = 0; i < num_symbols;) { - off_t offset = symtab->sh_offset + i * symtab->sh_entsize; - - // If we are reading Elf64_Sym's, we want to limit this array to - // 32 elements (to keep stack consumption low), otherwise we can - // have a 64 element Elf32_Sym array. -#if __WORDSIZE == 64 -#define NUM_SYMBOLS 32 -#else -#define NUM_SYMBOLS 64 -#endif - - // Read at most NUM_SYMBOLS symbols at once to save read() calls. - ElfW(Sym) buf[NUM_SYMBOLS]; - const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset); - SAFE_ASSERT(len % sizeof(buf[0]) == 0); - const ssize_t num_symbols_in_buf = len / sizeof(buf[0]); - SAFE_ASSERT(num_symbols_in_buf <= sizeof(buf)/sizeof(buf[0])); - for (int j = 0; j < num_symbols_in_buf; ++j) { - const ElfW(Sym)& symbol = buf[j]; - uint64_t start_address = symbol.st_value; - start_address += symbol_offset; - uint64_t end_address = start_address + symbol.st_size; - if (symbol.st_value != 0 && // Skip null value symbols. - symbol.st_shndx != 0 && // Skip undefined symbols. - start_address <= pc && pc < end_address) { - ssize_t len1 = ReadFromOffset(fd, out, out_size, - strtab->sh_offset + symbol.st_name); - if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) { - return false; - } - return true; // Obtained the symbol name. - } - } - i += num_symbols_in_buf; - } - return false; -} - -// Get the symbol name of "pc" from the file pointed by "fd". Process -// both regular and dynamic symbol tables if necessary. On success, -// write the symbol name to "out" and return true. Otherwise, return -// false. -static bool GetSymbolFromObjectFile(const int fd, uint64_t pc, - char *out, int out_size, - uint64_t map_start_address) { - // Read the ELF header. - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return false; - } - - uint64_t symbol_offset = 0; - if (elf_header.e_type == ET_DYN) { // DSO needs offset adjustment. - symbol_offset = map_start_address; - } - - ElfW(Shdr) symtab, strtab; - - // Consult a regular symbol table first. - if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, - SHT_SYMTAB, &symtab)) { - return false; - } - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, symbol_offset, - &strtab, &symtab)) { - return true; // Found the symbol in a regular symbol table. - } - - // If the symbol is not found, then consult a dynamic symbol table. - if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, - SHT_DYNSYM, &symtab)) { - return false; - } - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, symbol_offset, - &strtab, &symtab)) { - return true; // Found the symbol in a dynamic symbol table. - } - - return false; -} - -namespace { -// Thin wrapper around a file descriptor so that the file descriptor -// gets closed for sure. -struct FileDescriptor { - const int fd_; - explicit FileDescriptor(int fd) : fd_(fd) {} - ~FileDescriptor() { - if (fd_ >= 0) { - NO_INTR(close(fd_)); - } - } - int get() { return fd_; } - - private: - explicit FileDescriptor(const FileDescriptor&); - void operator=(const FileDescriptor&); -}; - -// Helper class for reading lines from file. -// -// Note: we don't use ProcMapsIterator since the object is big (it has -// a 5k array member) and uses async-unsafe functions such as sscanf() -// and snprintf(). -class LineReader { - public: - explicit LineReader(int fd, char *buf, int buf_len) : fd_(fd), - buf_(buf), buf_len_(buf_len), bol_(buf), eol_(buf), eod_(buf) { - } - - // Read '\n'-terminated line from file. On success, modify "bol" - // and "eol", then return true. Otherwise, return false. - // - // Note: if the last line doesn't end with '\n', the line will be - // dropped. It's an intentional behavior to make the code simple. - bool ReadLine(const char **bol, const char **eol) { - if (BufferIsEmpty()) { // First time. - const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_); - if (num_bytes <= 0) { // EOF or error. - return false; - } - eod_ = buf_ + num_bytes; - bol_ = buf_; - } else { - bol_ = eol_ + 1; // Advance to the next line in the buffer. - SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". - if (!HasCompleteLine()) { - const int incomplete_line_length = eod_ - bol_; - // Move the trailing incomplete line to the beginning. - memmove(buf_, bol_, incomplete_line_length); - // Read text from file and append it. - char * const append_pos = buf_ + incomplete_line_length; - const int capacity_left = buf_len_ - incomplete_line_length; - const ssize_t num_bytes = ReadPersistent(fd_, append_pos, - capacity_left); - if (num_bytes <= 0) { // EOF or error. - return false; - } - eod_ = append_pos + num_bytes; - bol_ = buf_; - } - } - eol_ = FindLineFeed(); - if (eol_ == NULL) { // '\n' not found. Malformed line. - return false; - } - *eol_ = '\0'; // Replace '\n' with '\0'. - - *bol = bol_; - *eol = eol_; - return true; - } - - // Beginning of line. - const char *bol() { - return bol_; - } - - // End of line. - const char *eol() { - return eol_; - } - - private: - explicit LineReader(const LineReader&); - void operator=(const LineReader&); - - char *FindLineFeed() { - return reinterpret_cast(memchr(bol_, '\n', eod_ - bol_)); - } - - bool BufferIsEmpty() { - return buf_ == eod_; - } - - bool HasCompleteLine() { - return !BufferIsEmpty() && FindLineFeed() != NULL; - } - - const int fd_; - char * const buf_; - const int buf_len_; - char *bol_; - char *eol_; - const char *eod_; // End of data in "buf_". -}; -} // namespace - -// Place the hex number read from "start" into "*hex". The pointer to -// the first non-hex character or "end" is returned. -static char *GetHex(const char *start, const char *end, uint64_t *hex) { - *hex = 0; - const char *p; - for (p = start; p < end; ++p) { - int ch = *p; - if ((ch >= '0' && ch <= '9') || - (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { - *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9); - } else { // Encountered the first non-hex character. - break; - } - } - SAFE_ASSERT(p <= end); - return const_cast(p); -} - -// Search for the object file (from /proc/self/maps) that contains -// the specified pc. If found, open this file and return the file handle, -// and also set start_address to the start address of where this object -// file is mapped to in memory. Otherwise, return -1. -static ATTRIBUTE_NOINLINE int -OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, - uint64_t &start_address) { - int object_fd; - - // Open /proc/self/maps. - int maps_fd; - NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY)); - FileDescriptor wrapped_maps_fd(maps_fd); - if (wrapped_maps_fd.get() < 0) { - return -1; - } - - // Iterate over maps and look for the map containing the pc. Then - // look into the symbol tables inside. - char buf[1024]; // Big enough for line of sane /proc/self/maps - LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf)); - while (true) { - const char *cursor; - const char *eol; - if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line. - return -1; - } - - // Start parsing line in /proc/self/maps. Here is an example: - // - // 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat - // - // We want start address (08048000), end address (0804c000), flags - // (r-xp) and file name (/bin/cat). - - // Read start address. - cursor = GetHex(cursor, eol, &start_address); - if (cursor == eol || *cursor != '-') { - return -1; // Malformed line. - } - ++cursor; // Skip '-'. - - // Read end address. - uint64_t end_address; - cursor = GetHex(cursor, eol, &end_address); - if (cursor == eol || *cursor != ' ') { - return -1; // Malformed line. - } - ++cursor; // Skip ' '. - - // Check start and end addresses. - if (!(start_address <= pc && pc < end_address)) { - continue; // We skip this map. PC isn't in this map. - } - - // Read flags. Skip flags until we encounter a space or eol. - const char * const flags_start = cursor; - while (cursor < eol && *cursor != ' ') { - ++cursor; - } - // We expect at least four letters for flags (ex. "r-xp"). - if (cursor == eol || cursor < flags_start + 4) { - return -1; // Malformed line. - } - - // Check flags. We are only interested in "r-x" maps. - if (memcmp(flags_start, "r-x", 3) != 0) { // Not a "r-x" map. - continue; // We skip this map. - } - ++cursor; // Skip ' '. - - // Skip to file name. "cursor" now points to file offset. We need to - // skip at least three spaces for file offset, dev, and inode. - int num_spaces = 0; - while (cursor < eol) { - if (*cursor == ' ') { - ++num_spaces; - } else if (num_spaces >= 3) { - // The first non-space character after skipping three spaces - // is the beginning of the file name. - break; - } - ++cursor; - } - if (cursor == eol) { - return -1; // Malformed line. - } - - // Finally, "cursor" now points to file name of our interest. - NO_INTR(object_fd = open(cursor, O_RDONLY)); - if (object_fd < 0) { - return -1; - } - return object_fd; - } -} - -// The implementation of our symbolization routine. If it -// successfully finds the symbol containing "pc" and obtains the -// symbol name, returns true and write the symbol name to "out". -// Otherwise, returns false. If Callback function is installed via -// InstallSymbolizeCallback(), the function is also called in this function, -// and "out" is used as its output. -// To keep stack consumption low, we would like this function to not -// get inlined. -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - uint64_t pc0 = reinterpret_cast(pc); - uint64_t start_address = 0; - - int object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, - start_address); - if (object_fd == -1) { - return false; - } - FileDescriptor wrapped_object_fd(object_fd); - int elf_type = FileGetElfType(wrapped_object_fd.get()); - if (elf_type == -1) { - return false; - } - if (g_symbolize_callback) { - // Run the call back if it's installed. - // Note: relocation (and much of the rest of this code) will be - // wrong for prelinked shared libraries and PIE executables. - uint64 relocation = (elf_type == ET_DYN) ? start_address : 0; - int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(), - pc, out, out_size, - relocation); - if (num_bytes_written > 0) { - out += num_bytes_written; - out_size -= num_bytes_written; - } - } - if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, - out, out_size, start_address)) { - return false; - } - - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; -} - -_END_GOOGLE_NAMESPACE_ - -#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) - -#include -#include - -_START_GOOGLE_NAMESPACE_ - -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - Dl_info info; - if (dladdr(pc, &info)) { - if ((int)strlen(info.dli_sname) < out_size) { - strcpy(out, info.dli_sname); - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; - } - } - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#else -# error BUG: HAVE_SYMBOLIZE was wrongly set -#endif - -_START_GOOGLE_NAMESPACE_ - -bool Symbolize(void *pc, char *out, int out_size) { - SAFE_ASSERT(out_size >= 0); - return SymbolizeAndDemangle(pc, out, out_size); -} - -_END_GOOGLE_NAMESPACE_ - -#else /* HAVE_SYMBOLIZE */ - -#include - -#include "config.h" - -_START_GOOGLE_NAMESPACE_ - -// TODO: Support other environments. -bool Symbolize(void *pc, char *out, int out_size) { - assert(0); - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#endif diff --git a/third_party/src/glog/src/symbolize.h b/third_party/src/glog/src/symbolize.h deleted file mode 100644 index 1ebe4dd9..00000000 --- a/third_party/src/glog/src/symbolize.h +++ /dev/null @@ -1,116 +0,0 @@ -// 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 -// -// This library provides Symbolize() function that symbolizes program -// counters to their corresponding symbol names on linux platforms. -// This library has a minimal implementation of an ELF symbol table -// reader (i.e. it doesn't depend on libelf, etc.). -// -// The algorithm used in Symbolize() is as follows. -// -// 1. Go through a list of maps in /proc/self/maps and find the map -// containing the program counter. -// -// 2. Open the mapped file and find a regular symbol table inside. -// Iterate over symbols in the symbol table and look for the symbol -// containing the program counter. If such a symbol is found, -// obtain the symbol name, and demangle the symbol if possible. -// If the symbol isn't found in the regular symbol table (binary is -// stripped), try the same thing with a dynamic symbol table. -// -// Note that Symbolize() is originally implemented to be used in -// FailureSignalHandler() in base/google.cc. Hence it doesn't use -// malloc() and other unsafe operations. It should be both -// thread-safe and async-signal-safe. - -#ifndef BASE_SYMBOLIZE_H_ -#define BASE_SYMBOLIZE_H_ - -#include "utilities.h" -#include "config.h" -#include "glog/logging.h" - -#ifdef HAVE_SYMBOLIZE - -#if defined(__ELF__) // defined by gcc on Linux -#include -#include // For ElfW() macro. - -// If there is no ElfW macro, let's define it by ourself. -#ifndef ElfW -# if SIZEOF_VOID_P == 4 -# define ElfW(type) Elf32_##type -# elif SIZEOF_VOID_P == 8 -# define ElfW(type) Elf64_##type -# else -# error "Unknown sizeof(void *)" -# endif -#endif - -_START_GOOGLE_NAMESPACE_ - -// Gets the section header for the given name, if it exists. Returns true on -// success. Otherwise, returns false. -bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, - ElfW(Shdr) *out); - -_END_GOOGLE_NAMESPACE_ - -#endif /* __ELF__ */ - -_START_GOOGLE_NAMESPACE_ - -// Installs a callback function, which will be called right before a symbol name -// is printed. The callback is intended to be used for showing a file name and a -// line number preceding a symbol name. -// "fd" is a file descriptor of the object file containing the program -// counter "pc". The callback function should write output to "out" -// and return the size of the output written. On error, the callback -// function should return -1. -typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size, - uint64 relocation); -void InstallSymbolizeCallback(SymbolizeCallback callback); - -_END_GOOGLE_NAMESPACE_ - -#endif - -_START_GOOGLE_NAMESPACE_ - -// Symbolizes a program counter. On success, returns true and write the -// symbol name to "out". The symbol name is demangled if possible -// (supports symbols generated by GCC 3.x or newer). Otherwise, -// returns false. -bool Symbolize(void *pc, char *out, int out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_SYMBOLIZE_H_ diff --git a/third_party/src/glog/src/symbolize_unittest.cc b/third_party/src/glog/src/symbolize_unittest.cc deleted file mode 100644 index f25909d1..00000000 --- a/third_party/src/glog/src/symbolize_unittest.cc +++ /dev/null @@ -1,365 +0,0 @@ -// 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 -#include - -#include "glog/logging.h" -#include "symbolize.h" -#include "googletest.h" -#include "config.h" - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -#if defined(HAVE_STACKTRACE) && defined(__ELF__) - -#define always_inline - -// This unit tests make sense only with GCC. -// Uses lots of GCC specific features. -#if defined(__GNUC__) && !defined(__OPENCC__) -# if __GNUC__ >= 4 -# define TEST_WITH_MODERN_GCC -# if __i386__ // always_inline isn't supported for x86_64 with GCC 4.1.0. -# undef always_inline -# define always_inline __attribute__((always_inline)) -# define HAVE_ALWAYS_INLINE -# endif // __i386__ -# else -# endif // __GNUC__ >= 4 -# if defined(__i386__) || defined(__x86_64__) -# define TEST_X86_32_AND_64 1 -# 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() { - volatile int a = 0; - ++a; -} - -static void static_func() { - volatile int a = 0; - ++a; -} -} - -TEST(Symbolize, Symbolize) { - // We do C-style cast since GCC 2.95.3 doesn't allow - // reinterpret_cast(&func). - - // Compilers should give us pointers to them. - EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); - EXPECT_STREQ("static_func", TrySymbolize((void *)(&static_func))); - - EXPECT_TRUE(NULL == TrySymbolize(NULL)); -} - -struct Foo { - static void func(int x); -}; - -void ATTRIBUTE_NOINLINE Foo::func(int x) { - volatile int a = x; - ++a; -} - -// With a modern GCC, Symbolize() should return demangled symbol -// names. Function parameters should be omitted. -#ifdef TEST_WITH_MODERN_GCC -TEST(Symbolize, SymbolizeWithDemangling) { - Foo::func(100); - EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func))); -} -#endif - -// Tests that verify that Symbolize footprint is within some limit. - -// To measure the stack footprint of the Symbolize function, we create -// a signal handler (for SIGUSR1 say) that calls the Symbolize function -// on an alternate stack. This alternate stack is initialized to some -// known pattern (0x55, 0x55, 0x55, ...). We then self-send this signal, -// and after the signal handler returns, look at the alternate stack -// buffer to see what portion has been touched. -// -// This trick gives us the the stack footprint of the signal handler. -// But the signal handler, even before the call to Symbolize, consumes -// some stack already. We however only want the stack usage of the -// Symbolize function. To measure this accurately, we install two signal -// handlers: one that does nothing and just returns, and another that -// calls Symbolize. The difference between the stack consumption of these -// two signals handlers should give us the Symbolize stack foorprint. - -static void *g_pc_to_symbolize; -static char g_symbolize_buffer[4096]; -static char *g_symbolize_result; - -static void EmptySignalHandler(int signo) {} - -static void SymbolizeSignalHandler(int signo) { - if (Symbolize(g_pc_to_symbolize, g_symbolize_buffer, - sizeof(g_symbolize_buffer))) { - g_symbolize_result = g_symbolize_buffer; - } else { - g_symbolize_result = NULL; - } -} - -const int kAlternateStackSize = 8096; -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 ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) { - int y; - return &y < x; -} -static int GetStackConsumption(const char* alt_stack) { - int x; - if (StackGrowsDown(&x)) { - for (int i = 0; i < kAlternateStackSize; i++) { - if (alt_stack[i] != kAlternateStackFillValue) { - return (kAlternateStackSize - i); - } - } - } else { - for (int i = (kAlternateStackSize - 1); i >= 0; i--) { - if (alt_stack[i] != kAlternateStackFillValue) { - return i; - } - } - } - return -1; -} - -#ifdef HAVE_SIGALTSTACK - -// Call Symbolize and figure out the stack footprint of this call. -static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) { - - g_pc_to_symbolize = pc; - - // The alt-signal-stack cannot be heap allocated because there is a - // bug in glibc-2.2 where some signal handler setup code looks at the - // current stack pointer to figure out what thread is currently running. - // Therefore, the alternate stack must be allocated from the main stack - // itself. - char altstack[kAlternateStackSize]; - memset(altstack, kAlternateStackFillValue, kAlternateStackSize); - - // Set up the alt-signal-stack (and save the older one). - stack_t sigstk; - memset(&sigstk, 0, sizeof(stack_t)); - stack_t old_sigstk; - sigstk.ss_sp = altstack; - sigstk.ss_size = kAlternateStackSize; - sigstk.ss_flags = 0; - CHECK_ERR(sigaltstack(&sigstk, &old_sigstk)); - - // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones). - struct sigaction sa; - memset(&sa, 0, sizeof(struct sigaction)); - struct sigaction old_sa1, old_sa2; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK; - - // SIGUSR1 maps to EmptySignalHandler. - sa.sa_handler = EmptySignalHandler; - CHECK_ERR(sigaction(SIGUSR1, &sa, &old_sa1)); - - // SIGUSR2 maps to SymbolizeSignalHanlder. - sa.sa_handler = SymbolizeSignalHandler; - CHECK_ERR(sigaction(SIGUSR2, &sa, &old_sa2)); - - // Send SIGUSR1 signal and measure the stack consumption of the empty - // signal handler. - CHECK_ERR(kill(getpid(), SIGUSR1)); - int stack_consumption1 = GetStackConsumption(altstack); - - // Send SIGUSR2 signal and measure the stack consumption of the symbolize - // signal handler. - CHECK_ERR(kill(getpid(), SIGUSR2)); - int stack_consumption2 = GetStackConsumption(altstack); - - // The difference between the two stack consumption values is the - // stack footprint of the Symbolize function. - if (stack_consumption1 != -1 && stack_consumption2 != -1) { - *stack_consumed = stack_consumption2 - stack_consumption1; - } else { - *stack_consumed = -1; - } - - // Log the stack consumption values. - LOG(INFO) << "Stack consumption of empty signal handler: " - << stack_consumption1; - LOG(INFO) << "Stack consumption of symbolize signal handler: " - << stack_consumption2; - LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed; - - // Now restore the old alt-signal-stack and signal handlers. - CHECK_ERR(sigaltstack(&old_sigstk, NULL)); - CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL)); - CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL)); - - return g_symbolize_result; -} - -// Symbolize stack consumption should be within 2kB. -const int kStackConsumptionUpperLimit = 2048; - -TEST(Symbolize, SymbolizeStackConsumption) { - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption((void *)(&nonstatic_func), - &stack_consumed); - EXPECT_STREQ("nonstatic_func", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); - - symbol = SymbolizeStackConsumption((void *)(&static_func), - &stack_consumed); - EXPECT_STREQ("static_func", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); -} - -#ifdef TEST_WITH_MODERN_GCC -TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) { - Foo::func(100); - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption((void *)(&Foo::func), &stack_consumed); - - EXPECT_STREQ("Foo::func()", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); -} -#endif - -#endif // HAVE_SIGALTSTACK - -// x86 specific tests. Uses some inline assembler. -extern "C" { -inline void* always_inline inline_func() { - register void *pc = NULL; -#ifdef TEST_X86_32_AND_64 - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); -#endif - return pc; -} - -void* ATTRIBUTE_NOINLINE non_inline_func() { - register void *pc = NULL; -#ifdef TEST_X86_32_AND_64 - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); -#endif - return pc; -} - -void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() { -#if defined(TEST_X86_32_AND_64) && defined(HAVE_ATTRIBUTE_NOINLINE) - void *pc = non_inline_func(); - const char *symbol = TrySymbolize(pc); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "non_inline_func"); - cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl; -#endif -} - -void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() { -#if defined(TEST_X86_32_AND_64) && defined(HAVE_ALWAYS_INLINE) - void *pc = inline_func(); // Must be inlined. - const char *symbol = TrySymbolize(pc); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, __FUNCTION__); - cout << "Test case TestWithPCInsideInlineFunction passed." << endl; -#endif -} -} - -// Test with a return address. -void ATTRIBUTE_NOINLINE TestWithReturnAddress() { -#if defined(HAVE_ATTRIBUTE_NOINLINE) - void *return_address = __builtin_return_address(0); - const char *symbol = TrySymbolize(return_address); - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "main"); - cout << "Test case TestWithReturnAddress passed." << endl; -#endif -} - -int main(int argc, char **argv) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - InitGoogleTest(&argc, argv); -#ifdef HAVE_SYMBOLIZE - // 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); - - TestWithPCInsideInlineFunction(); - TestWithPCInsideNonInlineFunction(); - TestWithReturnAddress(); - return RUN_ALL_TESTS(); -#else - return 0; -#endif -} - -#else -int main() { -#ifdef HAVE_SYMBOLIZE - printf("PASS (no symbolize_unittest support)\n"); -#else - printf("PASS (no symbolize support)\n"); -#endif - return 0; -} -#endif // HAVE_STACKTRACE diff --git a/third_party/src/glog/src/utilities.cc b/third_party/src/glog/src/utilities.cc deleted file mode 100644 index 8ec69d3f..00000000 --- a/third_party/src/glog/src/utilities.cc +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright (c) 2008, 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: Shinichiro Hamaji - -#include "utilities.h" - -#include -#include - -#include -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include -#if defined(HAVE_SYSCALL_H) -#include // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include // for syscall() -#endif -#ifdef HAVE_SYSLOG_H -# include -#endif - -#include "base/googleinit.h" - -using std::string; - -_START_GOOGLE_NAMESPACE_ - -static const char* g_program_invocation_short_name = NULL; -static pthread_t g_main_thread_id; - -_END_GOOGLE_NAMESPACE_ - -// The following APIs are all internal. -#ifdef HAVE_STACKTRACE - -#include "stacktrace.h" -#include "symbolize.h" -#include "base/commandlineflags.h" - -GLOG_DEFINE_bool(symbolize_stacktrace, true, - "Symbolize the stack trace in the tombstone"); - -_START_GOOGLE_NAMESPACE_ - -typedef void DebugWriter(const char*, void*); - -// The %p field width for printf() functions is two characters per byte. -// For some environments, add two extra bytes for the leading "0x". -static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*); - -static void DebugWriteToStderr(const char* data, void *) { - // This one is signal-safe. - if (write(STDERR_FILENO, data, strlen(data)) < 0) { - // Ignore errors. - } -} - -void DebugWriteToString(const char* data, void *arg) { - reinterpret_cast(arg)->append(data); -} - -#ifdef HAVE_SYMBOLIZE -// Print a program counter and its symbol name. -static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char tmp[1024]; - const char *symbol = "(unknown)"; - // Symbolizes the previous address of pc because pc may be in the - // next function. The overrun happens when the function ends with - // a call to a function annotated noreturn (e.g. CHECK). - if (Symbolize(reinterpret_cast(pc) - 1, tmp, sizeof(tmp))) { - symbol = tmp; - } - char buf[1024]; - snprintf(buf, sizeof(buf), "%s@ %*p %s\n", - prefix, kPrintfPointerFieldWidth, pc, symbol); - writerfn(buf, arg); -} -#endif - -static void DumpPC(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char buf[100]; - snprintf(buf, sizeof(buf), "%s@ %*p\n", - prefix, kPrintfPointerFieldWidth, pc); - writerfn(buf, arg); -} - -// Dump current stack trace as directed by writerfn -static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { - // Print stack trace - void* stack[32]; - int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1); - for (int i = 0; i < depth; i++) { -#if defined(HAVE_SYMBOLIZE) - if (FLAGS_symbolize_stacktrace) { - DumpPCAndSymbol(writerfn, arg, stack[i], " "); - } else { - DumpPC(writerfn, arg, stack[i], " "); - } -#else - DumpPC(writerfn, arg, stack[i], " "); -#endif - } -} - -static void DumpStackTraceAndExit() { - DumpStackTrace(1, DebugWriteToStderr, NULL); - - // Set the default signal handler for SIGABRT, to avoid invoking our - // own signal handler installed by InstallFailedSignalHandler(). - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(SIGABRT, &sig_action, NULL); - - abort(); -} - -_END_GOOGLE_NAMESPACE_ - -#endif // HAVE_STACKTRACE - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -const char* ProgramInvocationShortName() { - if (g_program_invocation_short_name != NULL) { - return g_program_invocation_short_name; - } else { - // TODO(hamaji): Use /proc/self/cmdline and so? - return "UNKNOWN"; - } -} - -bool IsGoogleLoggingInitialized() { - return g_program_invocation_short_name != NULL; -} - -bool is_default_thread() { - if (g_program_invocation_short_name == NULL) { - // InitGoogleLogging() not yet called, so unlikely to be in a different - // thread - return true; - } else { - return pthread_equal(pthread_self(), g_main_thread_id); - } -} - -#ifdef OS_WINDOWS -struct timeval { - long tv_sec, tv_usec; -}; - -// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd -// See COPYING for copyright information. -static int gettimeofday(struct timeval *tv, void* tz) { -#define EPOCHFILETIME (116444736000000000ULL) - FILETIME ft; - LARGE_INTEGER li; - uint64 tt; - - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - tt = (li.QuadPart - EPOCHFILETIME) / 10; - tv->tv_sec = tt / 1000000; - tv->tv_usec = tt % 1000000; - - return 0; -} -#endif - -int64 CycleClock_Now() { - // TODO(hamaji): temporary impementation - it might be too slow. - struct timeval tv; - gettimeofday(&tv, NULL); - return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; -} - -int64 UsecToCycles(int64 usec) { - return usec; -} - -WallTime WallTime_Now() { - // Now, cycle clock is retuning microseconds since the epoch. - return CycleClock_Now() * 0.000001; -} - -static int32 g_main_thread_pid = getpid(); -int32 GetMainThreadPid() { - return g_main_thread_pid; -} - -bool PidHasChanged() { - int32 pid = getpid(); - if (g_main_thread_pid == pid) { - return false; - } - g_main_thread_pid = pid; - return true; -} - -pid_t GetTID() { - // On Linux and MacOSX, we try to use gettid(). -#if defined OS_LINUX || defined OS_MACOSX -#ifndef __NR_gettid -#ifdef OS_MACOSX -#define __NR_gettid SYS_gettid -#elif ! defined __i386__ -#error "Must define __NR_gettid for non-x86 platforms" -#else -#define __NR_gettid 224 -#endif -#endif - static bool lacks_gettid = false; - if (!lacks_gettid) { - pid_t tid = syscall(__NR_gettid); - if (tid != -1) { - return tid; - } - // Technically, this variable has to be volatile, but there is a small - // performance penalty in accessing volatile variables and there should - // not be any serious adverse effect if a thread does not immediately see - // the value change to "true". - lacks_gettid = true; - } -#endif // OS_LINUX || OS_MACOSX - - // If gettid() could not be used, we use one of the following. -#if defined OS_LINUX - return getpid(); // Linux: getpid returns thread ID when gettid is absent -#elif defined OS_WINDOWS || defined OS_CYGWIN - return GetCurrentThreadId(); -#else - // If none of the techniques above worked, we use pthread_self(). - return (pid_t)(uintptr_t)pthread_self(); -#endif -} - -const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef OS_WINDOWS // Look for either path separator in Windows - if (!base) - base = strrchr(filepath, '\\'); -#endif - return base ? (base+1) : filepath; -} - -static string g_my_user_name; -const string& MyUserName() { - return g_my_user_name; -} -static void MyUserNameInitializer() { - // TODO(hamaji): Probably this is not portable. -#if defined(OS_WINDOWS) - const char* user = getenv("USERNAME"); -#else - const char* user = getenv("USER"); -#endif - if (user != NULL) { - g_my_user_name = user; - } else { - g_my_user_name = "invalid-user"; - } -} -REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()) - -#ifdef HAVE_STACKTRACE -void DumpStackTraceToString(string* stacktrace) { - DumpStackTrace(1, DebugWriteToString, stacktrace); -} -#endif - -// We use an atomic operation to prevent problems with calling CrashReason -// from inside the Mutex implementation (potentially through RAW_CHECK). -static const CrashReason* g_reason = 0; - -void SetCrashReason(const CrashReason* r) { - sync_val_compare_and_swap(&g_reason, - reinterpret_cast(0), - r); -} - -void InitGoogleLoggingUtilities(const char* argv0) { - CHECK(!IsGoogleLoggingInitialized()) - << "You called InitGoogleLogging() twice!"; - const char* slash = strrchr(argv0, '/'); -#ifdef OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); -#endif - g_program_invocation_short_name = slash ? slash + 1 : argv0; - g_main_thread_id = pthread_self(); - -#ifdef HAVE_STACKTRACE - InstallFailureFunction(&DumpStackTraceAndExit); -#endif -} - -void ShutdownGoogleLoggingUtilities() { - CHECK(IsGoogleLoggingInitialized()) - << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!"; - g_program_invocation_short_name = NULL; -#ifdef HAVE_SYSLOG_H - closelog(); -#endif -} - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -// Make an implementation of stacktrace compiled. -#ifdef STACKTRACE_H -# include STACKTRACE_H -#endif diff --git a/third_party/src/glog/src/utilities.h b/third_party/src/glog/src/utilities.h deleted file mode 100644 index 5f79968e..00000000 --- a/third_party/src/glog/src/utilities.h +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2008, 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: Shinichiro Hamaji -// -// Define utilties for glog internal usage. - -#ifndef UTILITIES_H__ -#define UTILITIES_H__ - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# define OS_WINDOWS -#elif defined(__CYGWIN__) || defined(__CYGWIN32__) -# define OS_CYGWIN -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define OS_LINUX -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) -# define OS_MACOSX -#elif defined(__FreeBSD__) -# define OS_FREEBSD -#elif defined(__NetBSD__) -# define OS_NETBSD -#elif defined(__OpenBSD__) -# define OS_OPENBSD -#else -// TODO(hamaji): Add other platforms. -#endif - -// printf macros for size_t, in the style of inttypes.h -#ifdef _LP64 -#define __PRIS_PREFIX "z" -#else -#define __PRIS_PREFIX -#endif - -// Use these macros after a % in a printf format string -// to get correct 32/64 bit behavior, like this: -// size_t size = records.size(); -// printf("%"PRIuS"\n", size); - -#define PRIdS __PRIS_PREFIX "d" -#define PRIxS __PRIS_PREFIX "x" -#define PRIuS __PRIS_PREFIX "u" -#define PRIXS __PRIS_PREFIX "X" -#define PRIoS __PRIS_PREFIX "o" - -#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE - -#include - -#if defined(OS_WINDOWS) -# include "port.h" -#endif - -#include "config.h" -#include "glog/logging.h" - -// There are three different ways we can try to get the stack trace: -// -// 1) The libunwind library. This is still in development, and as a -// separate library adds a new dependency, but doesn't need a frame -// pointer. It also doesn't call malloc. -// -// 2) Our hand-coded stack-unwinder. This depends on a certain stack -// layout, which is used by gcc (and those systems using a -// gcc-compatible ABI) on x86 systems, at least since gcc 2.95. -// It uses the frame pointer to do its work. -// -// 3) The gdb unwinder -- also the one used by the c++ exception code. -// It's obviously well-tested, but has a fatal flaw: it can call -// malloc() from the unwinder. This is a problem because we're -// trying to use the unwinder to instrument malloc(). -// -// Note: if you add a new implementation here, make sure it works -// correctly when GetStackTrace() is called with max_depth == 0. -// Some code may do that. - -#if defined(HAVE_LIB_UNWIND) -# define STACKTRACE_H "stacktrace_libunwind-inl.h" -#elif !defined(NO_FRAME_POINTER) -# if defined(__i386__) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_x86-inl.h" -# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H -# define STACKTRACE_H "stacktrace_x86_64-inl.h" -# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_powerpc-inl.h" -# endif -#endif - -#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H) -# define STACKTRACE_H "stacktrace_generic-inl.h" -#endif - -#if defined(STACKTRACE_H) -# define HAVE_STACKTRACE -#endif - -// defined by gcc -#if defined(__ELF__) && defined(OS_LINUX) -# define HAVE_SYMBOLIZE -#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) -// Use dladdr to symbolize. -# define HAVE_SYMBOLIZE -#endif - -#ifndef ARRAYSIZE -// There is a better way, but this is good enough for our purpose. -# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) -#endif - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NOINLINE __attribute__ ((noinline)) -# define HAVE_ATTRIBUTE_NOINLINE -#else -# define ATTRIBUTE_NOINLINE -#endif - -const char* ProgramInvocationShortName(); - -bool IsGoogleLoggingInitialized(); - -bool is_default_thread(); - -int64 CycleClock_Now(); - -int64 UsecToCycles(int64 usec); - -typedef double WallTime; -WallTime WallTime_Now(); - -int32 GetMainThreadPid(); -bool PidHasChanged(); - -pid_t GetTID(); - -const std::string& MyUserName(); - -// Get the part of filepath after the last path separator. -// (Doesn't modify filepath, contrary to basename() in libgen.h.) -const char* const_basename(const char* filepath); - -// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't -// defined, we try the CPU specific logics (we only support x86 and -// x86_64 for now) first, then use a naive implementation, which has a -// race condition. -template -inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) { -#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP) - return __sync_val_compare_and_swap(ptr, oldval, newval); -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - T ret; - __asm__ __volatile__("lock; cmpxchg %1, (%2);" - :"=a"(ret) - // GCC may produces %sil or %dil for - // constraint "r", but some of apple's gas - // dosn't know the 8 bit registers. - // We use "q" to avoid these registers. - :"q"(newval), "q"(ptr), "a"(oldval) - :"memory", "cc"); - return ret; -#else - T ret = *ptr; - if (ret == oldval) { - *ptr = newval; - } - return ret; -#endif -} - -void DumpStackTraceToString(std::string* stacktrace); - -struct CrashReason { - CrashReason() : filename(0), line_number(0), message(0), depth(0) {} - - const char* filename; - int line_number; - const char* message; - - // We'll also store a bit of stack trace context at the time of crash as - // it may not be available later on. - void* stack[32]; - int depth; -}; - -void SetCrashReason(const CrashReason* r); - -void InitGoogleLoggingUtilities(const char* argv0); -void ShutdownGoogleLoggingUtilities(); - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -using namespace GOOGLE_NAMESPACE::glog_internal_namespace_; - -#endif // UTILITIES_H__ diff --git a/third_party/src/glog/src/utilities_unittest.cc b/third_party/src/glog/src/utilities_unittest.cc deleted file mode 100644 index 7b796190..00000000 --- a/third_party/src/glog/src/utilities_unittest.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2008, 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: Shinichiro Hamaji - -#include "utilities.h" -#include "googletest.h" -#include "glog/logging.h" - -using namespace GOOGLE_NAMESPACE; - -TEST(utilities, sync_val_compare_and_swap) { - bool now_entering = false; - EXPECT_FALSE(sync_val_compare_and_swap(&now_entering, false, true)); - EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true)); - EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true)); -} - -TEST(utilities, InitGoogleLoggingDeathTest) { - ASSERT_DEATH(InitGoogleLogging("foobar"), ""); -} - -int main(int argc, char **argv) { - InitGoogleLogging(argv[0]); - InitGoogleTest(&argc, argv); - - CHECK_EQ(RUN_ALL_TESTS(), 0); -} diff --git a/third_party/src/glog/src/vlog_is_on.cc b/third_party/src/glog/src/vlog_is_on.cc deleted file mode 100644 index 8a79df50..00000000 --- a/third_party/src/glog/src/vlog_is_on.cc +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 1999, 2007, 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: Ray Sidney and many others -// -// Broken out from logging.cc by Soren Lassen -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include -#include -#include -#include -#include -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -// glog doesn't have annotation -#define ANNOTATE_BENIGN_RACE(address, description) - -using std::string; - -GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this." -" Overridable by --vmodule."); - -GLOG_DEFINE_string(vmodule, "", "per-module verbose level." -" Argument is a comma-separated list of =." -" is a glob pattern, matched against the filename base" -" (that is, name ignoring .cc/.h./-inl.h)." -" overrides any value given by --v."); - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -// Implementation of fnmatch that does not need 0-termination -// of arguments and does not allocate any memory, -// but we only support "*" and "?" wildcards, not the "[...]" patterns. -// It's not a static function for the unittest. -GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, - size_t patt_len, - const char* str, - size_t str_len) { - size_t p = 0; - size_t s = 0; - while (1) { - if (p == patt_len && s == str_len) return true; - if (p == patt_len) return false; - if (s == str_len) return p+1 == patt_len && pattern[p] == '*'; - if (pattern[p] == str[s] || pattern[p] == '?') { - p += 1; - s += 1; - continue; - } - if (pattern[p] == '*') { - if (p+1 == patt_len) return true; - do { - if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) { - return true; - } - s += 1; - } while (s != str_len); - return false; - } - return false; - } -} - -} // namespace glog_internal_namespace_ - -using glog_internal_namespace_::SafeFNMatch_; - -int32 kLogSiteUninitialized = 1000; - -// List of per-module log levels from FLAGS_vmodule. -// Once created each element is never deleted/modified -// except for the vlog_level: other threads will read VModuleInfo blobs -// w/o locks and we'll store pointers to vlog_level at VLOG locations -// that will never go away. -// We can't use an STL struct here as we wouldn't know -// when it's safe to delete/update it: other threads need to use it w/o locks. -struct VModuleInfo { - string module_pattern; - mutable int32 vlog_level; // Conceptually this is an AtomicWord, but it's - // too much work to use AtomicWord type here - // w/o much actual benefit. - const VModuleInfo* next; -}; - -// This protects the following global variables. -static Mutex vmodule_lock; -// Pointer to head of the VModuleInfo list. -// It's a map from module pattern to logging level for those module(s). -static VModuleInfo* vmodule_list = 0; -// Boolean initialization flag. -static bool inited_vmodule = false; - -// L >= vmodule_lock. -static void VLOG2Initializer() { - vmodule_lock.AssertHeld(); - // Can now parse --vmodule flag and initialize mapping of module-specific - // logging levels. - inited_vmodule = false; - const char* vmodule = FLAGS_vmodule.c_str(); - const char* sep; - VModuleInfo* head = NULL; - VModuleInfo* tail = NULL; - while ((sep = strchr(vmodule, '=')) != NULL) { - string pattern(vmodule, sep - vmodule); - int module_level; - if (sscanf(sep, "=%d", &module_level) == 1) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = pattern; - info->vlog_level = module_level; - if (head) tail->next = info; - else head = info; - tail = info; - } - // Skip past this entry - vmodule = strchr(sep, ','); - if (vmodule == NULL) break; - vmodule++; // Skip past "," - } - if (head) { // Put them into the list at the head: - tail->next = vmodule_list; - vmodule_list = head; - } - inited_vmodule = true; -} - -// This can be called very early, so we use SpinLock and RAW_VLOG here. -int SetVLOGLevel(const char* module_pattern, int log_level) { - int result = FLAGS_v; - int const pattern_len = strlen(module_pattern); - bool found = false; - MutexLock l(&vmodule_lock); // protect whole read-modify-write - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (info->module_pattern == module_pattern) { - if (!found) { - result = info->vlog_level; - found = true; - } - info->vlog_level = log_level; - } else if (!found && - SafeFNMatch_(info->module_pattern.c_str(), - info->module_pattern.size(), - module_pattern, pattern_len)) { - result = info->vlog_level; - found = true; - } - } - if (!found) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = module_pattern; - info->vlog_level = log_level; - info->next = vmodule_list; - vmodule_list = info; - } - RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level); - return result; -} - -// NOTE: Individual VLOG statements cache the integer log level pointers. -// NOTE: This function must not allocate memory or require any locks. -bool InitVLOG3__(int32** site_flag, int32* site_default, - const char* fname, int32 verbose_level) { - MutexLock l(&vmodule_lock); - bool read_vmodule_flag = inited_vmodule; - if (!read_vmodule_flag) { - VLOG2Initializer(); - } - - // protect the errno global in case someone writes: - // VLOG(..) << "The last error was " << strerror(errno) - int old_errno = errno; - - // site_default normally points to FLAGS_v - int32* site_flag_value = site_default; - - // Get basename for file - const char* base = strrchr(fname, '/'); - base = base ? (base+1) : fname; - const char* base_end = strchr(base, '.'); - size_t base_length = base_end ? size_t(base_end - base) : strlen(base); - - // Trim out trailing "-inl" if any - if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) { - base_length -= 4; - } - - // TODO: Trim out _unittest suffix? Perhaps it is better to have - // the extra control and just leave it there. - - // find target in vector of modules, replace site_flag_value with - // a module-specific verbose level, if any. - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(), - base, base_length)) { - site_flag_value = &info->vlog_level; - // value at info->vlog_level is now what controls - // the VLOG at the caller site forever - break; - } - } - - // Cache the vlog value pointer if --vmodule flag has been parsed. - ANNOTATE_BENIGN_RACE(site_flag, - "*site_flag may be written by several threads," - " but the value will be the same"); - if (read_vmodule_flag) *site_flag = site_flag_value; - - // restore the errno in case something recoverable went wrong during - // the initialization of the VLOG mechanism (see above note "protect the..") - errno = old_errno; - return *site_flag_value >= verbose_level; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/windows/base/commandlineflags.h b/third_party/src/glog/src/windows/base/commandlineflags.h deleted file mode 100644 index c8d50890..00000000 --- a/third_party/src/glog/src/windows/base/commandlineflags.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2008, 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. - -// --- -// This file is a compatibility layer that defines Google's version of -// command line flags that are used for configuration. -// -// We put flags into their own namespace. It is purposefully -// named in an opaque way that people should have trouble typing -// directly. The idea is that DEFINE puts the flag in the weird -// namespace, and DECLARE imports the flag from there into the -// current namespace. The net result is to force people to use -// DECLARE to get access to a flag, rather than saying -// extern bool FLAGS_logtostderr; -// or some such instead. We want this so we can put extra -// functionality (like sanity-checking) in DECLARE if we want, -// and make sure it is picked up everywhere. -// -// We also put the type of the variable in the namespace, so that -// people can't DECLARE_int32 something that they DEFINE_bool'd -// elsewhere. -#ifndef BASE_COMMANDLINEFLAGS_H__ -#define BASE_COMMANDLINEFLAGS_H__ - -#include "config.h" -#include -#include // for memchr -#include // for getenv - -#ifdef HAVE_LIB_GFLAGS - -#include - -#else - -#include "glog/logging.h" - -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name -#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \ - namespace fL##shorttype { \ - GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) -#define DEFINE_bool(name, value, meaning) \ - DEFINE_VARIABLE(bool, B, name, value, meaning, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32) -#define DEFINE_int32(name, value, meaning) \ - DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32) - -// Special case for string, because we have to specify the namespace -// std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace fLS { \ - extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#define DEFINE_string(name, value, meaning) \ - namespace fLS { \ - std::string FLAGS_##name##_buf(value); \ - GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \ - char FLAGS_no##name; \ - } \ - using fLS::FLAGS_##name - -#endif // HAVE_LIB_GFLAGS - -// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we -// have GLOG_* environ variables even if we have gflags installed. -// -// If both an environment variable and a flag are specified, the value -// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the -// verbosity will be 1, not 0. - -#define GLOG_DEFINE_bool(name, value, meaning) \ - DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_int32(name, value, meaning) \ - DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning) - -#define GLOG_DEFINE_string(name, value, meaning) \ - DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning) - -// These macros (could be functions, but I don't want to bother with a .cc -// file), make it easier to initialize flags from the environment. - -#define EnvToString(envname, dflt) \ - (!getenv(envname) ? (dflt) : getenv(envname)) - -#define EnvToBool(envname, dflt) \ - (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL) - -#define EnvToInt(envname, dflt) \ - (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10)) - -#endif // BASE_COMMANDLINEFLAGS_H__ diff --git a/third_party/src/glog/src/windows/base/googleinit.h b/third_party/src/glog/src/windows/base/googleinit.h deleted file mode 100644 index 5a8b515c..00000000 --- a/third_party/src/glog/src/windows/base/googleinit.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2008, 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: Jacob Hoffman-Andrews - -#ifndef _GOOGLEINIT_H -#define _GOOGLEINIT_H - -class GoogleInitializer { - public: - typedef void (*void_function)(void); - GoogleInitializer(const char*, void_function f) { - f(); - } -}; - -#define REGISTER_MODULE_INITIALIZER(name, body) \ - namespace { \ - static void google_init_module_##name () { body; } \ - GoogleInitializer google_initializer_module_##name(#name, \ - google_init_module_##name); \ - } - -#endif /* _GOOGLEINIT_H */ diff --git a/third_party/src/glog/src/windows/base/mutex.h b/third_party/src/glog/src/windows/base/mutex.h deleted file mode 100644 index 37527d58..00000000 --- a/third_party/src/glog/src/windows/base/mutex.h +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2007, 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: Craig Silverstein. -// -// A simple mutex wrapper, supporting locks and read-write locks. -// You should assume the locks are *not* re-entrant. -// -// To use: you should define the following macros in your configure.ac: -// ACX_PTHREAD -// AC_RWLOCK -// The latter is defined in ../autoconf. -// -// This class is meant to be internal-only and should be wrapped by an -// internal namespace. Before you use this module, please give the -// name of your internal namespace for this module. Or, if you want -// to expose it, you'll want to move it to the Google namespace. We -// cannot put this class in global namespace because there can be some -// problems when we have multiple versions of Mutex in each shared object. -// -// NOTE: by default, we have #ifdef'ed out the TryLock() method. -// This is for two reasons: -// 1) TryLock() under Windows is a bit annoying (it requires a -// #define to be defined very early). -// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG -// mode. -// If you need TryLock(), and either these two caveats are not a -// problem for you, or you're willing to work around them, then -// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs -// in the code below. -// -// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: -// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html -// Because of that, we might as well use windows locks for -// cygwin. They seem to be more reliable than the cygwin pthreads layer. -// -// TRICKY IMPLEMENTATION NOTE: -// This class is designed to be safe to use during -// dynamic-initialization -- that is, by global constructors that are -// run before main() starts. The issue in this case is that -// dynamic-initialization happens in an unpredictable order, and it -// could be that someone else's dynamic initializer could call a -// function that tries to acquire this mutex -- but that all happens -// before this mutex's constructor has run. (This can happen even if -// the mutex and the function that uses the mutex are in the same .cc -// file.) Basically, because Mutex does non-trivial work in its -// constructor, it's not, in the naive implementation, safe to use -// before dynamic initialization has run on it. -// -// The solution used here is to pair the actual mutex primitive with a -// bool that is set to true when the mutex is dynamically initialized. -// (Before that it's false.) Then we modify all mutex routines to -// look at the bool, and not try to lock/unlock until the bool makes -// it to true (which happens after the Mutex constructor has run.) -// -// This works because before main() starts -- particularly, during -// dynamic initialization -- there are no threads, so a) it's ok that -// the mutex operations are a no-op, since we don't need locking then -// anyway; and b) we can be quite confident our bool won't change -// state between a call to Lock() and a call to Unlock() (that would -// require a global constructor in one translation unit to call Lock() -// and another global constructor in another translation unit to call -// Unlock() later, which is pretty perverse). -// -// That said, it's tricky, and can conceivably fail; it's safest to -// avoid trying to acquire a mutex in a global constructor, if you -// can. One way it can fail is that a really smart compiler might -// initialize the bool to true at static-initialization time (too -// early) rather than at dynamic-initialization time. To discourage -// that, we set is_safe_ to true in code (not the constructor -// colon-initializer) and set it to true via a function that always -// evaluates to true, but that the compiler can't know always -// evaluates to true. This should be good enough. - -#ifndef GOOGLE_MUTEX_H_ -#define GOOGLE_MUTEX_H_ - -#include "config.h" // to figure out pthreads support - -#if defined(NO_THREADS) - typedef int MutexType; // to keep a lock-count -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN // We only need minimal includes -# endif -# ifdef GMUTEX_TRYLOCK - // We need Windows NT or later for TryEnterCriticalSection(). If you - // don't need that functionality, you can remove these _WIN32_WINNT - // lines, and change TryLock() to assert(0) or something. -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# endif -// To avoid macro definition of ERROR. -# ifndef NOGDI -# define NOGDI -# endif -// To avoid macro definition of min/max. -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include - typedef CRITICAL_SECTION MutexType; -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - // Needed for pthread_rwlock_*. If it causes problems, you could take it - // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it - // *does* cause problems for FreeBSD, or MacOSX, but isn't needed - // for locking there.) -# ifdef __linux__ -# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls -# endif -# include - typedef pthread_rwlock_t MutexType; -#elif defined(HAVE_PTHREAD) -# include - typedef pthread_mutex_t MutexType; -#else -# error Need to implement mutex.h for your architecture, or #define NO_THREADS -#endif - -// We need to include these header files after defining _XOPEN_SOURCE -// as they may define the _XOPEN_SOURCE macro. -#include -#include // for abort() - -#define MUTEX_NAMESPACE glog_internal_namespace_ - -namespace MUTEX_NAMESPACE { - -class Mutex { - public: - // Create a Mutex that is not held by anybody. This constructor is - // typically used for Mutexes allocated on the heap or the stack. - // See below for a recommendation for constructing global Mutex - // objects. - inline Mutex(); - - // Destructor - inline ~Mutex(); - - inline void Lock(); // Block if needed until free then acquire exclusively - inline void Unlock(); // Release a lock acquired via Lock() -#ifdef GMUTEX_TRYLOCK - inline bool TryLock(); // If free, Lock() and return true, else return false -#endif - // Note that on systems that don't support read-write locks, these may - // be implemented as synonyms to Lock() and Unlock(). So you can use - // these for efficiency, but don't use them anyplace where being able - // to do shared reads is necessary to avoid deadlock. - inline void ReaderLock(); // Block until free or shared then acquire a share - inline void ReaderUnlock(); // Release a read share of this Mutex - inline void WriterLock() { Lock(); } // Acquire an exclusive lock - inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() - - // TODO(hamaji): Do nothing, implement correctly. - inline void AssertHeld() {} - - private: - MutexType mutex_; - // We want to make sure that the compiler sets is_safe_ to true only - // when we tell it to, and never makes assumptions is_safe_ is - // always true. volatile is the most reliable way to do that. - volatile bool is_safe_; - - inline void SetIsSafe() { is_safe_ = true; } - - // Catch the error of writing Mutex when intending MutexLock. - Mutex(Mutex* /*ignored*/) {} - // Disallow "evil" constructors - Mutex(const Mutex&); - void operator=(const Mutex&); -}; - -// Now the implementation of Mutex for various systems -#if defined(NO_THREADS) - -// When we don't have threads, we can be either reading or writing, -// but not both. We can have lots of readers at once (in no-threads -// mode, that's most likely to happen in recursive function calls), -// but only one writer. We represent this by having mutex_ be -1 when -// writing and a number > 0 when reading (and 0 when no lock is held). -// -// In debug mode, we assert these invariants, while in non-debug mode -// we do nothing, for efficiency. That's why everything is in an -// assert. - -Mutex::Mutex() : mutex_(0) { } -Mutex::~Mutex() { assert(mutex_ == 0); } -void Mutex::Lock() { assert(--mutex_ == -1); } -void Mutex::Unlock() { assert(mutex_++ == -1); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } -#endif -void Mutex::ReaderLock() { assert(++mutex_ > 0); } -void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } - -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) - -Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } -Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } -void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } -void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - TryEnterCriticalSection(&mutex_) != 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks -void Mutex::ReaderUnlock() { Unlock(); } - -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_rwlock_trywrlock(&mutex_) == 0 : - true; } -#endif -void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } -void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#undef SAFE_PTHREAD - -#elif defined(HAVE_PTHREAD) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_mutex_trylock(&mutex_) == 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } -void Mutex::ReaderUnlock() { Unlock(); } -#undef SAFE_PTHREAD - -#endif - -// -------------------------------------------------------------------------- -// Some helper classes - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } - ~MutexLock() { mu_->Unlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - MutexLock(const MutexLock&); - void operator=(const MutexLock&); -}; - -// ReaderMutexLock and WriterMutexLock do the same, for rwlocks -class ReaderMutexLock { - public: - explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } - ~ReaderMutexLock() { mu_->ReaderUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - ReaderMutexLock(const ReaderMutexLock&); - void operator=(const ReaderMutexLock&); -}; - -class WriterMutexLock { - public: - explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } - ~WriterMutexLock() { mu_->WriterUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - WriterMutexLock(const WriterMutexLock&); - void operator=(const WriterMutexLock&); -}; - -// Catch bug where variable name is omitted, e.g. MutexLock (&mu); -#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) -#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) -#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) - -} // namespace MUTEX_NAMESPACE - -using namespace MUTEX_NAMESPACE; - -#undef MUTEX_NAMESPACE - -#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/third_party/src/glog/src/windows/config_cmake.h.in b/third_party/src/glog/src/windows/config_cmake.h.in deleted file mode 100644 index e5468d86..00000000 --- a/third_party/src/glog/src/windows/config_cmake.h.in +++ /dev/null @@ -1,142 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* Namespace for Google classes */ -#define GOOGLE_NAMESPACE google - -/* Define if you have the `dladdr' function */ -#undef HAVE_DLADDR - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_H - -/* define if you have google gflags library */ -#undef HAVE_LIB_GFLAGS - -/* define if you have libunwind */ -#undef HAVE_LIB_UNWIND - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* define if the compiler implements pthread_rwlock_* */ -#undef HAVE_RWLOCK - -/* Define if you have the `sigaltstack' function */ -#undef HAVE_SIGALTSTACK - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* define if the compiler supports using expression for operator */ -#undef HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#undef HAVE___BUILTIN_EXPECT - -/* define if your compiler has __sync_val_compare_and_swap */ -#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#undef PC_FROM_UCONTEXT - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#undef STL_NAMESPACE - -/* Version number of package */ -#undef VERSION - -/* Stops putting the code inside the Google namespace */ -#define _END_GOOGLE_NAMESPACE_ } - -/* Puts following code inside the Google namespace */ -#define _START_GOOGLE_NAMESPACE_ namespace google { - -/* Always the empty-string on non-windows systems. On windows, should be - "__declspec(dllexport)". This way, when we compile the dll, we export our - functions/classes. It's safe to define this here because config.h is only - used internally, to compile the DLL, and every DLL source file #includes - "config.h" before anything else. */ -#ifndef GOOGLE_GLOG_DLL_DECL -# define GOOGLE_GLOG_IS_A_DLL 1 /* not set if you're statically linking */ -# define GOOGLE_GLOG_DLL_DECL __declspec(dllexport) -# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) -#endif - -/* Whether snprintf exists in stdio.h */ -#cmakedefine HAVE_SNPRINTF 1 - -/* Whether pid_t exists in process.h */ -#cmakedefine HAVE_PID_T 1 diff --git a/third_party/src/glog/src/windows/glog/log_severity.h b/third_party/src/glog/src/windows/glog/log_severity.h deleted file mode 100644 index 22a4191a..00000000 --- a/third_party/src/glog/src/windows/glog/log_severity.h +++ /dev/null @@ -1,96 +0,0 @@ -// This file is automatically generated from src/glog/log_severity.h -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 2007, 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. - -#ifndef BASE_LOG_SEVERITY_H__ -#define BASE_LOG_SEVERITY_H__ - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// Variables of type LogSeverity are widely taken to lie in the range -// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if -// you ever need to change their values or add a new severity. -typedef int LogSeverity; - -const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, - NUM_SEVERITIES = 4; -#ifndef GLOG_NO_ABBREVIATED_SEVERITIES -# ifdef ERROR -# error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail. -# endif -const int INFO = GLOG_INFO, WARNING = GLOG_WARNING, - ERROR = GLOG_ERROR, FATAL = GLOG_FATAL; -#endif - -// DFATAL is FATAL in debug mode, ERROR in normal mode -#ifdef NDEBUG -#define DFATAL_LEVEL ERROR -#else -#define DFATAL_LEVEL FATAL -#endif - -extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; - -// NDEBUG usage helpers related to (RAW_)DCHECK: -// -// DEBUG_MODE is for small !NDEBUG uses like -// if (DEBUG_MODE) foo.CheckThatFoo(); -// instead of substantially more verbose -// #ifndef NDEBUG -// foo.CheckThatFoo(); -// #endif -// -// IF_DEBUG_MODE is for small !NDEBUG uses like -// IF_DEBUG_MODE( string error; ) -// DCHECK(Foo(&error)) << error; -// instead of substantially more verbose -// #ifndef NDEBUG -// string error; -// DCHECK(Foo(&error)) << error; -// #endif -// -#ifdef NDEBUG -enum { DEBUG_MODE = 0 }; -#define IF_DEBUG_MODE(x) -#else -enum { DEBUG_MODE = 1 }; -#define IF_DEBUG_MODE(x) x -#endif - -#endif // BASE_LOG_SEVERITY_H__ diff --git a/third_party/src/glog/src/windows/glog/logging.h b/third_party/src/glog/src/windows/glog/logging.h deleted file mode 100644 index 1d91b12a..00000000 --- a/third_party/src/glog/src/windows/glog/logging.h +++ /dev/null @@ -1,1603 +0,0 @@ -// This file is automatically generated from src/glog/logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 1999, 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: Ray Sidney -// -// This file contains #include information about logging-related stuff. -// Pretty much everybody needs to #include this file so that they can -// log various happenings. -// -#ifndef _LOGGING_H_ -#define _LOGGING_H_ - -#include -#include -#include -#include -#include -#include -#include -#if 0 -# include -#endif -#include - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif -#if defined(_MSC_VER) -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ - __pragma(warning(disable:n)) -#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop)) -#else -#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) -#define GLOG_MSVC_POP_WARNING() -#endif - -// We care a lot about number of bits things take up. Unfortunately, -// systems define their bit-specific ints in a lot of different ways. -// We use our own way, and have a typedef to get there. -// Note: these commands below may look like "#if 1" or "#if 0", but -// that's because they were constructed that way at ./configure time. -// Look at logging.h.in to see how they're calculated (based on your config). -#if 0 -#include // the normal place uint16_t is defined -#endif -#if 0 -#include // the normal place u_int16_t is defined -#endif -#if 0 -#include // a third place for uint16_t or u_int16_t -#endif - -#if 0 -#include -#endif - -namespace google { - -#if 0 // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif 0 // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif 1 // the windows (vc7) format -typedef __int32 int32; -typedef unsigned __int32 uint32; -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else -#error Do not know how to define a 32-bit integer quantity on your system -#endif - -} - -// The global value of GOOGLE_STRIP_LOG. All the messages logged to -// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. -// If it can be determined at compile time that the message will not be -// printed, the statement will be compiled out. -// -// Example: to strip out all INFO and WARNING messages, use the value -// of 2 below. To make an exception for WARNING messages from a single -// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including -// base/logging.h -#ifndef GOOGLE_STRIP_LOG -#define GOOGLE_STRIP_LOG 0 -#endif - -// GCC can be told that a certain branch is not likely to be taken (for -// instance, a CHECK failure), and use that information in static analysis. -// Giving it this information can help it optimize for the common case in -// the absence of better information (ie. -fprofile-arcs). -// -#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN -#if 0 -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x -#define GOOGLE_PREDICT_FALSE(x) x -#define GOOGLE_PREDICT_TRUE(x) x -#endif -#endif - -// Make a bunch of macros for logging. The way to log things is to stream -// things to LOG(). E.g., -// -// LOG(INFO) << "Found " << num_cookies << " cookies"; -// -// You can capture log messages in a string, rather than reporting them -// immediately: -// -// vector errors; -// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; -// -// This pushes back the new error onto 'errors'; if given a NULL pointer, -// it reports the error via LOG(ERROR). -// -// You can also do conditional logging: -// -// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// You can also do occasional logging (log every n'th occurrence of an -// event): -// -// LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// The above will cause log messages to be output on the 1st, 11th, 21st, ... -// times it is executed. Note that the special google::COUNTER value is used -// to identify which repetition is happening. -// -// You can also do occasional conditional logging (log every n'th -// occurrence of an event, when condition is satisfied): -// -// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER -// << "th big cookie"; -// -// You can log messages the first N times your code executes a line. E.g. -// -// LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; -// -// Outputs log messages for the first 20 times it is executed. -// -// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. -// These log to syslog as well as to the normal logs. If you use these at -// all, you need to be aware that syslog can drastically reduce performance, -// especially if it is configured for remote logging! Don't use these -// unless you fully understand this and have a concrete need to use them. -// Even then, try to minimize your use of them. -// -// There are also "debug mode" logging macros like the ones above: -// -// DLOG(INFO) << "Found cookies"; -// -// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; -// -// All "debug mode" logging is compiled away to nothing for non-debug mode -// compiles. -// -// We also have -// -// LOG_ASSERT(assertion); -// DLOG_ASSERT(assertion); -// -// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; -// -// There are "verbose level" logging macros. They look like -// -// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; -// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; -// -// These always log at the INFO log level (when they log at all). -// The verbose logging can also be turned on module-by-module. For instance, -// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 -// will cause: -// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} -// b. VLOG(1) and lower messages to be printed from file.{h,cc} -// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" -// d. VLOG(0) and lower messages to be printed from elsewhere -// -// The wildcarding functionality shown by (c) supports both '*' (match -// 0 or more characters) and '?' (match any single character) wildcards. -// -// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as -// -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished with just VLOG(2) << ...; -// } -// -// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" -// condition macros for sample cases, when some extra computation and -// preparation for logs is not needed. -// VLOG_IF(1, (size > 1024)) -// << "I'm printed when size is more than 1024 and when you run the " -// "program with --v=1 or more"; -// VLOG_EVERY_N(1, 10) -// << "I'm printed every 10th occurrence, and when you run the program " -// "with --v=1 or more. Present occurence is " << google::COUNTER; -// VLOG_IF_EVERY_N(1, (size > 1024), 10) -// << "I'm printed on every 10th occurence of case when size is more " -// " than 1024, when you run the program with --v=1 or more. "; -// "Present occurence is " << google::COUNTER; -// -// The supported severity levels for macros that allow you to specify one -// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. -// Note that messages of a given severity are logged not only in the -// logfile for that severity, but also in all logfiles of lower severity. -// E.g., a message of severity FATAL will be logged to the logfiles of -// severity FATAL, ERROR, WARNING, and INFO. -// -// There is also the special severity of DFATAL, which logs FATAL in -// debug mode, ERROR in normal mode. -// -// Very important: logging a message at the FATAL severity level causes -// the program to terminate (after the message is logged). -// -// Unless otherwise specified, logs will be written to the filename -// "...log..", followed -// by the date, time, and pid (you can't prevent the date, time, and pid -// from being in the filename). -// -// The logging code takes two flags: -// --v=# set the verbose level -// --logtostderr log all the messages to stderr instead of to logfiles - -// LOG LINE PREFIX FORMAT -// -// Log lines have this form: -// -// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... -// -// where the fields are defined as follows: -// -// L A single character, representing the log level -// (eg 'I' for INFO) -// mm The month (zero padded; ie May is '05') -// dd The day (zero padded) -// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds -// threadid The space-padded thread ID as returned by GetTID() -// (this matches the PID on Linux) -// file The file name -// line The line number -// msg The user-supplied message -// -// Example: -// -// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog -// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 -// -// NOTE: although the microseconds are useful for comparing events on -// a single machine, clocks on different machines may not be well -// synchronized. Hence, use caution when comparing the low bits of -// timestamps from different machines. - -#ifndef DECLARE_VARIABLE -#define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name - -// bool specialization -#define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, B, name, bool) - -// int32 specialization -#define DECLARE_int32(name) \ - DECLARE_VARIABLE(google::int32, I, name, int32) - -// Special case for string, because we have to specify the namespace -// std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace fLS { \ - extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#endif - -// Set whether log messages go to stderr instead of logfiles -DECLARE_bool(logtostderr); - -// Set whether log messages go to stderr in addition to logfiles. -DECLARE_bool(alsologtostderr); - -// Set color messages logged to stderr (if supported by terminal). -DECLARE_bool(colorlogtostderr); - -// Log messages at a level >= this flag are automatically sent to -// stderr in addition to log files. -DECLARE_int32(stderrthreshold); - -// Set whether the log prefix should be prepended to each line of output. -DECLARE_bool(log_prefix); - -// Log messages at a level <= this flag are buffered. -// Log messages at a higher level are flushed immediately. -DECLARE_int32(logbuflevel); - -// Sets the maximum number of seconds which logs may be buffered for. -DECLARE_int32(logbufsecs); - -// Log suppression level: messages logged at a lower level than this -// are suppressed. -DECLARE_int32(minloglevel); - -// If specified, logfiles are written into this directory instead of the -// default logging directory. -DECLARE_string(log_dir); - -// Sets the path of the directory into which to put additional links -// to the log files. -DECLARE_string(log_link); - -DECLARE_int32(v); // in vlog_is_on.cc - -// Sets the maximum log file size (in MB). -DECLARE_int32(max_log_size); - -// Sets whether to avoid logging to the disk if the disk is full. -DECLARE_bool(stop_logging_if_full_disk); - -#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS -#undef DECLARE_VARIABLE -#undef DECLARE_bool -#undef DECLARE_int32 -#undef DECLARE_string -#endif - -// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for -// security reasons. See LOG(severtiy) below. - -// A few definitions of macros that don't generate much code. Since -// LOG(INFO) and its ilk are used all over our code, it's -// better to have compact code for these operations. - -#if GOOGLE_STRIP_LOG == 0 -#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_INFO(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_INFO, message) -#else -#define COMPACT_GOOGLE_LOG_INFO google::NullStream() -#define LOG_TO_STRING_INFO(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 1 -#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_WARNING) -#define LOG_TO_STRING_WARNING(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_WARNING, message) -#else -#define COMPACT_GOOGLE_LOG_WARNING google::NullStream() -#define LOG_TO_STRING_WARNING(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 2 -#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ERROR) -#define LOG_TO_STRING_ERROR(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ERROR, message) -#else -#define COMPACT_GOOGLE_LOG_ERROR google::NullStream() -#define LOG_TO_STRING_ERROR(message) google::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_FATAL(message) google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_FATAL, message) -#else -#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal() -#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal() -#endif - -// For DFATAL, we want to use LogMessage (as opposed to -// LogMessageFatal), to be consistent with the original behavior. -#ifdef NDEBUG -#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR -#elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_FATAL) -#else -#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() -#endif - -#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, &google::LogMessage::SendToLog) -#define SYSLOG_INFO(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_WARNING(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_ERROR(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_FATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \ - &google::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToLog) -#define SYSLOG_DFATAL(counter) \ - google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ - &google::LogMessage::SendToSyslogAndLog) - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) -// A very useful logging macro to log windows errors: -#define LOG_SYSRESULT(result) \ - if (FAILED(HRESULT_FROM_WIN32(result))) { \ - LPSTR message = NULL; \ - LPSTR msg = reinterpret_cast(&message); \ - DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ - FORMAT_MESSAGE_FROM_SYSTEM, \ - 0, result, 0, msg, 100, NULL); \ - if (message_length > 0) { \ - google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \ - &google::LogMessage::SendToLog).stream() \ - << reinterpret_cast(message); \ - LocalFree(message); \ - } \ - } -#endif - -// We use the preprocessor's merging operator, "##", so that, e.g., -// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny -// subtle difference between ostream member streaming functions (e.g., -// ostream::operator<<(int) and ostream non-member streaming functions -// (e.g., ::operator<<(ostream&, string&): it turns out that it's -// impossible to stream something like a string directly to an unnamed -// ostream. We employ a neat hack by calling the stream() member -// function of LogMessage which seems to avoid the problem. -#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() -#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() - -namespace google { - -// They need the definitions of integer types. -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Initialize google's logging library. You will see the program name -// specified by argv0 in log outputs. -GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); - -// Shutdown google's logging library. -GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); - -// Install a function which will be called after LOG(FATAL). -GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); - -class LogSink; // defined below - -// If a non-NULL sink pointer is given, we push this message to that sink. -// For LOG_TO_SINK we then do normal LOG(severity) logging as well. -// This is useful for capturing messages and passing/storing them -// somewhere more specific than the global log of the process. -// Argument types: -// LogSink* sink; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -#define LOG_TO_SINK(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast(sink), true).stream() -#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ - google::LogMessage( \ - __FILE__, __LINE__, \ - google::GLOG_ ## severity, \ - static_cast(sink), false).stream() - -// If a non-NULL string pointer is given, we write this message to that string. -// We then do normal LOG(severity) logging as well. -// This is useful for capturing messages and storing them somewhere more -// specific than the global log of the process. -// Argument types: -// string* message; -// LogSeverity severity; -// The cast is to disambiguate NULL arguments. -// NOTE: LOG(severity) expands to LogMessage().stream() for the specified -// severity. -#define LOG_TO_STRING(severity, message) \ - LOG_TO_STRING_##severity(static_cast(message)).stream() - -// If a non-NULL pointer is given, we push the message onto the end -// of a vector of strings; otherwise, we report it with LOG(severity). -// This is handy for capturing messages and perhaps passing them back -// to the caller, rather than reporting them immediately. -// Argument types: -// LogSeverity severity; -// vector *outvec; -// The cast is to disambiguate NULL arguments. -#define LOG_STRING(severity, outvec) \ - LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() - -#define LOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) -#define SYSLOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) - -#define LOG_ASSERT(condition) \ - LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition - -// CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by NDEBUG, so the check will be executed regardless of -// compilation mode. Therefore, it is safe to do things like: -// CHECK(fp->Write(x) == 4) -#define CHECK(condition) \ - LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A container for a string pointer which can be evaluated to a bool - -// true iff the pointer is NULL. -struct CheckOpString { - CheckOpString(std::string* str) : str_(str) { } - // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), - // so there's no point in cleaning up str_. - operator bool() const { - return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); - } - std::string* str_; -}; - -// Function is overloaded for integral types to allow static const -// integrals declared in classes and not defined to be used as arguments to -// CHECK* macros. It's not encouraged though. -template -inline const T& GetReferenceableValue(const T& t) { return t; } -inline char GetReferenceableValue(char t) { return t; } -inline unsigned char GetReferenceableValue(unsigned char t) { return t; } -inline signed char GetReferenceableValue(signed char t) { return t; } -inline short GetReferenceableValue(short t) { return t; } -inline unsigned short GetReferenceableValue(unsigned short t) { return t; } -inline int GetReferenceableValue(int t) { return t; } -inline unsigned int GetReferenceableValue(unsigned int t) { return t; } -inline long GetReferenceableValue(long t) { return t; } -inline unsigned long GetReferenceableValue(unsigned long t) { return t; } -inline long long GetReferenceableValue(long long t) { return t; } -inline unsigned long long GetReferenceableValue(unsigned long long t) { - return t; -} - -// This is a dummy class to define the following operator. -struct DummyClassToDefineOperator {}; - -} - -// Define global operator<< to declare using ::operator<<. -// This declaration will allow use to use CHECK macros for user -// defined classes which have operator<< (e.g., stl_logging.h). -inline std::ostream& operator<<( - std::ostream& out, const google::DummyClassToDefineOperator&) { - return out; -} - -namespace google { - -// This formats a value for a failing CHECK_XX statement. Ordinarily, -// it uses the definition for operator<<, with a few special cases below. -template -inline void MakeCheckOpValueString(std::ostream* os, const T& v) { - (*os) << v; -} - -// Overrides for char types provide readable values for unprintable -// characters. -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const signed char& v); -template <> GOOGLE_GLOG_DLL_DECL -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); - -// Build the error message string. Specify no inlining for code size. -template -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) - ; - -namespace base { -namespace internal { - -// If "s" is less than base_logging::INFO, returns base_logging::INFO. -// If "s" is greater than base_logging::FATAL, returns -// base_logging::ERROR. Otherwise, returns "s". -LogSeverity NormalizeSeverity(LogSeverity s); - -} // namespace internal - -// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX -// statement. See MakeCheckOpString for sample usage. Other -// approaches were considered: use of a template method (e.g., -// base::BuildCheckOpString(exprtext, base::Print, &v1, -// base::Print, &v2), however this approach has complications -// related to volatile arguments and function-pointer arguments). -class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { - public: - // Inserts "exprtext" and " (" to the stream. - explicit CheckOpMessageBuilder(const char *exprtext); - // Deletes "stream_". - ~CheckOpMessageBuilder(); - // For inserting the first variable. - std::ostream* ForVar1() { return stream_; } - // For inserting the second variable (adds an intermediate " vs. "). - std::ostream* ForVar2(); - // Get the result (inserts the closing ")"). - std::string* NewString(); - - private: - std::ostringstream *stream_; -}; - -} // namespace base - -template -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { - base::CheckOpMessageBuilder comb(exprtext); - MakeCheckOpValueString(comb.ForVar1(), v1); - MakeCheckOpValueString(comb.ForVar2(), v2); - return comb.NewString(); -} - -// Helper functions for CHECK_OP macro. -// The (int, int) specialization works around the issue that the compiler -// will not instantiate the template version of the function on values of -// unnamed enum type - see comment below. -#define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* name##Impl(const T1& v1, const T2& v2, \ - const char* exprtext) { \ - if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ - else return MakeCheckOpString(v1, v2, exprtext); \ - } \ - inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ - return name##Impl(v1, v2, exprtext); \ - } - -// We use the full name Check_EQ, Check_NE, etc. in case the file including -// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. -// This happens if, for example, those are used as token names in a -// yacc grammar. -DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? -DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. -DEFINE_CHECK_OP_IMPL(Check_LE, <=) -DEFINE_CHECK_OP_IMPL(Check_LT, < ) -DEFINE_CHECK_OP_IMPL(Check_GE, >=) -DEFINE_CHECK_OP_IMPL(Check_GT, > ) -#undef DEFINE_CHECK_OP_IMPL - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. - -#if defined(STATIC_ANALYSIS) -// Only for static analysis tool to know that it is equivalent to assert -#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) -#elif !defined(NDEBUG) -// In debug mode, avoid constructing CheckOpStrings if possible, -// to reduce the overhead of CHECK statments by 2x. -// Real DCHECK-heavy tests have seen 1.5x speedups. - -// The meaning of "string" might be different between now and -// when this macro gets invoked (e.g., if someone is experimenting -// with other string implementations that get defined after this -// file is included). Save the current meaning now and use it -// in the macro. -typedef std::string _Check_string; -#define CHECK_OP_LOG(name, op, val1, val2, log) \ - while (google::_Check_string* _result = \ - google::Check##name##Impl( \ - google::GetReferenceableValue(val1), \ - google::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, \ - google::CheckOpString(_result)).stream() -#else -// In optimized mode, use CheckOpString to hint to compiler that -// the while condition is unlikely. -#define CHECK_OP_LOG(name, op, val1, val2, log) \ - while (google::CheckOpString _result = \ - google::Check##name##Impl( \ - google::GetReferenceableValue(val1), \ - google::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, _result).stream() -#endif // STATIC_ANALYSIS, !NDEBUG - -#if GOOGLE_STRIP_LOG <= 3 -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal) -#else -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal) -#endif // STRIP_LOG <= 3 - -// Equality/Inequality checks - compare two values, and log a FATAL message -// including the two values when the result is not as expected. The values -// must have operator<<(ostream, ...) defined. -// -// You may append to the error message like so: -// CHECK_NE(1, 2) << ": The world must be ending!"; -// -// We are very careful to ensure that each argument is evaluated exactly -// once, and that anything which is legal to pass as a function argument is -// legal here. In particular, the arguments may be temporary expressions -// which will end up being destroyed at the end of the apparent statement, -// for example: -// CHECK_EQ(string("abc")[1], 'b'); -// -// WARNING: These don't compile correctly if one of the arguments is a pointer -// and the other is NULL. To work around this, simply static_cast NULL to the -// type of the desired pointer. - -#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) -#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) -#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) -#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) -#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) -#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) - -// Check that the input is non NULL. This very useful in constructor -// initializer lists. - -#define CHECK_NOTNULL(val) \ - google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) - -// Helper functions for string comparisons. -// To avoid bloat, the definitions are in logging.cc. -#define DECLARE_CHECK_STROP_IMPL(func, expected) \ - GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ - const char* s1, const char* s2, const char* names); -DECLARE_CHECK_STROP_IMPL(strcmp, true) -DECLARE_CHECK_STROP_IMPL(strcmp, false) -DECLARE_CHECK_STROP_IMPL(strcasecmp, true) -DECLARE_CHECK_STROP_IMPL(strcasecmp, false) -#undef DECLARE_CHECK_STROP_IMPL - -// Helper macro for string comparisons. -// Don't use this macro directly in your code, use CHECK_STREQ et al below. -#define CHECK_STROP(func, op, expected, s1, s2) \ - while (google::CheckOpString _result = \ - google::Check##func##expected##Impl((s1), (s2), \ - #s1 " " #op " " #s2)) \ - LOG(FATAL) << *_result.str_ - - -// String (char*) equality/inequality checks. -// CASE versions are case-insensitive. -// -// Note that "s1" and "s2" may be temporary strings which are destroyed -// by the compiler at the end of the current "full expression" -// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). - -#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) -#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) -#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) -#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) - -#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) -#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) - -#define CHECK_DOUBLE_EQ(val1, val2) \ - do { \ - CHECK_LE((val1), (val2)+0.000000000000001L); \ - CHECK_GE((val1), (val2)-0.000000000000001L); \ - } while (0) - -#define CHECK_NEAR(val1, val2, margin) \ - do { \ - CHECK_LE((val1), (val2)+(margin)); \ - CHECK_GE((val1), (val2)-(margin)); \ - } while (0) - -// perror()..googly style! -// -// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and -// CHECK equivalents with the addition that they postpend a description -// of the current state of errno to their output lines. - -#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() - -#define GOOGLE_PLOG(severity, counter) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, counter, \ - &google::LogMessage::SendToLog) - -#define PLOG_IF(severity, condition) \ - !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) - -// A CHECK() macro that postpends errno if the condition is false. E.g. -// -// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } -#define PCHECK(condition) \ - PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ - << "Check failed: " #condition " " - -// A CHECK() macro that lets you assert the success of a function that -// returns -1 and sets errno in case of an error. E.g. -// -// CHECK_ERR(mkdir(path, 0700)); -// -// or -// -// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; -#define CHECK_ERR(invocation) \ -PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ - << #invocation - -// Use macro expansion to create, for each use of LOG_EVERY_N(), static -// variables with the __LINE__ expansion as part of the variable name. -#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) -#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line - -#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) -#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (condition && \ - ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - google::ErrnoLogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0; \ - if (LOG_OCCURRENCES <= n) \ - ++LOG_OCCURRENCES; \ - if (LOG_OCCURRENCES <= n) \ - google::LogMessage( \ - __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -namespace glog_internal_namespace_ { -template -struct CompileAssert { -}; -struct CrashReason; -} // namespace glog_internal_namespace_ - -#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \ - typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] - -#define LOG_EVERY_N(severity, n) \ - GOOGLE_GLOG_COMPILE_ASSERT(google::GLOG_ ## severity < \ - google::NUM_SEVERITIES, \ - INVALID_REQUESTED_LOG_SEVERITY); \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define SYSLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) - -#define PLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_FIRST_N(severity, n) \ - SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) - -#define LOG_IF_EVERY_N(severity, condition, n) \ - SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) - -// We want the special COUNTER value available for LOG_EVERY_X()'ed messages -enum PRIVATE_Counter {COUNTER}; - -#ifdef GLOG_NO_ABBREVIATED_SEVERITIES -// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets -// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us -// to keep using this syntax, we define this macro to do the same thing -// as COMPACT_GOOGLE_LOG_ERROR. -#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR -#define SYSLOG_0 SYSLOG_ERROR -#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR -// Needed for LOG_IS_ON(ERROR). -const LogSeverity GLOG_0 = GLOG_ERROR; -#else -// Users may include windows.h after logging.h without -// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN. -// For this case, we cannot detect if ERROR is defined before users -// actually use ERROR. Let's make an undefined symbol to warn users. -# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail -# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG -# define SYSLOG_0 GLOG_ERROR_MSG -# define LOG_TO_STRING_0 GLOG_ERROR_MSG -# define GLOG_0 GLOG_ERROR_MSG -#endif - -// Plus some debug-logging macros that get compiled to nothing for production - -#ifndef NDEBUG - -#define DLOG(severity) LOG(severity) -#define DVLOG(verboselevel) VLOG(verboselevel) -#define DLOG_IF(severity, condition) LOG_IF(severity, condition) -#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) -#define DLOG_IF_EVERY_N(severity, condition, n) \ - LOG_IF_EVERY_N(severity, condition, n) -#define DLOG_ASSERT(condition) LOG_ASSERT(condition) - -// debug-only checking. not executed in NDEBUG mode. -#define DCHECK(condition) CHECK(condition) -#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) -#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) -#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) -#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) -#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) -#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) -#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val) -#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) -#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) -#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) -#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) - -#else // NDEBUG - -#define DLOG(severity) \ - true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DVLOG(verboselevel) \ - (true || !VLOG_IS_ON(verboselevel)) ?\ - (void) 0 : google::LogMessageVoidify() & LOG(INFO) - -#define DLOG_IF(severity, condition) \ - (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_EVERY_N(severity, n) \ - true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_IF_EVERY_N(severity, condition, n) \ - (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) - -#define DLOG_ASSERT(condition) \ - true ? (void) 0 : LOG_ASSERT(condition) - -// MSVC warning C4127: conditional expression is constant -#define DCHECK(condition) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK(condition) - -#define DCHECK_EQ(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2) - -#define DCHECK_NE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2) - -#define DCHECK_LE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2) - -#define DCHECK_LT(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2) - -#define DCHECK_GE(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2) - -#define DCHECK_GT(val1, val2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2) - -// You may see warnings in release mode if you don't use the return -// value of DCHECK_NOTNULL. Please just use DCHECK for such cases. -#define DCHECK_NOTNULL(val) (val) - -#define DCHECK_STREQ(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2) - -#define DCHECK_STRCASEEQ(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2) - -#define DCHECK_STRNE(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2) - -#define DCHECK_STRCASENE(str1, str2) \ - GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ - while (false) \ - GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2) - -#endif // NDEBUG - -// Log only in verbose mode. - -#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) - -#define VLOG_IF(verboselevel, condition) \ - LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) - -#define VLOG_EVERY_N(verboselevel, n) \ - LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) - -#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ - LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) - -namespace base_logging { - -// LogMessage::LogStream is a std::ostream backed by this streambuf. -// This class ignores overflow and leaves two bytes at the end of the -// buffer to allow for a '\n' and '\0'. -class LogStreamBuf : public std::streambuf { - public: - // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'. - LogStreamBuf(char *buf, int len) { - setp(buf, buf + len - 2); - } - // This effectively ignores overflow. - virtual int_type overflow(int_type ch) { - return ch; - } - - // Legacy public ostrstream method. - size_t pcount() const { return pptr() - pbase(); } - char* pbase() const { return std::streambuf::pbase(); } -}; - -} // namespace base_logging - -// -// This class more or less represents a particular log message. You -// create an instance of LogMessage and then stream stuff to it. -// When you finish streaming to it, ~LogMessage is called and the -// full message gets streamed to the appropriate destination. -// -// You shouldn't actually use LogMessage's constructor to log things, -// though. You should use the LOG() macro (and variants thereof) -// above. -class GOOGLE_GLOG_DLL_DECL LogMessage { -public: - enum { - // Passing kNoLogPrefix for the line number disables the - // log-message prefix. Useful for using the LogMessage - // infrastructure as a printing utility. See also the --log_prefix - // flag for controlling the log-message prefix on an - // application-wide basis. - kNoLogPrefix = -1 - }; - - // LogStream inherit from non-DLL-exported class (std::ostrstream) - // and VC++ produces a warning for this situation. - // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ - // 2005 if you are deriving from a type in the Standard C++ Library" - // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx - // Let's just ignore the warning. -#ifdef _MSC_VER -# pragma warning(disable: 4275) -#endif - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { -#ifdef _MSC_VER -# pragma warning(default: 4275) -#endif - public: - LogStream(char *buf, int len, int ctr) - : std::ostream(NULL), - streambuf_(buf, len), - ctr_(ctr), - self_(this) { - rdbuf(&streambuf_); - } - - int ctr() const { return ctr_; } - void set_ctr(int ctr) { ctr_ = ctr; } - LogStream* self() const { return self_; } - - // Legacy std::streambuf methods. - size_t pcount() const { return streambuf_.pcount(); } - char* pbase() const { return streambuf_.pbase(); } - char* str() const { return pbase(); } - - private: - base_logging::LogStreamBuf streambuf_; - int ctr_; // Counter hack (for the LOG_EVERY_X() macro) - LogStream *self_; // Consistency check hack - }; - -public: - // icc 8 requires this typedef to avoid an internal compiler error. - typedef void (LogMessage::*SendMethod)(); - - LogMessage(const char* file, int line, LogSeverity severity, int ctr, - SendMethod send_method); - - // Two special constructors that generate reduced amounts of code at - // LOG call sites for common cases. - - // Used for LOG(INFO): Implied are: - // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. - // - // Using this constructor instead of the more complex constructor above - // saves 19 bytes per call site. - LogMessage(const char* file, int line); - - // Used for LOG(severity) where severity != INFO. Implied - // are: ctr = 0, send_method = &LogMessage::SendToLog - // - // Using this constructor instead of the more complex constructor above - // saves 17 bytes per call site. - LogMessage(const char* file, int line, LogSeverity severity); - - // Constructor to log this message to a specified sink (if not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if - // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. - LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, - bool also_send_to_log); - - // Constructor where we also give a vector pointer - // for storing the messages (if the pointer is not NULL). - // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::vector* outvec); - - // Constructor where we also give a string pointer for storing the - // message (if the pointer is not NULL). Implied are: ctr = 0, - // send_method = &LogMessage::WriteToStringAndLog. - LogMessage(const char* file, int line, LogSeverity severity, - std::string* message); - - // A special constructor used for check failures - LogMessage(const char* file, int line, const CheckOpString& result); - - ~LogMessage(); - - // Flush a buffered message to the sink set in the constructor. Always - // called by the destructor, it may also be called from elsewhere if - // needed. Only the first call is actioned; any later ones are ignored. - void Flush(); - - // An arbitrary limit on the length of a single log message. This - // is so that streaming can be done more efficiently. - static const size_t kMaxLogMessageLen; - - // Theses should not be called directly outside of logging.*, - // only passed as SendMethod arguments to other LogMessage methods: - void SendToLog(); // Actually dispatch to the logs - void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs - - // Call abort() or similar to perform LOG(FATAL) crash. - static void Fail() ; - - std::ostream& stream(); - - int preserved_errno() const; - - // Must be called without the log_mutex held. (L < log_mutex) - static int64 num_messages(int severity); - - struct LogMessageData; - -private: - // Fully internal SendMethod cases: - void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs - void SendToSink(); // Send to sink if provided, do nothing otherwise. - - // Write to string if provided and dispatch to the logs. - void WriteToStringAndLog(); - - void SaveOrSendToLog(); // Save to stringvec if provided, else to logs - - void Init(const char* file, int line, LogSeverity severity, - void (LogMessage::*send_method)()); - - // Used to fill in crash information during LOG(FATAL) failures. - void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); - - // Counts of messages sent at each priority: - static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex - - // We keep the data in a separate struct so that each instance of - // LogMessage uses less stack space. - LogMessageData* allocated_; - LogMessageData* data_; - - friend class LogDestination; - - LogMessage(const LogMessage&); - void operator=(const LogMessage&); -}; - -// This class happens to be thread-hostile because all instances share -// a single data buffer, but since it can only be created just before -// the process dies, we don't worry so much. -class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { - public: - LogMessageFatal(const char* file, int line); - LogMessageFatal(const char* file, int line, const CheckOpString& result); - ~LogMessageFatal() ; -}; - -// A non-macro interface to the log facility; (useful -// when the logging level is not a compile-time constant). -inline void LogAtLevel(int const severity, std::string const &msg) { - LogMessage(__FILE__, __LINE__, severity).stream() << msg; -} - -// A macro alternative of LogAtLevel. New code may want to use this -// version since there are two advantages: 1. this version outputs the -// file name and the line number where this macro is put like other -// LOG macros, 2. this macro can be used as C++ stream. -#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream() - -// A small helper for CHECK_NOTNULL(). -template -T* CheckNotNull(const char *file, int line, const char *names, T* t) { - if (t == NULL) { - LogMessageFatal(file, line, new std::string(names)); - } - return t; -} - -// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This -// only works if ostream is a LogStream. If the ostream is not a -// LogStream you'll get an assert saying as much at runtime. -GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, - const PRIVATE_Counter&); - - -// Derived class for PLOG*() above. -class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { - public: - - ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, - void (LogMessage::*send_method)()); - - // Postpends ": strerror(errno) [errno]". - ~ErrnoLogMessage(); - - private: - ErrnoLogMessage(const ErrnoLogMessage&); - void operator=(const ErrnoLogMessage&); -}; - - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". - -class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-safe. -GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); - -// Flushes all log files that contains messages that are at least of -// the specified severity level. Thread-hostile because it ignores -// locking -- used for catastrophic failures. -GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); - -// -// Set the destination to which a particular severity level of log -// messages is sent. If base_filename is "", it means "don't log this -// severity". Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, - const char* base_filename); - -// -// Set the basename of the symlink to the latest log file at a given -// severity. If symlink_basename is empty, do not make a symlink. If -// you don't call this function, the symlink basename is the -// invocation name of the program. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - -// -// Used to send logs to some other kind of destination -// Users should subclass LogSink and override send to do whatever they want. -// Implementations must be thread-safe because a shared instance will -// be called from whichever thread ran the LOG(XXX) line. -class GOOGLE_GLOG_DLL_DECL LogSink { - public: - virtual ~LogSink(); - - // Sink's logging logic (message_len is such as to exclude '\n' at the end). - // This method can't use LOG() or CHECK() as logging system mutex(s) are held - // during this call. - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) = 0; - - // Redefine this to implement waiting for - // the sink's logging logic to complete. - // It will be called after each send() returns, - // but before that LogMessage exits or crashes. - // By default this function does nothing. - // Using this function one can implement complex logic for send() - // that itself involves logging; and do all this w/o causing deadlocks and - // inconsistent rearrangement of log messages. - // E.g. if a LogSink has thread-specific actions, the send() method - // can simply add the message to a queue and wake up another thread that - // handles real logging while itself making some LOG() calls; - // WaitTillSent() can be implemented to wait for that logic to complete. - // See our unittest for an example. - virtual void WaitTillSent(); - - // Returns the normal text output of the log message. - // Can be useful to implement send(). - static std::string ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len); -}; - -// Add or remove a LogSink as a consumer of logging data. Thread-safe. -GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); -GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); - -// -// Specify an "extension" added to the filename specified via -// SetLogDestination. This applies to all severity levels. It's -// often used to append the port we're listening on to the logfile -// name. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( - const char* filename_extension); - -// -// Make it so that all log messages of at least a particular severity -// are logged to stderr (in addition to logging to the usual log -// file(s)). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); - -// -// Make it so that all log messages go only to stderr. Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void LogToStderr(); - -// -// Make it so that all log messages of at least a particular severity are -// logged via email to a list of addresses (in addition to logging to the -// usual log file(s)). The list of addresses is just a string containing -// the email addresses to send to (separated by spaces, say). Thread-safe. -// -GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, - const char* addresses); - -// A simple function that sends email. dest is a commma-separated -// list of addressess. Thread-safe. -GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, - const char *subject, const char *body); - -GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); - -// For tests only: Clear the internal [cached] list of logging directories to -// force a refresh the next time GetLoggingDirectories is called. -// Thread-hostile. -void TestOnly_ClearLoggingDirectoriesList(); - -// Returns a set of existing temporary directories, which will be a -// subset of the directories returned by GetLogginDirectories(). -// Thread-safe. -GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( - std::vector* list); - -// Print any fatal message again -- useful to call from signal handler -// so that the last thing in the output is the fatal message. -// Thread-hostile, but a race is unlikely. -GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); - -// Truncate a log file that may be the append-only output of multiple -// processes and hence can't simply be renamed/reopened (typically a -// stdout/stderr). If the file "path" is > "limit" bytes, copy the -// last "keep" bytes to offset 0 and truncate the rest. Since we could -// be racing with other writers, this approach has the potential to -// lose very small amounts of data. For security, only follow symlinks -// if the path is /proc/self/fd/* -GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, - int64 limit, int64 keep); - -// Truncate stdout and stderr if they are over the value specified by -// --max_log_size; keep the final 1MB. This function has the same -// race condition as TruncateLogFile. -GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); - -// Return the string representation of the provided LogSeverity level. -// Thread-safe. -GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); - -// --------------------------------------------------------------------- -// Implementation details that are not useful to most clients -// --------------------------------------------------------------------- - -// A Logger is the interface used by logging modules to emit entries -// to a log. A typical implementation will dump formatted data to a -// sequence of files. We also provide interfaces that will forward -// the data to another thread so that the invoker never blocks. -// Implementations should be thread-safe since the logging system -// will write to them from multiple threads. - -namespace base { - -class GOOGLE_GLOG_DLL_DECL Logger { - public: - virtual ~Logger(); - - // Writes "message[0,message_len-1]" corresponding to an event that - // occurred at "timestamp". If "force_flush" is true, the log file - // is flushed immediately. - // - // The input message has already been formatted as deemed - // appropriate by the higher level logging facility. For example, - // textual log messages already contain timestamps, and the - // file:linenumber header. - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) = 0; - - // Flush any buffered messages - virtual void Flush() = 0; - - // Get the current LOG file size. - // The returned value is approximate since some - // logged data may not have been flushed to disk yet. - virtual uint32 LogSize() = 0; -}; - -// Get the logger for the specified severity level. The logger -// remains the property of the logging module and should not be -// deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); - -// Set the logger for the specified severity level. The logger -// becomes the property of the logging module and should not -// be deleted by the caller. Thread-safe. -extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); - -} - -// glibc has traditionally implemented two incompatible versions of -// strerror_r(). There is a poorly defined convention for picking the -// version that we want, but it is not clear whether it even works with -// all versions of glibc. -// So, instead, we provide this wrapper that automatically detects the -// version that is in use, and then implements POSIX semantics. -// N.B. In addition to what POSIX says, we also guarantee that "buf" will -// be set to an empty string, if this function failed. This means, in most -// cases, you do not need to check the error code and you can directly -// use the value of "buf". It will never have an undefined value. -GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); - - -// A class for which we define operator<<, which does nothing. -class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { - public: - // Initialize the LogStream so the messages can be written somewhere - // (they'll never be actually displayed). This will be needed if a - // NullStream& is implicitly converted to LogStream&, in which case - // the overloaded NullStream::operator<< will not be invoked. - NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream(const char* /*file*/, int /*line*/, - const CheckOpString& /*result*/) : - LogMessage::LogStream(message_buffer_, 1, 0) { } - NullStream &stream() { return *this; } - private: - // A very short buffer for messages (which we discard anyway). This - // will be needed if NullStream& converted to LogStream& (e.g. as a - // result of a conditional expression). - char message_buffer_[2]; -}; - -// Do nothing. This operator is inline, allowing the message to be -// compiled away. The message will not be compiled away if we do -// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when -// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly -// converted to LogStream and the message will be computed and then -// quietly discarded. -template -inline NullStream& operator<<(NullStream &str, const T &) { return str; } - -// Similar to NullStream, but aborts the program (without stack -// trace), like LogMessageFatal. -class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { - public: - NullStreamFatal() { } - NullStreamFatal(const char* file, int line, const CheckOpString& result) : - NullStream(file, line, result) { } - ~NullStreamFatal() { _exit(1); } -}; - -// Install a signal handler that will dump signal information and a stack -// trace when the program crashes on certain signals. We'll install the -// signal handler for the following signals. -// -// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. -// -// By default, the signal handler will write the failure dump to the -// standard error. You can customize the destination by installing your -// own writer function by InstallFailureWriter() below. -// -// Note on threading: -// -// The function should be called before threads are created, if you want -// to use the failure signal handler for all threads. The stack trace -// will be shown only for the thread that receives the signal. In other -// words, stack traces of other threads won't be shown. -GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); - -// Installs a function that is used for writing the failure dump. "data" -// is the pointer to the beginning of a message to be written, and "size" -// is the size of the message. You should not expect the data is -// terminated with '\0'. -GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( - void (*writer)(const char* data, int size)); - -} - -#endif // _LOGGING_H_ diff --git a/third_party/src/glog/src/windows/glog/raw_logging.h b/third_party/src/glog/src/windows/glog/raw_logging.h deleted file mode 100644 index 4757a719..00000000 --- a/third_party/src/glog/src/windows/glog/raw_logging.h +++ /dev/null @@ -1,189 +0,0 @@ -// This file is automatically generated from src/glog/raw_logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// 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: Maxim Lifantsev -// -// Thread-safe logging routines that do not allocate any memory or -// acquire any locks, and can therefore be used by low-level memory -// allocation and synchronization code. - -#ifndef BASE_RAW_LOGGING_H_ -#define BASE_RAW_LOGGING_H_ - -#include - -namespace google { - -#include "glog/log_severity.h" -#include "glog/vlog_is_on.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -// This is similar to LOG(severity) << format... and VLOG(level) << format.., -// but -// * it is to be used ONLY by low-level modules that can't use normal LOG() -// * it is desiged to be a low-level logger that does not allocate any -// memory and does not need any locks, hence: -// * it logs straight and ONLY to STDERR w/o buffering -// * it uses an explicit format and arguments list -// * it will silently chop off really long message strings -// Usage example: -// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); -// RAW_VLOG(3, "status is %i", status); -// These will print an almost standard log lines like this to stderr only: -// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file -// I0821 211317 file.cc:142] RAW: status is 20 -#define RAW_LOG(severity, ...) \ - do { \ - switch (google::GLOG_ ## severity) { \ - case 0: \ - RAW_LOG_INFO(__VA_ARGS__); \ - break; \ - case 1: \ - RAW_LOG_WARNING(__VA_ARGS__); \ - break; \ - case 2: \ - RAW_LOG_ERROR(__VA_ARGS__); \ - break; \ - case 3: \ - RAW_LOG_FATAL(__VA_ARGS__); \ - break; \ - default: \ - break; \ - } \ - } while (0) - -// The following STRIP_LOG testing is performed in the header file so that it's -// possible to completely compile out the logging code and the log messages. -#if STRIP_LOG == 0 -#define RAW_VLOG(verboselevel, ...) \ - do { \ - if (VLOG_IS_ON(verboselevel)) { \ - RAW_LOG_INFO(__VA_ARGS__); \ - } \ - } while (0) -#else -#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG == 0 -#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if STRIP_LOG <= 1 -#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 1 - -#if STRIP_LOG <= 2 -#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 2 - -#if STRIP_LOG <= 3 -#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_FATAL(...) \ - do { \ - google::RawLogStub__(0, __VA_ARGS__); \ - exit(1); \ - } while (0) -#endif // STRIP_LOG <= 3 - -// Similar to CHECK(condition) << message, -// but for low-level modules: we use only RAW_LOG that does not allocate memory. -// We do not want to provide args list here to encourage this usage: -// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); -// so that the args are not computed when not needed. -#define RAW_CHECK(condition, message) \ - do { \ - if (!(condition)) { \ - RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ - } \ - } while (0) - -// Debug versions of RAW_LOG and RAW_CHECK -#ifndef NDEBUG - -#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) - -#else // NDEBUG - -#define RAW_DLOG(severity, ...) \ - while (false) \ - RAW_LOG(severity, __VA_ARGS__) -#define RAW_DCHECK(condition, message) \ - while (false) \ - RAW_CHECK(condition, message) - -#endif // NDEBUG - -// Stub log function used to work around for unused variable warnings when -// building with STRIP_LOG > 0. -static inline void RawLogStub__(int /* ignored */, ...) { -} - -// Helper function to implement RAW_LOG and RAW_VLOG -// Logs format... at "severity" level, reporting it -// as called from file:line. -// This does not allocate memory or acquire locks. -GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, - const char* file, - int line, - const char* format, ...) - ; - -// Hack to propagate time information into this module so that -// this module does not have to directly call localtime_r(), -// which could allocate memory. -GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs); - -} - -#endif // BASE_RAW_LOGGING_H_ diff --git a/third_party/src/glog/src/windows/glog/stl_logging.h b/third_party/src/glog/src/windows/glog/stl_logging.h deleted file mode 100644 index d2e74956..00000000 --- a/third_party/src/glog/src/windows/glog/stl_logging.h +++ /dev/null @@ -1,187 +0,0 @@ -// This file is automatically generated from src/glog/stl_logging.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 2003, 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. -// -// Stream output operators for STL containers; to be used for logging *only*. -// Inclusion of this file lets you do: -// -// list x; -// LOG(INFO) << "data: " << x; -// vector v1, v2; -// CHECK_EQ(v1, v2); - -#ifndef UTIL_GTL_STL_LOGGING_INL_H_ -#define UTIL_GTL_STL_LOGGING_INL_H_ - -#if !1 -# error We do not support stl_logging for this compiler -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -# include -# include -# include -#endif - -// Forward declare these two, and define them after all the container streams -// operators so that we can recurse from pair -> container -> container -> pair -// properly. -template -std::ostream& operator<<(std::ostream& out, const std::pair& p); - -namespace google { - -template -void PrintSequence(std::ostream& out, Iter begin, Iter end); - -} - -#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_TWO_ARG_CONTAINER(std::vector) -OUTPUT_TWO_ARG_CONTAINER(std::deque) -OUTPUT_TWO_ARG_CONTAINER(std::list) -#ifdef __GNUC__ -OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist) -#endif - -#undef OUTPUT_TWO_ARG_CONTAINER - -#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_THREE_ARG_CONTAINER(std::set) -OUTPUT_THREE_ARG_CONTAINER(std::multiset) - -#undef OUTPUT_THREE_ARG_CONTAINER - -#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_FOUR_ARG_CONTAINER(std::map) -OUTPUT_FOUR_ARG_CONTAINER(std::multimap) -#ifdef __GNUC__ -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set) -OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset) -#endif - -#undef OUTPUT_FOUR_ARG_CONTAINER - -#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - google::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -#ifdef __GNUC__ -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map) -OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap) -#endif - -#undef OUTPUT_FIVE_ARG_CONTAINER - -template -inline std::ostream& operator<<(std::ostream& out, - const std::pair& p) { - out << '(' << p.first << ", " << p.second << ')'; - return out; -} - -namespace google { - -template -inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { - // Output at most 100 elements -- appropriate if used for logging. - for (int i = 0; begin != end && i < 100; ++i, ++begin) { - if (i > 0) out << ' '; - out << *begin; - } - if (begin != end) { - out << " ..."; - } -} - -} - -// Note that this is technically undefined behavior! We are adding things into -// the std namespace for a reason though -- we are providing new operations on -// types which are themselves defined with this namespace. Without this, these -// operator overloads cannot be found via ADL. If these definitions are not -// found via ADL, they must be #included before they're used, which requires -// this header to be included before apparently independent other headers. -// -// For example, base/logging.h defines various template functions to implement -// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails. -// It does so via the function template MakeCheckOpValueString: -// template -// void MakeCheckOpValueString(strstream* ss, const T& v) { -// (*ss) << v; -// } -// Because 'glog/logging.h' is included before 'glog/stl_logging.h', -// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only -// find these operator definitions via ADL. -// -// Even this solution has problems -- it may pull unintended operators into the -// namespace as well, allowing them to also be found via ADL, and creating code -// that only works with a particular order of includes. Long term, we need to -// move all of the *definitions* into namespace std, bet we need to ensure no -// one references them first. This lets us take that step. We cannot define them -// in both because that would create ambiguous overloads when both are found. -namespace std { using ::operator<<; } - -#endif // UTIL_GTL_STL_LOGGING_INL_H_ diff --git a/third_party/src/glog/src/windows/glog/vlog_is_on.h b/third_party/src/glog/src/windows/glog/vlog_is_on.h deleted file mode 100644 index 409a4011..00000000 --- a/third_party/src/glog/src/windows/glog/vlog_is_on.h +++ /dev/null @@ -1,133 +0,0 @@ -// This file is automatically generated from src/glog/vlog_is_on.h.in -// using src/windows/preprocess.sh. -// DO NOT EDIT! - -// Copyright (c) 1999, 2007, 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: Ray Sidney and many others -// -// Defines the VLOG_IS_ON macro that controls the variable-verbosity -// conditional logging. -// -// It's used by VLOG and VLOG_IF in logging.h -// and by RAW_VLOG in raw_logging.h to trigger the logging. -// -// It can also be used directly e.g. like this: -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished e.g. via just VLOG(2) << ...; -// } -// -// The truth value that VLOG_IS_ON(level) returns is determined by -// the three verbosity level flags: -// --v= Gives the default maximal active V-logging level; -// 0 is the default. -// Normally positive values are used for V-logging levels. -// --vmodule= Gives the per-module maximal V-logging levels to override -// the value given by --v. -// E.g. "my_module=2,foo*=3" would change the logging level -// for all code in source files "my_module.*" and "foo*.*" -// ("-inl" suffixes are also disregarded for this matching). -// -// SetVLOGLevel helper function is provided to do limited dynamic control over -// V-logging by overriding the per-module settings given via --vmodule flag. -// -// CAVEAT: --vmodule functionality is not available in non gcc compilers. -// - -#ifndef BASE_VLOG_IS_ON_H_ -#define BASE_VLOG_IS_ON_H_ - -#include "glog/log_severity.h" - -// Annoying stuff for windows -- makes sure clients can import these functions -#ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) -# else -# define GOOGLE_GLOG_DLL_DECL -# endif -#endif - -#if defined(__GNUC__) -// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. -// (Normally) the first time every VLOG_IS_ON(n) site is hit, -// we determine what variable will dynamically control logging at this site: -// it's either FLAGS_v or an appropriate internal variable -// matching the current source file that represents results of -// parsing of --vmodule flag and/or SetVLOGLevel calls. -#define VLOG_IS_ON(verboselevel) \ - __extension__ \ - ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ - google::int32 verbose_level__ = (verboselevel); \ - (*vlocal__ >= verbose_level__) && \ - ((vlocal__ != &google::kLogSiteUninitialized) || \ - (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ - __FILE__, verbose_level__))); }) -#else -// GNU extensions not available, so we do not support --vmodule. -// Dynamic value of FLAGS_v always controls the logging level. -#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) -#endif - -// Set VLOG(_IS_ON) level for module_pattern to log_level. -// This lets us dynamically control what is normally set by the --vmodule flag. -// Returns the level that previously applied to module_pattern. -// NOTE: To change the log level for VLOG(_IS_ON) sites -// that have already executed after/during InitGoogleLogging, -// one needs to supply the exact --vmodule pattern that applied to them. -// (If no --vmodule pattern applied to them -// the value of FLAGS_v will continue to control them.) -extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, - int log_level); - -// Various declarations needed for VLOG_IS_ON above: ========================= - -// Special value used to indicate that a VLOG_IS_ON site has not been -// initialized. We make this a large value, so the common-case check -// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition -// passes in such cases and InitVLOG3__ is then triggered. -extern google::int32 kLogSiteUninitialized; - -// Helper routine which determines the logging info for a particalur VLOG site. -// site_flag is the address of the site-local pointer to the controlling -// verbosity level -// site_default is the default to use for *site_flag -// fname is the current source file name -// verbose_level is the argument to VLOG_IS_ON -// We will return the return value for VLOG_IS_ON -// and if possible set *site_flag appropriately. -extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( - google::int32** site_flag, - google::int32* site_default, - const char* fname, - google::int32 verbose_level); - -#endif // BASE_VLOG_IS_ON_H_ diff --git a/third_party/src/glog/src/windows/logging.cc b/third_party/src/glog/src/windows/logging.cc deleted file mode 100644 index 5c09a660..00000000 --- a/third_party/src/glog/src/windows/logging.cc +++ /dev/null @@ -1,2050 +0,0 @@ -// Copyright (c) 1999, 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. - -#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite() - -#include "utilities.h" - -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include // For _exit. -#endif -#include -#include -#include -#ifdef HAVE_SYS_UTSNAME_H -# include // For uname. -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_PWD_H -# include -#endif -#ifdef HAVE_SYSLOG_H -# include -#endif -#include -#include // for errno -#include -#include "base/commandlineflags.h" // to get the program name -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -using std::string; -using std::vector; -using std::setw; -using std::setfill; -using std::hex; -using std::dec; -using std::min; -using std::ostream; -using std::ostringstream; - -using std::FILE; -using std::fwrite; -using std::fclose; -using std::fflush; -using std::fprintf; -using std::perror; - -#ifdef __QNX__ -using std::fdopen; -#endif - -// There is no thread annotation support. -#define EXCLUSIVE_LOCKS_REQUIRED(mu) - -static bool BoolFromEnv(const char *varname, bool defval) { - const char* const valstr = getenv(varname); - if (!valstr) { - return defval; - } - return memchr("tTyY1\0", valstr[0], 6) != NULL; -} - -GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), - "log messages go to stderr instead of logfiles"); -GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), - "log messages go to stderr in addition to logfiles"); -GLOG_DEFINE_bool(colorlogtostderr, false, - "color messages logged to stderr (if supported by terminal)"); -#ifdef OS_LINUX -GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " - "Logs can grow very quickly and they are rarely read before they " - "need to be evicted from memory. Instead, drop them from memory " - "as soon as they are flushed to disk."); -_START_GOOGLE_NAMESPACE_ -namespace logging { -static const int64 kPageSize = getpagesize(); -} -_END_GOOGLE_NAMESPACE_ -#endif - -// By default, errors (including fatal errors) get logged to stderr as -// well as the file. -// -// The default is ERROR instead of FATAL so that users can see problems -// when they run a program without having to look in another file. -DEFINE_int32(stderrthreshold, - GOOGLE_NAMESPACE::GLOG_ERROR, - "log messages at or above this level are copied to stderr in " - "addition to logfiles. This flag obsoletes --alsologtostderr."); - -GLOG_DEFINE_string(alsologtoemail, "", - "log messages go to these email addresses " - "in addition to logfiles"); -GLOG_DEFINE_bool(log_prefix, true, - "Prepend the log prefix to the start of each log line"); -GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " - "actually get logged anywhere"); -GLOG_DEFINE_int32(logbuflevel, 0, - "Buffer log messages logged at this level or lower" - " (-1 means don't buffer; 0 means buffer INFO only;" - " ...)"); -GLOG_DEFINE_int32(logbufsecs, 30, - "Buffer log messages for at most this many seconds"); -GLOG_DEFINE_int32(logemaillevel, 999, - "Email log messages logged at this level or higher" - " (0 means email all; 3 means email FATAL only;" - " ...)"); -GLOG_DEFINE_string(logmailer, "/bin/mail", - "Mailer used to send logging email"); - -// Compute the default value for --log_dir -static const char* DefaultLogDir() { - const char* env; - env = getenv("GOOGLE_LOG_DIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - env = getenv("TEST_TMPDIR"); - if (env != NULL && env[0] != '\0') { - return env; - } - return ""; -} - -GLOG_DEFINE_string(log_dir, DefaultLogDir(), - "If specified, logfiles are written into this directory instead " - "of the default logging directory."); -GLOG_DEFINE_string(log_link, "", "Put additional links to the log " - "files in this directory"); - -GLOG_DEFINE_int32(max_log_size, 1800, - "approx. maximum log file size (in MB). A value of 0 will " - "be silently overridden to 1."); - -GLOG_DEFINE_bool(stop_logging_if_full_disk, false, - "Stop attempting to log to disk if the disk is full."); - -GLOG_DEFINE_string(log_backtrace_at, "", - "Emit a backtrace when logging at file:linenum."); - -// TODO(hamaji): consider windows -#define PATH_SEPARATOR '/' - -static void GetHostName(string* hostname) { -#if defined(HAVE_SYS_UTSNAME_H) - struct utsname buf; - if (0 != uname(&buf)) { - // ensure null termination on failure - *buf.nodename = '\0'; - } - *hostname = buf.nodename; -#elif defined(OS_WINDOWS) - char buf[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD len = MAX_COMPUTERNAME_LENGTH + 1; - if (GetComputerNameA(buf, &len)) { - *hostname = buf; - } else { - hostname->clear(); - } -#else -# warning There is no way to retrieve the host name. - *hostname = "(unknown)"; -#endif -} - -// Returns true iff terminal supports using colors in output. -static bool TerminalSupportsColor() { - bool term_supports_color = false; -#ifdef OS_WINDOWS - // on Windows TERM variable is usually not set, but the console does - // support colors. - term_supports_color = true; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = getenv("TERM"); - if (term != NULL && term[0] != '\0') { - term_supports_color = - !strcmp(term, "xterm") || - !strcmp(term, "xterm-color") || - !strcmp(term, "xterm-256color") || - !strcmp(term, "screen") || - !strcmp(term, "linux") || - !strcmp(term, "cygwin"); - } -#endif - return term_supports_color; -} - -_START_GOOGLE_NAMESPACE_ - -enum GLogColor { - COLOR_DEFAULT, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW -}; - -static GLogColor SeverityToColor(LogSeverity severity) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - GLogColor color = COLOR_DEFAULT; - switch (severity) { - case GLOG_INFO: - color = COLOR_DEFAULT; - break; - case GLOG_WARNING: - color = COLOR_YELLOW; - break; - case GLOG_ERROR: - case GLOG_FATAL: - color = COLOR_RED; - break; - default: - // should never get here. - assert(false); - } - return color; -} - -#ifdef OS_WINDOWS - -// Returns the character attribute for the given color. -WORD GetColorAttribute(GLogColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; - } -} - -#else - -// Returns the ANSI color code for the given color. -const char* GetAnsiColorCode(GLogColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - case COLOR_DEFAULT: return ""; - }; - return NULL; // stop warning about return type. -} - -#endif // OS_WINDOWS - -// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 -static int32 MaxLogSize() { - return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); -} - -struct LogMessage::LogMessageData { - LogMessageData() {}; - - int preserved_errno_; // preserved errno - char* buf_; // buffer space for non FATAL messages - char* message_text_; // Complete message text (points to selected buffer) - LogStream* stream_alloc_; - LogStream* stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - ~LogMessageData(); - - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); -}; - -// A mutex that allows only one thread to log at a time, to keep things from -// getting jumbled. Some other very uncommon logging operations (like -// changing the destination file for log messages of a given severity) also -// lock this mutex. Please be sure that anybody who might possibly need to -// lock it does so. -static Mutex log_mutex; - -// Number of messages sent at each severity. Under log_mutex. -int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; - -// Globally disable log writing (if disk is full) -static bool stop_writing = false; - -const char*const LogSeverityNames[NUM_SEVERITIES] = { - "INFO", "WARNING", "ERROR", "FATAL" -}; - -// Has the user called SetExitOnDFatal(true)? -static bool exit_on_dfatal = true; - -const char* GetLogSeverityName(LogSeverity severity) { - return LogSeverityNames[severity]; -} - -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging); - -base::Logger::~Logger() { -} - -namespace { - -// Encapsulates all file-system related state -class LogFileObject : public base::Logger { - public: - LogFileObject(LogSeverity severity, const char* base_filename); - ~LogFileObject(); - - virtual void Write(bool force_flush, // Should we force a flush here? - time_t timestamp, // Timestamp for this entry - const char* message, - int message_len); - - // Configuration options - void SetBasename(const char* basename); - void SetExtension(const char* ext); - void SetSymlinkBasename(const char* symlink_basename); - - // Normal flushing routine - virtual void Flush(); - - // It is the actual file length for the system loggers, - // i.e., INFO, ERROR, etc. - virtual uint32 LogSize() { - MutexLock l(&lock_); - return file_length_; - } - - // Internal flush routine. Exposed so that FlushLogFilesUnsafe() - // can avoid grabbing a lock. Usually Flush() calls it after - // acquiring lock_. - void FlushUnlocked(); - - private: - static const uint32 kRolloverAttemptFrequency = 0x20; - - Mutex lock_; - bool base_filename_selected_; - string base_filename_; - string symlink_basename_; - string filename_extension_; // option users can specify (eg to add port#) - FILE* file_; - LogSeverity severity_; - uint32 bytes_since_flush_; - uint32 file_length_; - unsigned int rollover_attempt_; - int64 next_flush_time_; // cycle count at which to flush log - - // Actually create a logfile using the value of base_filename_ and the - // supplied argument time_pid_string - // REQUIRES: lock_ is held - bool CreateLogfile(const string& time_pid_string); -}; - -} // namespace - -class LogDestination { - public: - friend class LogMessage; - friend void ReprintFatalMessage(); - friend base::Logger* base::GetLogger(LogSeverity); - friend void base::SetLogger(LogSeverity, base::Logger*); - - // These methods are just forwarded to by their global versions. - static void SetLogDestination(LogSeverity severity, - const char* base_filename); - static void SetLogSymlink(LogSeverity severity, - const char* symlink_basename); - static void AddLogSink(LogSink *destination); - static void RemoveLogSink(LogSink *destination); - static void SetLogFilenameExtension(const char* filename_extension); - static void SetStderrLogging(LogSeverity min_severity); - static void SetEmailLogging(LogSeverity min_severity, const char* addresses); - static void LogToStderr(); - // Flush all log files that are at least at the given severity level - static void FlushLogFiles(int min_severity); - static void FlushLogFilesUnsafe(int min_severity); - - // we set the maximum size of our packet to be 1400, the logic being - // to prevent fragmentation. - // Really this number is arbitrary. - static const int kNetworkBytes = 1400; - - static const string& hostname(); - static const bool& terminal_supports_color() { - return terminal_supports_color_; - } - - static void DeleteLogDestinations(); - - private: - LogDestination(LogSeverity severity, const char* base_filename); - ~LogDestination() { } - - // Take a log message of a particular severity and log it to stderr - // iff it's of a high enough severity to deserve it. - static void MaybeLogToStderr(LogSeverity severity, const char* message, - size_t len); - - // Take a log message of a particular severity and log it to email - // iff it's of a high enough severity to deserve it. - static void MaybeLogToEmail(LogSeverity severity, const char* message, - size_t len); - // Take a log message of a particular severity and log it to a file - // iff the base filename is not "" (which means "don't log to me") - static void MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - // Take a log message of a particular severity and log it to the file - // for that severity and also for all files with severity less than - // this severity. - static void LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, size_t len); - - // Send logging info to all registered sinks. - static void LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len); - - // Wait for all registered sinks via WaitTillSent - // including the optional one in "data". - static void WaitForSinks(LogMessage::LogMessageData* data); - - static LogDestination* log_destination(LogSeverity severity); - - LogFileObject fileobject_; - base::Logger* logger_; // Either &fileobject_, or wrapper around it - - static LogDestination* log_destinations_[NUM_SEVERITIES]; - static LogSeverity email_logging_severity_; - static string addresses_; - static string hostname_; - static bool terminal_supports_color_; - - // arbitrary global logging destinations. - static vector* sinks_; - - // Protects the vector sinks_, - // but not the LogSink objects its elements reference. - static Mutex sink_mutex_; - - // Disallow - LogDestination(const LogDestination&); - LogDestination& operator=(const LogDestination&); -}; - -// Errors do not get logged to email by default. -LogSeverity LogDestination::email_logging_severity_ = 99999; - -string LogDestination::addresses_; -string LogDestination::hostname_; - -vector* LogDestination::sinks_ = NULL; -Mutex LogDestination::sink_mutex_; -bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); - -/* static */ -const string& LogDestination::hostname() { - if (hostname_.empty()) { - GetHostName(&hostname_); - if (hostname_.empty()) { - hostname_ = "(unknown)"; - } - } - return hostname_; -} - -LogDestination::LogDestination(LogSeverity severity, - const char* base_filename) - : fileobject_(severity, base_filename), - logger_(&fileobject_) { -} - -inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { - // assume we have the log_mutex or we simply don't care - // about it - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destination(i); - if (log != NULL) { - // Flush the base fileobject_ logger directly instead of going - // through any wrappers to reduce chance of deadlock. - log->fileobject_.FlushUnlocked(); - } - } -} - -inline void LogDestination::FlushLogFiles(int min_severity) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for (int i = min_severity; i < NUM_SEVERITIES; i++) { - LogDestination* log = log_destination(i); - if (log != NULL) { - log->logger_->Flush(); - } - } -} - -inline void LogDestination::SetLogDestination(LogSeverity severity, - const char* base_filename) { - assert(severity >= 0 && severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetBasename(base_filename); -} - -inline void LogDestination::SetLogSymlink(LogSeverity severity, - const char* symlink_basename) { - CHECK_GE(severity, 0); - CHECK_LT(severity, NUM_SEVERITIES); - MutexLock l(&log_mutex); - log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); -} - -inline void LogDestination::AddLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - if (!sinks_) sinks_ = new vector; - sinks_->push_back(destination); -} - -inline void LogDestination::RemoveLogSink(LogSink *destination) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&sink_mutex_); - // This doesn't keep the sinks in order, but who cares? - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - if ((*sinks_)[i] == destination) { - (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; - sinks_->pop_back(); - break; - } - } - } -} - -inline void LogDestination::SetLogFilenameExtension(const char* ext) { - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { - log_destination(severity)->fileobject_.SetExtension(ext); - } -} - -inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - FLAGS_stderrthreshold = min_severity; -} - -inline void LogDestination::LogToStderr() { - // *Don't* put this stuff in a mutex lock, since SetStderrLogging & - // SetLogDestination already do the locking! - SetStderrLogging(0); // thus everything is "also" logged to stderr - for ( int i = 0; i < NUM_SEVERITIES; ++i ) { - SetLogDestination(i, ""); // "" turns off logging to a logfile - } -} - -inline void LogDestination::SetEmailLogging(LogSeverity min_severity, - const char* addresses) { - assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); - // Prevent any subtle race conditions by wrapping a mutex lock around - // all this stuff. - MutexLock l(&log_mutex); - LogDestination::email_logging_severity_ = min_severity; - LogDestination::addresses_ = addresses; -} - -static void ColoredWriteToStderr(LogSeverity severity, - const char* message, size_t len) { - const GLogColor color = - (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ? - SeverityToColor(severity) : COLOR_DEFAULT; - - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - if (COLOR_DEFAULT == color) { - fwrite(message, len, 1, stderr); - return; - } -#ifdef OS_WINDOWS - const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stderr_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stderr); - SetConsoleTextAttribute(stderr_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - fwrite(message, len, 1, stderr); - fflush(stderr); - // Restores the text color. - SetConsoleTextAttribute(stderr_handle, old_color_attrs); -#else - fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color)); - fwrite(message, len, 1, stderr); - fprintf(stderr, "\033[m"); // Resets the terminal to default. -#endif // OS_WINDOWS -} - -static void WriteToStderr(const char* message, size_t len) { - // Avoid using cerr from this module since we may get called during - // exit code, and cerr may be partially or fully destroyed by then. - fwrite(message, len, 1, stderr); -} - -inline void LogDestination::MaybeLogToStderr(LogSeverity severity, - const char* message, size_t len) { - if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { - ColoredWriteToStderr(severity, message, len); -#ifdef OS_WINDOWS - // On Windows, also output to the debugger - ::OutputDebugStringA(string(message,len).c_str()); -#endif - } -} - - -inline void LogDestination::MaybeLogToEmail(LogSeverity severity, - const char* message, size_t len) { - if (severity >= email_logging_severity_ || - severity >= FLAGS_logemaillevel) { - string to(FLAGS_alsologtoemail); - if (!addresses_.empty()) { - if (!to.empty()) { - to += ","; - } - to += addresses_; - } - const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + - glog_internal_namespace_::ProgramInvocationShortName()); - string body(hostname()); - body += "\n\n"; - body.append(message, len); - - // should NOT use SendEmail(). The caller of this function holds the - // log_mutex and SendEmail() calls LOG/VLOG which will block trying to - // acquire the log_mutex object. Use SendEmailInternal() and set - // use_logging to false. - SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); - } -} - - -inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - const bool should_flush = severity > FLAGS_logbuflevel; - LogDestination* destination = log_destination(severity); - destination->logger_->Write(should_flush, timestamp, message, len); -} - -inline void LogDestination::LogToAllLogfiles(LogSeverity severity, - time_t timestamp, - const char* message, - size_t len) { - - if ( FLAGS_logtostderr ) { // global flag: never log to file - ColoredWriteToStderr(severity, message, len); - } else { - for (int i = severity; i >= 0; --i) - LogDestination::MaybeLogToLogfile(i, timestamp, message, len); - } -} - -inline void LogDestination::LogToSinks(LogSeverity severity, - const char *full_filename, - const char *base_filename, - int line, - const struct ::tm* tm_time, - const char* message, - size_t message_len) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->send(severity, full_filename, base_filename, - line, tm_time, message, message_len); - } - } -} - -inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (int i = sinks_->size() - 1; i >= 0; i--) { - (*sinks_)[i]->WaitTillSent(); - } - } - const bool send_to_sink = - (data->send_method_ == &LogMessage::SendToSink) || - (data->send_method_ == &LogMessage::SendToSinkAndLog); - if (send_to_sink && data->sink_ != NULL) { - data->sink_->WaitTillSent(); - } -} - -LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; - -inline LogDestination* LogDestination::log_destination(LogSeverity severity) { - assert(severity >=0 && severity < NUM_SEVERITIES); - if (!log_destinations_[severity]) { - log_destinations_[severity] = new LogDestination(severity, NULL); - } - return log_destinations_[severity]; -} - -void LogDestination::DeleteLogDestinations() { - for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { - delete log_destinations_[severity]; - log_destinations_[severity] = NULL; - } -} - -namespace { - -LogFileObject::LogFileObject(LogSeverity severity, - const char* base_filename) - : base_filename_selected_(base_filename != NULL), - base_filename_((base_filename != NULL) ? base_filename : ""), - symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), - filename_extension_(), - file_(NULL), - severity_(severity), - bytes_since_flush_(0), - file_length_(0), - rollover_attempt_(kRolloverAttemptFrequency-1), - next_flush_time_(0) { - assert(severity >= 0); - assert(severity < NUM_SEVERITIES); -} - -LogFileObject::~LogFileObject() { - MutexLock l(&lock_); - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - } -} - -void LogFileObject::SetBasename(const char* basename) { - MutexLock l(&lock_); - base_filename_selected_ = true; - if (base_filename_ != basename) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - base_filename_ = basename; - } -} - -void LogFileObject::SetExtension(const char* ext) { - MutexLock l(&lock_); - if (filename_extension_ != ext) { - // Get rid of old log file since we are changing names - if (file_ != NULL) { - fclose(file_); - file_ = NULL; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - filename_extension_ = ext; - } -} - -void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { - MutexLock l(&lock_); - symlink_basename_ = symlink_basename; -} - -void LogFileObject::Flush() { - MutexLock l(&lock_); - FlushUnlocked(); -} - -void LogFileObject::FlushUnlocked(){ - if (file_ != NULL) { - fflush(file_); - bytes_since_flush_ = 0; - } - // Figure out when we are due for another flush. - const int64 next = (FLAGS_logbufsecs - * static_cast(1000000)); // in usec - next_flush_time_ = CycleClock_Now() + UsecToCycles(next); -} - -bool LogFileObject::CreateLogfile(const string& time_pid_string) { - string string_filename = base_filename_+filename_extension_+ - time_pid_string; - const char* filename = string_filename.c_str(); - int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664); - if (fd == -1) return false; -#ifdef HAVE_FCNTL - // Mark the file close-on-exec. We don't really care if this fails - fcntl(fd, F_SETFD, FD_CLOEXEC); -#endif - - file_ = fdopen(fd, "a"); // Make a FILE*. - if (file_ == NULL) { // Man, we're screwed! - close(fd); - unlink(filename); // Erase the half-baked evidence: an unusable log file - return false; - } - - // We try to create a symlink called ., - // which is easier to use. (Every time we create a new logfile, - // we destroy the old symlink and create a new one, so it always - // points to the latest logfile.) If it fails, we're sad but it's - // no error. - if (!symlink_basename_.empty()) { - // take directory from filename - const char* slash = strrchr(filename, PATH_SEPARATOR); - const string linkname = - symlink_basename_ + '.' + LogSeverityNames[severity_]; - string linkpath; - if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname - linkpath += linkname; - unlink(linkpath.c_str()); // delete old one if it exists - - // We must have unistd.h. -#ifdef HAVE_UNISTD_H - // Make the symlink be relative (in the same dir) so that if the - // entire log directory gets relocated the link is still valid. - const char *linkdest = slash ? (slash + 1) : filename; - if (symlink(linkdest, linkpath.c_str()) != 0) { - // silently ignore failures - } - - // Make an additional link to the log file in a place specified by - // FLAGS_log_link, if indicated - if (!FLAGS_log_link.empty()) { - linkpath = FLAGS_log_link + "/" + linkname; - unlink(linkpath.c_str()); // delete old one if it exists - if (symlink(filename, linkpath.c_str()) != 0) { - // silently ignore failures - } - } -#endif - } - - return true; // Everything worked -} - -void LogFileObject::Write(bool force_flush, - time_t timestamp, - const char* message, - int message_len) { - MutexLock l(&lock_); - - // We don't log if the base_name_ is "" (which means "don't write") - if (base_filename_selected_ && base_filename_.empty()) { - return; - } - - if (static_cast(file_length_ >> 20) >= MaxLogSize() || - PidHasChanged()) { - if (file_ != NULL) fclose(file_); - file_ = NULL; - file_length_ = bytes_since_flush_ = 0; - rollover_attempt_ = kRolloverAttemptFrequency-1; - } - - // If there's no destination file, make one before outputting - if (file_ == NULL) { - // Try to rollover the log file every 32 log messages. The only time - // this could matter would be when we have trouble creating the log - // file. If that happens, we'll lose lots of log messages, of course! - if (++rollover_attempt_ != kRolloverAttemptFrequency) return; - rollover_attempt_ = 0; - - struct ::tm tm_time; - localtime_r(×tamp, &tm_time); - - // The logfile's filename will have the date/time & pid in it - ostringstream time_pid_stream; - time_pid_stream.fill('0'); - time_pid_stream << 1900+tm_time.tm_year - << setw(2) << 1+tm_time.tm_mon - << setw(2) << tm_time.tm_mday - << '-' - << setw(2) << tm_time.tm_hour - << setw(2) << tm_time.tm_min - << setw(2) << tm_time.tm_sec - << '.' - << GetMainThreadPid(); - const string& time_pid_string = time_pid_stream.str(); - - if (base_filename_selected_) { - if (!CreateLogfile(time_pid_string)) { - perror("Could not create log file"); - fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", - time_pid_string.c_str()); - return; - } - } else { - // If no base filename for logs of this severity has been set, use a - // default base filename of - // "...log..". So - // logfiles will have names like - // webserver.examplehost.root.log.INFO.19990817-150000.4354, where - // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), - // and 4354 is the pid of the logging process. The date & time reflect - // when the file was created for output. - // - // Where does the file get put? Successively try the directories - // "/tmp", and "." - string stripped_filename( - glog_internal_namespace_::ProgramInvocationShortName()); - string hostname; - GetHostName(&hostname); - - string uidname = MyUserName(); - // We should not call CHECK() here because this function can be - // called after holding on to log_mutex. We don't want to - // attempt to hold on to the same mutex, and get into a - // deadlock. Simply use a name like invalid-user. - if (uidname.empty()) uidname = "invalid-user"; - - stripped_filename = stripped_filename+'.'+hostname+'.' - +uidname+".log." - +LogSeverityNames[severity_]+'.'; - // We're going to (potentially) try to put logs in several different dirs - const vector & log_dirs = GetLoggingDirectories(); - - // Go through the list of dirs, and try to create the log file in each - // until we succeed or run out of options - bool success = false; - for (vector::const_iterator dir = log_dirs.begin(); - dir != log_dirs.end(); - ++dir) { - base_filename_ = *dir + "/" + stripped_filename; - if ( CreateLogfile(time_pid_string) ) { - success = true; - break; - } - } - // If we never succeeded, we have to give up - if ( success == false ) { - perror("Could not create logging file"); - fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", - time_pid_string.c_str()); - return; - } - } - - // Write a header message into the log file - ostringstream file_header_stream; - file_header_stream.fill('0'); - file_header_stream << "Log file created at: " - << 1900+tm_time.tm_year << '/' - << setw(2) << 1+tm_time.tm_mon << '/' - << setw(2) << tm_time.tm_mday - << ' ' - << setw(2) << tm_time.tm_hour << ':' - << setw(2) << tm_time.tm_min << ':' - << setw(2) << tm_time.tm_sec << '\n' - << "Running on machine: " - << LogDestination::hostname() << '\n' - << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " - << "threadid file:line] msg" << '\n'; - const string& file_header_string = file_header_stream.str(); - - const int header_len = file_header_string.size(); - fwrite(file_header_string.data(), 1, header_len, file_); - file_length_ += header_len; - bytes_since_flush_ += header_len; - } - - // Write to LOG file - if ( !stop_writing ) { - // fwrite() doesn't return an error when the disk is full, for - // messages that are less than 4096 bytes. When the disk is full, - // it returns the message length for messages that are less than - // 4096 bytes. fwrite() returns 4096 for message lengths that are - // greater than 4096, thereby indicating an error. - errno = 0; - fwrite(message, 1, message_len, file_); - if ( FLAGS_stop_logging_if_full_disk && - errno == ENOSPC ) { // disk full, stop writing to disk - stop_writing = true; // until the disk is - return; - } else { - file_length_ += message_len; - bytes_since_flush_ += message_len; - } - } else { - if ( CycleClock_Now() >= next_flush_time_ ) - stop_writing = false; // check to see if disk has free space. - return; // no need to flush - } - - // See important msgs *now*. Also, flush logs at least every 10^6 chars, - // or every "FLAGS_logbufsecs" seconds. - if ( force_flush || - (bytes_since_flush_ >= 1000000) || - (CycleClock_Now() >= next_flush_time_) ) { - FlushUnlocked(); -#ifdef OS_LINUX - if (FLAGS_drop_log_memory) { - if (file_length_ >= logging::kPageSize) { - // don't evict the most recent page - uint32 len = file_length_ & ~(logging::kPageSize - 1); - posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED); - } - } -#endif - } -} - -} // namespace - -// An arbitrary limit on the length of a single log message. This -// is so that streaming can be done more efficiently. -const size_t LogMessage::kMaxLogMessageLen = 30000; - -// Static log data space to avoid alloc failures in a LOG(FATAL) -// -// Since multiple threads may call LOG(FATAL), and we want to preserve -// the data from the first call, we allocate two sets of space. One -// for exclusive use by the first thread, and one for shared use by -// all other threads. -static Mutex fatal_msg_lock; -static CrashReason crash_reason; -static bool fatal_msg_exclusive = true; -static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1]; -static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1]; -static LogMessage::LogStream fatal_msg_stream_exclusive( - fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0); -static LogMessage::LogStream fatal_msg_stream_shared( - fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0); -static LogMessage::LogMessageData fatal_msg_data_exclusive; -static LogMessage::LogMessageData fatal_msg_data_shared; - -LogMessage::LogMessageData::~LogMessageData() { - delete[] buf_; - delete stream_alloc_; -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - int ctr, void (LogMessage::*send_method)()) - : allocated_(NULL) { - Init(file, line, severity, send_method); - data_->stream_->set_ctr(ctr); -} - -LogMessage::LogMessage(const char* file, int line, - const CheckOpString& result) - : allocated_(NULL) { - Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); - stream() << "Check failed: " << (*result.str_) << " "; -} - -LogMessage::LogMessage(const char* file, int line) - : allocated_(NULL) { - Init(file, line, GLOG_INFO, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SendToLog); -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - LogSink* sink, bool also_send_to_log) - : allocated_(NULL) { - Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : - &LogMessage::SendToSink); - data_->sink_ = sink; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - vector *outvec) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::SaveOrSendToLog); - data_->outvec_ = outvec; // override Init()'s setting to NULL -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - string *message) - : allocated_(NULL) { - Init(file, line, severity, &LogMessage::WriteToStringAndLog); - data_->message_ = message; // override Init()'s setting to NULL -} - -void LogMessage::Init(const char* file, - int line, - LogSeverity severity, - void (LogMessage::*send_method)()) { - allocated_ = NULL; - if (severity != GLOG_FATAL || !exit_on_dfatal) { - allocated_ = new LogMessageData(); - data_ = allocated_; - data_->buf_ = new char[kMaxLogMessageLen+1]; - data_->message_text_ = data_->buf_; - data_->stream_alloc_ = - new LogStream(data_->message_text_, kMaxLogMessageLen, 0); - data_->stream_ = data_->stream_alloc_; - data_->first_fatal_ = false; - } else { - MutexLock l(&fatal_msg_lock); - if (fatal_msg_exclusive) { - fatal_msg_exclusive = false; - data_ = &fatal_msg_data_exclusive; - data_->message_text_ = fatal_msg_buf_exclusive; - data_->stream_ = &fatal_msg_stream_exclusive; - data_->first_fatal_ = true; - } else { - data_ = &fatal_msg_data_shared; - data_->message_text_ = fatal_msg_buf_shared; - data_->stream_ = &fatal_msg_stream_shared; - data_->first_fatal_ = false; - } - data_->stream_alloc_ = NULL; - } - - stream().fill('0'); - data_->preserved_errno_ = errno; - data_->severity_ = severity; - data_->line_ = line; - data_->send_method_ = send_method; - data_->sink_ = NULL; - data_->outvec_ = NULL; - WallTime now = WallTime_Now(); - data_->timestamp_ = static_cast(now); - localtime_r(&data_->timestamp_, &data_->tm_time_); - int usecs = static_cast((now - data_->timestamp_) * 1000000); - RawLog__SetLastTime(data_->tm_time_, usecs); - - data_->num_chars_to_log_ = 0; - data_->num_chars_to_syslog_ = 0; - data_->basename_ = const_basename(file); - data_->fullname_ = file; - data_->has_been_flushed_ = false; - - // If specified, prepend a prefix to each line. For example: - // I1018 160715 f5d4fbb0 logging.cc:1153] - // (log level, GMT month, date, time, thread_id, file basename, line) - // We exclude the thread_id for the default thread. - if (FLAGS_log_prefix && (line != kNoLogPrefix)) { - stream() << LogSeverityNames[severity][0] - << setw(2) << 1+data_->tm_time_.tm_mon - << setw(2) << data_->tm_time_.tm_mday - << ' ' - << setw(2) << data_->tm_time_.tm_hour << ':' - << setw(2) << data_->tm_time_.tm_min << ':' - << setw(2) << data_->tm_time_.tm_sec << "." - << setw(6) << usecs - << ' ' - << setfill(' ') << setw(5) - << static_cast(GetTID()) << setfill('0') - << ' ' - << data_->basename_ << ':' << data_->line_ << "] "; - } - data_->num_prefix_chars_ = data_->stream_->pcount(); - - if (!FLAGS_log_backtrace_at.empty()) { - char fileline[128]; - snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); -#ifdef HAVE_STACKTRACE - if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { - string stacktrace; - DumpStackTraceToString(&stacktrace); - stream() << " (stacktrace:\n" << stacktrace << ") "; - } -#endif - } -} - -LogMessage::~LogMessage() { - Flush(); - delete allocated_; -} - -int LogMessage::preserved_errno() const { - return data_->preserved_errno_; -} - -ostream& LogMessage::stream() { - return *(data_->stream_); -} - -// Flush buffered message, called by the destructor, or any other function -// that needs to synchronize the log. -void LogMessage::Flush() { - if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) - return; - - data_->num_chars_to_log_ = data_->stream_->pcount(); - data_->num_chars_to_syslog_ = - data_->num_chars_to_log_ - data_->num_prefix_chars_; - - // Do we need to add a \n to the end of this message? - bool append_newline = - (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); - char original_final_char = '\0'; - - // If we do need to add a \n, we'll do it by violating the memory of the - // ostrstream buffer. This is quick, and we'll make sure to undo our - // modification before anything else is done with the ostrstream. It - // would be preferable not to do things this way, but it seems to be - // the best way to deal with this. - if (append_newline) { - original_final_char = data_->message_text_[data_->num_chars_to_log_]; - data_->message_text_[data_->num_chars_to_log_++] = '\n'; - } - - // Prevent any subtle race conditions by wrapping a mutex lock around - // the actual logging action per se. - { - MutexLock l(&log_mutex); - (this->*(data_->send_method_))(); - ++num_messages_[static_cast(data_->severity_)]; - } - LogDestination::WaitForSinks(data_); - - if (append_newline) { - // Fix the ostrstream back how it was before we screwed with it. - // It's 99.44% certain that we don't need to worry about doing this. - data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; - } - - // If errno was already set before we enter the logging call, we'll - // set it back to that value when we return from the logging call. - // It happens often that we log an error message after a syscall - // failure, which can potentially set the errno to some other - // values. We would like to preserve the original errno. - if (data_->preserved_errno_ != 0) { - errno = data_->preserved_errno_; - } - - // Note that this message is now safely logged. If we're asked to flush - // again, as a result of destruction, say, we'll do nothing on future calls. - data_->has_been_flushed_ = true; -} - -// Copy of first FATAL log message so that we can print it out again -// after all the stack traces. To preserve legacy behavior, we don't -// use fatal_msg_buf_exclusive. -static time_t fatal_time; -static char fatal_message[256]; - -void ReprintFatalMessage() { - if (fatal_message[0]) { - const int n = strlen(fatal_message); - if (!FLAGS_logtostderr) { - // Also write to stderr (don't color to avoid terminal checks) - WriteToStderr(fatal_message, n); - } - LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - static bool already_warned_before_initgoogle = false; - - log_mutex.AssertHeld(); - - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - - // Messages of a given severity get logged to lower severity logs, too - - if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { - const char w[] = "WARNING: Logging before InitGoogleLogging() is " - "written to STDERR\n"; - WriteToStderr(w, strlen(w)); - already_warned_before_initgoogle = true; - } - - // global flag: never log to file if set. Also -- don't log to a - // file if we haven't parsed the command line flags to get the - // program name. - if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { - ColoredWriteToStderr(data_->severity_, - data_->message_text_, data_->num_chars_to_log_); - - // this could be protected by a flag if necessary. - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - } else { - - // log this message to all log files of severity <= severity_ - LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, - data_->message_text_, - data_->num_chars_to_log_); - - LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - // NOTE: -1 removes trailing \n - } - - // If we log a FATAL message, flush all the log destinations, then toss - // a signal for others to catch. We leave the logs in a state that - // someone else can use them (as long as they flush afterwards) - if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) { - if (data_->first_fatal_) { - // Store crash information so that it is accessible from within signal - // handlers that may be invoked later. - RecordCrashReason(&crash_reason); - SetCrashReason(&crash_reason); - - // Store shortened fatal message for other logs and GWQ status - const int copy = min(data_->num_chars_to_log_, - sizeof(fatal_message)-1); - memcpy(fatal_message, data_->message_text_, copy); - fatal_message[copy] = '\0'; - fatal_time = data_->timestamp_; - } - - if (!FLAGS_logtostderr) { - for (int i = 0; i < NUM_SEVERITIES; ++i) { - if ( LogDestination::log_destinations_[i] ) - LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); - } - } - - // release the lock that our caller (directly or indirectly) - // LogMessage::~LogMessage() grabbed so that signal handlers - // can use the logging facility. Alternately, we could add - // an entire unsafe logging interface to bypass locking - // for signal handlers but this seems simpler. - log_mutex.Unlock(); - LogDestination::WaitForSinks(data_); - - const char* message = "*** Check failure stack trace: ***\n"; - if (write(STDERR_FILENO, message, strlen(message)) < 0) { - // Ignore errors. - } - Fail(); - } -} - -void LogMessage::RecordCrashReason( - glog_internal_namespace_::CrashReason* reason) { - reason->filename = fatal_msg_data_exclusive.fullname_; - reason->line_number = fatal_msg_data_exclusive.line_; - reason->message = fatal_msg_buf_exclusive + - fatal_msg_data_exclusive.num_prefix_chars_; -#ifdef HAVE_STACKTRACE - // Retrieve the stack trace, omitting the logging frames that got us here. - reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); -#else - reason->depth = 0; -#endif -} - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NORETURN __attribute__((noreturn)) -#else -# define ATTRIBUTE_NORETURN -#endif - -static void logging_fail() ATTRIBUTE_NORETURN; - -static void logging_fail() { -#if defined(_DEBUG) && defined(_MSC_VER) && defined(_M_IX86) - // When debugging on windows, avoid the obnoxious dialog and make - // it possible to continue past a LOG(FATAL) in the debugger - _asm int 3 -#else - abort(); -#endif -} - -typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN; - -GOOGLE_GLOG_DLL_DECL -logging_fail_func_t g_logging_fail_func = &logging_fail; - -void InstallFailureFunction(void (*fail_func)()) { - g_logging_fail_func = (logging_fail_func_t)fail_func; -} - -void LogMessage::Fail() { - g_logging_fail_func(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->sink_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, - data_->line_, &data_->tm_time_, - data_->message_text_ + data_->num_prefix_chars_, - (data_->num_chars_to_log_ - - data_->num_prefix_chars_ - 1)); - } -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - SendToSink(); - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->outvec_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when recording in outvec_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->outvec_->push_back(string(start, len)); - } else { - SendToLog(); - } -} - -void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { - if (data_->message_ != NULL) { - RAW_DCHECK(data_->num_chars_to_log_ > 0 && - data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); - // Omit prefix of message and trailing newline when writing to message_. - const char *start = data_->message_text_ + data_->num_prefix_chars_; - int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; - data_->message_->assign(start, len); - } - SendToLog(); -} - -// L >= log_mutex (callers must hold the log_mutex). -void LogMessage::SendToSyslogAndLog() { -#ifdef HAVE_SYSLOG_H - // Before any calls to syslog(), make a single call to openlog() - static bool openlog_already_called = false; - if (!openlog_already_called) { - openlog(glog_internal_namespace_::ProgramInvocationShortName(), - LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_USER); - openlog_already_called = true; - } - - // This array maps Google severity levels to syslog levels - const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; - syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast(data_->severity_)], "%.*s", - int(data_->num_chars_to_syslog_), - data_->message_text_ + data_->num_prefix_chars_); - SendToLog(); -#else - LOG(ERROR) << "No syslog support: message=" << data_->message_text_; -#endif -} - -base::Logger* base::GetLogger(LogSeverity severity) { - MutexLock l(&log_mutex); - return LogDestination::log_destination(severity)->logger_; -} - -void base::SetLogger(LogSeverity severity, base::Logger* logger) { - MutexLock l(&log_mutex); - LogDestination::log_destination(severity)->logger_ = logger; -} - -// L < log_mutex. Acquires and releases mutex_. -int64 LogMessage::num_messages(int severity) { - MutexLock l(&log_mutex); - return num_messages_[severity]; -} - -// Output the COUNTER value. This is only valid if ostream is a -// LogStream. -ostream& operator<<(ostream &os, const PRIVATE_Counter&) { -#ifdef DISABLE_RTTI - LogMessage::LogStream *log = static_cast(&os); -#else - LogMessage::LogStream *log = dynamic_cast(&os); -#endif - CHECK(log && log == log->self()) - << "You must not use COUNTER with non-glog ostream"; - os << log->ctr(); - return os; -} - -ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, - LogSeverity severity, int ctr, - void (LogMessage::*send_method)()) - : LogMessage(file, line, severity, ctr, send_method) { -} - -ErrnoLogMessage::~ErrnoLogMessage() { - // Don't access errno directly because it may have been altered - // while streaming the message. - char buf[100]; - posix_strerror_r(preserved_errno(), buf, sizeof(buf)); - stream() << ": " << buf << " [" << preserved_errno() << "]"; -} - -void FlushLogFiles(LogSeverity min_severity) { - LogDestination::FlushLogFiles(min_severity); -} - -void FlushLogFilesUnsafe(LogSeverity min_severity) { - LogDestination::FlushLogFilesUnsafe(min_severity); -} - -void SetLogDestination(LogSeverity severity, const char* base_filename) { - LogDestination::SetLogDestination(severity, base_filename); -} - -void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { - LogDestination::SetLogSymlink(severity, symlink_basename); -} - -LogSink::~LogSink() { -} - -void LogSink::WaitTillSent() { - // noop default -} - -string LogSink::ToString(LogSeverity severity, const char* file, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - ostringstream stream(string(message, message_len)); - stream.fill('0'); - - // FIXME(jrvb): Updating this to use the correct value for usecs - // requires changing the signature for both this method and - // LogSink::send(). This change needs to be done in a separate CL - // so subclasses of LogSink can be updated at the same time. - int usecs = 0; - - stream << LogSeverityNames[severity][0] - << setw(2) << 1+tm_time->tm_mon - << setw(2) << tm_time->tm_mday - << ' ' - << setw(2) << tm_time->tm_hour << ':' - << setw(2) << tm_time->tm_min << ':' - << setw(2) << tm_time->tm_sec << '.' - << setw(6) << usecs - << ' ' - << setfill(' ') << setw(5) << GetTID() << setfill('0') - << ' ' - << file << ':' << line << "] "; - - stream << string(message, message_len); - return stream.str(); -} - -void AddLogSink(LogSink *destination) { - LogDestination::AddLogSink(destination); -} - -void RemoveLogSink(LogSink *destination) { - LogDestination::RemoveLogSink(destination); -} - -void SetLogFilenameExtension(const char* ext) { - LogDestination::SetLogFilenameExtension(ext); -} - -void SetStderrLogging(LogSeverity min_severity) { - LogDestination::SetStderrLogging(min_severity); -} - -void SetEmailLogging(LogSeverity min_severity, const char* addresses) { - LogDestination::SetEmailLogging(min_severity, addresses); -} - -void LogToStderr() { - LogDestination::LogToStderr(); -} - -namespace base { -namespace internal { - -bool GetExitOnDFatal() { - MutexLock l(&log_mutex); - return exit_on_dfatal; -} - -// Determines whether we exit the program for a LOG(DFATAL) message in -// debug mode. It does this by skipping the call to Fail/FailQuietly. -// This is intended for testing only. -// -// This can have some effects on LOG(FATAL) as well. Failure messages -// are always allocated (rather than sharing a buffer), the crash -// reason is not recorded, the "gwq" status message is not updated, -// and the stack trace is not recorded. The LOG(FATAL) *will* still -// exit the program. Since this function is used only in testing, -// these differences are acceptable. -void SetExitOnDFatal(bool value) { - MutexLock l(&log_mutex); - exit_on_dfatal = value; -} - -} // namespace internal -} // namespace base - -// use_logging controls whether the logging functions LOG/VLOG are used -// to log errors. It should be set to false when the caller holds the -// log_mutex. -static bool SendEmailInternal(const char*dest, const char *subject, - const char*body, bool use_logging) { - if (dest && *dest) { - if ( use_logging ) { - VLOG(1) << "Trying to send TITLE:" << subject - << " BODY:" << body << " to " << dest; - } else { - fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", - subject, body, dest); - } - - string cmd = - FLAGS_logmailer + " -s\"" + subject + "\" " + dest; - FILE* pipe = popen(cmd.c_str(), "w"); - if (pipe != NULL) { - // Add the body if we have one - if (body) - fwrite(body, sizeof(char), strlen(body), pipe); - bool ok = pclose(pipe) != -1; - if ( !ok ) { - if ( use_logging ) { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf; - } else { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf); - } - } - return ok; - } else { - if ( use_logging ) { - LOG(ERROR) << "Unable to send mail to " << dest; - } else { - fprintf(stderr, "Unable to send mail to %s\n", dest); - } - } - } - return false; -} - -bool SendEmail(const char*dest, const char *subject, const char*body){ - return SendEmailInternal(dest, subject, body, true); -} - -static void GetTempDirectories(vector* list) { - list->clear(); -#ifdef OS_WINDOWS - // On windows we'll try to find a directory in this order: - // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) - // C:/TMP/ - // C:/TEMP/ - // C:/WINDOWS/ or C:/WINNT/ - // . - char tmp[MAX_PATH]; - if (GetTempPathA(MAX_PATH, tmp)) - list->push_back(tmp); - list->push_back("C:\\tmp\\"); - list->push_back("C:\\temp\\"); -#else - // Directories, in order of preference. If we find a dir that - // exists, we stop adding other less-preferred dirs - const char * candidates[] = { - // Non-null only during unittest/regtest - getenv("TEST_TMPDIR"), - - // Explicitly-supplied temp dirs - getenv("TMPDIR"), getenv("TMP"), - - // If all else fails - "/tmp", - }; - - for (size_t i = 0; i < ARRAYSIZE(candidates); i++) { - const char *d = candidates[i]; - if (!d) continue; // Empty env var - - // Make sure we don't surprise anyone who's expecting a '/' - string dstr = d; - if (dstr[dstr.size() - 1] != '/') { - dstr += "/"; - } - list->push_back(dstr); - - struct stat statbuf; - if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { - // We found a dir that exists - we're done. - return; - } - } - -#endif -} - -static vector* logging_directories_list; - -const vector& GetLoggingDirectories() { - // Not strictly thread-safe but we're called early in InitGoogle(). - if (logging_directories_list == NULL) { - logging_directories_list = new vector; - - if ( !FLAGS_log_dir.empty() ) { - // A dir was specified, we should use it - logging_directories_list->push_back(FLAGS_log_dir.c_str()); - } else { - GetTempDirectories(logging_directories_list); -#ifdef OS_WINDOWS - char tmp[MAX_PATH]; - if (GetWindowsDirectoryA(tmp, MAX_PATH)) - logging_directories_list->push_back(tmp); - logging_directories_list->push_back(".\\"); -#else - logging_directories_list->push_back("./"); -#endif - } - } - return *logging_directories_list; -} - -void TestOnly_ClearLoggingDirectoriesList() { - fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " - "called from test code.\n"); - delete logging_directories_list; - logging_directories_list = NULL; -} - -void GetExistingTempDirectories(vector* list) { - GetTempDirectories(list); - vector::iterator i_dir = list->begin(); - while( i_dir != list->end() ) { - // zero arg to access means test for existence; no constant - // defined on windows - if ( access(i_dir->c_str(), 0) ) { - i_dir = list->erase(i_dir); - } else { - ++i_dir; - } - } -} - -void TruncateLogFile(const char *path, int64 limit, int64 keep) { -#ifdef HAVE_UNISTD_H - struct stat statbuf; - const int kCopyBlockSize = 8 << 10; - char copybuf[kCopyBlockSize]; - int64 read_offset, write_offset; - // Don't follow symlinks unless they're our own fd symlinks in /proc - int flags = O_RDWR; - const char *procfd_prefix = "/proc/self/fd/"; - if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; - - int fd = open(path, flags); - if (fd == -1) { - if (errno == EFBIG) { - // The log file in question has got too big for us to open. The - // real fix for this would be to compile logging.cc (or probably - // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's - // rather scary. - // Instead just truncate the file to something we can manage - if (truncate(path, 0) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } else { - LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; - } - } else { - PLOG(ERROR) << "Unable to open " << path; - } - return; - } - - if (fstat(fd, &statbuf) == -1) { - PLOG(ERROR) << "Unable to fstat()"; - goto out_close_fd; - } - - // See if the path refers to a regular file bigger than the - // specified limit - if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; - if (statbuf.st_size <= limit) goto out_close_fd; - if (statbuf.st_size <= keep) goto out_close_fd; - - // This log file is too large - we need to truncate it - LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; - - // Copy the last "keep" bytes of the file to the beginning of the file - read_offset = statbuf.st_size - keep; - write_offset = 0; - int bytesin, bytesout; - while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { - bytesout = pwrite(fd, copybuf, bytesin, write_offset); - if (bytesout == -1) { - PLOG(ERROR) << "Unable to write to " << path; - break; - } else if (bytesout != bytesin) { - LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; - } - read_offset += bytesin; - write_offset += bytesout; - } - if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; - - // Truncate the remainder of the file. If someone else writes to the - // end of the file after our last read() above, we lose their latest - // data. Too bad ... - if (ftruncate(fd, write_offset) == -1) { - PLOG(ERROR) << "Unable to truncate " << path; - } - - out_close_fd: - close(fd); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - -void TruncateStdoutStderr() { -#ifdef HAVE_UNISTD_H - int64 limit = MaxLogSize() << 20; - int64 keep = 1 << 20; - TruncateLogFile("/proc/self/fd/1", limit, keep); - TruncateLogFile("/proc/self/fd/2", limit, keep); -#else - LOG(ERROR) << "No log truncation support."; -#endif -} - - -// Helper functions for string comparisons. -#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ - string* Check##func##expected##Impl(const char* s1, const char* s2, \ - const char* names) { \ - bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ - if (equal == expected) return NULL; \ - else { \ - ostringstream ss; \ - if (!s1) s1 = ""; \ - if (!s2) s2 = ""; \ - ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ - return new string(ss.str()); \ - } \ - } -DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) -DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) -#undef DEFINE_CHECK_STROP_IMPL - -int posix_strerror_r(int err, char *buf, size_t len) { - // Sanity check input parameters - if (buf == NULL || len <= 0) { - errno = EINVAL; - return -1; - } - - // Reset buf and errno, and try calling whatever version of strerror_r() - // is implemented by glibc - buf[0] = '\000'; - int old_errno = errno; - errno = 0; - char *rc = reinterpret_cast(strerror_r(err, buf, len)); - - // Both versions set errno on failure - if (errno) { - // Should already be there, but better safe than sorry - buf[0] = '\000'; - return -1; - } - errno = old_errno; - - // POSIX is vague about whether the string will be terminated, although - // is indirectly implies that typically ERANGE will be returned, instead - // of truncating the string. This is different from the GNU implementation. - // We play it safe by always terminating the string explicitly. - buf[len-1] = '\000'; - - // If the function succeeded, we can use its exit code to determine the - // semantics implemented by glibc - if (!rc) { - return 0; - } else { - // GNU semantics detected - if (rc == buf) { - return 0; - } else { - buf[0] = '\000'; -#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) - if (reinterpret_cast(rc) < sys_nerr) { - // This means an error on MacOSX or FreeBSD. - return -1; - } -#endif - strncat(buf, rc, len-1); - return 0; - } - } -} - -LogMessageFatal::LogMessageFatal(const char* file, int line) : - LogMessage(file, line, GLOG_FATAL) {} - -LogMessageFatal::LogMessageFatal(const char* file, int line, - const CheckOpString& result) : - LogMessage(file, line, result) {} - -LogMessageFatal::~LogMessageFatal() { - Flush(); - LogMessage::Fail(); -} - -namespace base { - -CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext) - : stream_(new ostringstream) { - *stream_ << exprtext << " ("; -} - -CheckOpMessageBuilder::~CheckOpMessageBuilder() { - delete stream_; -} - -ostream* CheckOpMessageBuilder::ForVar2() { - *stream_ << " vs. "; - return stream_; -} - -string* CheckOpMessageBuilder::NewString() { - *stream_ << ")"; - return new string(stream_->str()); -} - -} // namespace base - -template <> -void MakeCheckOpValueString(std::ostream* os, const char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const signed char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "signed char value " << (short)v; - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "unsigned char value " << (unsigned short)v; - } -} - -void InitGoogleLogging(const char* argv0) { - glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); -} - -void ShutdownGoogleLogging() { - glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); - LogDestination::DeleteLogDestinations(); - delete logging_directories_list; - logging_directories_list = NULL; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/windows/port.cc b/third_party/src/glog/src/windows/port.cc deleted file mode 100644 index d9943254..00000000 --- a/third_party/src/glog/src/windows/port.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2008, 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: Craig Silverstein - * Copied from google-perftools and modified by Shinichiro Hamaji - */ - -#ifndef _WIN32 -# error You should only be including windows/port.cc in a windows environment! -#endif - -#include "config.h" -#include // for va_list, va_start, va_end -#include // for strstr() -#include -#include -#include -#include "port.h" - -using std::string; -using std::vector; - -// These call the windows _vsnprintf, but always NUL-terminate. -int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { - if (size == 0) // not even room for a \0? - return -1; // not what C99 says to do, but what windows does - str[size-1] = '\0'; - return _vsnprintf(str, size-1, format, ap); -} - -#ifndef HAVE_SNPRINTF -int snprintf(char *str, size_t size, const char *format, ...) { - va_list ap; - va_start(ap, format); - const int r = vsnprintf(str, size, format, ap); - va_end(ap); - return r; -} -#endif diff --git a/third_party/src/glog/src/windows/port.h b/third_party/src/glog/src/windows/port.h deleted file mode 100644 index 4f09c874..00000000 --- a/third_party/src/glog/src/windows/port.h +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (c) 2008, 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: Craig Silverstein - * Copied from google-perftools and modified by Shinichiro Hamaji - * - * These are some portability typedefs and defines to make it a bit - * easier to compile this code under VC++. - * - * Several of these are taken from glib: - * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html - */ - -#ifndef CTEMPLATE_WINDOWS_PORT_H_ -#define CTEMPLATE_WINDOWS_PORT_H_ - -#include "config.h" - -#ifdef _WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ -#endif - -#include -#include /* for gethostname */ -#include /* because we so often use open/close/etc */ -#include /* for _getcwd() */ -#include /* for _getpid() */ -#include /* read in vsnprintf decl. before redifining it */ -#include /* template_dictionary.cc uses va_copy */ -#include /* for _strnicmp(), strerror_s() */ -#include /* for localtime_s() */ -/* Note: the C++ #includes are all together at the bottom. This file is - * used by both C and C++ code, so we put all the C++ together. - */ - -/* 4244: otherwise we get problems when substracting two size_t's to an int - * 4251: it's complaining about a private struct I've chosen not to dllexport - * 4355: we use this in a constructor, but we do it safely - * 4715: for some reason VC++ stopped realizing you can't return after abort() - * 4800: we know we're casting ints/char*'s to bools, and we're ok with that - * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() - */ -#pragma warning(disable:4244 4251 4355 4715 4800 4996) - -/* file I/O */ -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif -#define access _access -#define getcwd _getcwd -#define open _open -#define read _read -#define write _write -#define lseek _lseek -#define close _close -#define popen _popen -#define pclose _pclose -#ifndef R_OK -#define R_OK 04 /* read-only (for access()) */ -#endif -#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) -#ifndef __MINGW32__ -enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; -#endif -#define S_IRUSR S_IREAD -#define S_IWUSR S_IWRITE - -/* Not quite as lightweight as a hard-link, but more than good enough for us. */ -#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false) - -#define strcasecmp _stricmp -#define strncasecmp _strnicmp - -/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */ -/* VC11 provides std::hash */ -#if defined(_MSC_VER) && (_MSC_VER < 1700) -#define hash hash_compare -#endif - -/* Sleep is in ms, on windows */ -#define sleep(secs) Sleep((secs) * 1000) - -/* We can't just use _vsnprintf and _snprintf as drop-in-replacements, - * because they don't always NUL-terminate. :-( We also can't use the - * name vsnprintf, since windows defines that (but not snprintf (!)). - */ -#ifndef HAVE_SNPRINTF -extern int snprintf(char *str, size_t size, - const char *format, ...); -#endif -extern int safe_vsnprintf(char *str, size_t size, - const char *format, va_list ap); -#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) -#ifndef va_copy -#define va_copy(dst, src) (dst) = (src) -#endif - -/* Windows doesn't support specifying the number of buckets as a - * hash_map constructor arg, so we leave this blank. - */ -#define CTEMPLATE_SMALL_HASHTABLE - -#define DEFAULT_TEMPLATE_ROOTDIR ".." - -// ----------------------------------- SYSTEM/PROCESS -#ifndef HAVE_PID_T -typedef int pid_t; -#endif -#define getpid _getpid - -// ----------------------------------- THREADS -typedef DWORD pthread_t; -typedef DWORD pthread_key_t; -typedef LONG pthread_once_t; -enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock -#define pthread_self GetCurrentThreadId -#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) - -inline struct tm* localtime_r(const time_t* timep, struct tm* result) { - localtime_s(result, timep); - return result; -} - -inline char* strerror_r(int errnum, char* buf, size_t buflen) { - strerror_s(buf, buflen, errnum); - return buf; -} - -#ifndef __cplusplus -/* I don't see how to get inlining for C code in MSVC. Ah well. */ -#define inline -#endif - -#endif /* _WIN32 */ - -#endif /* CTEMPLATE_WINDOWS_PORT_H_ */ diff --git a/third_party/src/glog/src/windows/preprocess.sh b/third_party/src/glog/src/windows/preprocess.sh deleted file mode 100644 index 5398988e..00000000 --- a/third_party/src/glog/src/windows/preprocess.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2008, 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: Craig Silverstein -# Copied from google-perftools and modified by Shinichiro Hamaji -# -# This script is meant to be run at distribution-generation time, for -# instance by autogen.sh. It does some of the work configure would -# normally do, for windows systems. In particular, it expands all the -# @...@ variables found in .in files, and puts them here, in the windows -# directory. -# -# This script should be run before any new release. - -if [ -z "$1" ]; then - echo "USAGE: $0 " - exit 1 -fi - -DLLDEF_MACRO_NAME="GLOG_DLL_DECL" - -# The text we put in every .h files we create. As a courtesy, we'll -# include a helpful comment for windows users as to how to use -# GLOG_DLL_DECL. Apparently sed expands \n into a newline. Good! -DLLDEF_DEFINES="\ -// NOTE: if you are statically linking the template library into your binary\n\ -// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\ -// as a compiler flag in your project file to turn off the dllimports.\n\ -#ifndef $DLLDEF_MACRO_NAME\n\ -# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\ -#endif" - -# Read all the windows config info into variables -# In order for the 'set' to take, this requires putting all in a subshell. -( - while read define varname value; do - [ "$define" != "#define" ] && continue - eval "$varname='$value'" - done - - # Process all the .in files in the "glog" subdirectory - mkdir -p "$1/windows/glog" - for file in `echo "$1"/glog/*.in`; do - echo "Processing $file" - outfile="$1/windows/glog/`basename $file .in`" - - echo "\ -// This file is automatically generated from $file -// using src/windows/preprocess.sh. -// DO NOT EDIT! -" > "$outfile" - # Besides replacing @...@, we also need to turn on dllimport - # We also need to replace hash by hash_compare (annoying we hard-code :-( ) - sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \ - -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \ - -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \ - -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \ - -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \ - -e "s!@ac_cv_have_stdint_h@!0!g" \ - -e "s!@ac_cv_have_systypes_h@!0!g" \ - -e "s!@ac_cv_have_inttypes_h@!0!g" \ - -e "s!@ac_cv_have_unistd_h@!0!g" \ - -e "s!@ac_cv_have_uint16_t@!0!g" \ - -e "s!@ac_cv_have_u_int16_t@!0!g" \ - -e "s!@ac_cv_have___uint16@!1!g" \ - -e "s!@ac_cv_have_libgflags@!0!g" \ - -e "s!@ac_cv_have___builtin_expect@!0!g" \ - -e "s!@ac_cv_cxx_using_operator@!1!g" \ - -e "s!@ac_cv___attribute___noreturn@!!g" \ - -e "s!@ac_cv___attribute___noinline@!!g" \ - -e "s!@ac_cv___attribute___printf_4_5@!!g" \ - -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \ - -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \ - -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \ - -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \ - -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \ - -e "s!\\bhash\\b!hash_compare!g" \ - "$file" >> "$outfile" - done -) < "$1/windows/config.h" - -# log_severity.h isn't a .in file. -echo "\ -// This file is automatically generated from $1/glog/log_severity.h -// using src/windows/preprocess.sh. -// DO NOT EDIT! -" > "$1/windows/glog/log_severity.h" -cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h" - -echo "DONE" diff --git a/third_party/src/glog/src/windows/raw_logging.cc b/third_party/src/glog/src/windows/raw_logging.cc deleted file mode 100644 index 7a7409bb..00000000 --- a/third_party/src/glog/src/windows/raw_logging.cc +++ /dev/null @@ -1,172 +0,0 @@ -// 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: Maxim Lifantsev -// -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include // for close() and write() -#endif -#include // for open() -#include -#include "config.h" -#include "glog/logging.h" // To pick up flag settings etc. -#include "glog/raw_logging.h" -#include "base/commandlineflags.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -#if defined(HAVE_SYSCALL_H) -#include // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include // for syscall() -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H) -# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len) -#else - // Not so safe, but what can you do? -# define safe_write(fd, s, len) write(fd, s, len) -#endif - -_START_GOOGLE_NAMESPACE_ - -// Data for RawLog__ below. We simply pick up the latest -// time data created by a normal log message to avoid calling -// localtime_r which can allocate memory. -static struct ::tm last_tm_time_for_raw_log; -static int last_usecs_for_raw_log; - -void RawLog__SetLastTime(const struct ::tm& t, int usecs) { - memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log)); - last_usecs_for_raw_log = usecs; -} - -// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths -// that invoke malloc() and getenv() that might acquire some locks. -// If this becomes a problem we should reimplement a subset of vsnprintf -// that does not need locks and malloc. - -// Helper for RawLog__ below. -// *DoRawLog writes to *buf of *size and move them past the written portion. -// It returns true iff there was no overflow or error. -static bool DoRawLog(char** buf, int* size, const char* format, ...) { - va_list ap; - va_start(ap, format); - int n = vsnprintf(*buf, *size, format, ap); - va_end(ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -// Helper for RawLog__ below. -inline static bool VADoRawLog(char** buf, int* size, - const char* format, va_list ap) { - int n = vsnprintf(*buf, *size, format, ap); - if (n < 0 || n > *size) return false; - *size -= n; - *buf += n; - return true; -} - -static const int kLogBufSize = 3000; -static bool crashed = false; -static CrashReason crash_reason; -static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0' - -void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) { - if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold || - FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) { - return; // this stderr log message is suppressed - } - // can't call localtime_r here: it can allocate - struct ::tm& t = last_tm_time_for_raw_log; - char buffer[kLogBufSize]; - char* buf = buffer; - int size = sizeof(buffer); - - // NOTE: this format should match the specification in base/logging.h - DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ", - LogSeverityNames[severity][0], - 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, - last_usecs_for_raw_log, - static_cast(GetTID()), - const_basename(const_cast(file)), line); - - // Record the position and size of the buffer after the prefix - const char* msg_start = buf; - const int msg_size = size; - - va_list ap; - va_start(ap, format); - bool no_chop = VADoRawLog(&buf, &size, format, ap); - va_end(ap); - if (no_chop) { - DoRawLog(&buf, &size, "\n"); - } else { - DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n"); - } - // We make a raw syscall to write directly to the stderr file descriptor, - // avoiding FILE buffering (to avoid invoking malloc()), and bypassing - // libc (to side-step any libc interception). - // We write just once to avoid races with other invocations of RawLog__. - safe_write(STDERR_FILENO, buffer, strlen(buffer)); - if (severity == GLOG_FATAL) { - if (!sync_val_compare_and_swap(&crashed, false, true)) { - crash_reason.filename = file; - crash_reason.line_number = line; - memcpy(crash_buf, msg_start, msg_size); // Don't include prefix - crash_reason.message = crash_buf; -#ifdef HAVE_STACKTRACE - crash_reason.depth = - GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1); -#else - crash_reason.depth = 0; -#endif - SetCrashReason(&crash_reason); - } - LogMessage::Fail(); // abort() - } -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/src/glog/src/windows/utilities.cc b/third_party/src/glog/src/windows/utilities.cc deleted file mode 100644 index a6d19617..00000000 --- a/third_party/src/glog/src/windows/utilities.cc +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright (c) 2008, 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: Shinichiro Hamaji - -#include "utilities.h" - -#include -#include - -#include -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include -#if defined(HAVE_SYSCALL_H) -#include // for syscall() -#elif defined(HAVE_SYS_SYSCALL_H) -#include // for syscall() -#endif -#ifdef HAVE_SYSLOG_H -# include -#endif - -#include "base/googleinit.h" - -using std::string; - -_START_GOOGLE_NAMESPACE_ - -static const char* g_program_invocation_short_name = NULL; -static pthread_t g_main_thread_id; - -_END_GOOGLE_NAMESPACE_ - -// The following APIs are all internal. -#ifdef HAVE_STACKTRACE - -#include "stacktrace.h" -#include "symbolize.h" -#include "base/commandlineflags.h" - -GLOG_DEFINE_bool(symbolize_stacktrace, true, - "Symbolize the stack trace in the tombstone"); - -_START_GOOGLE_NAMESPACE_ - -typedef void DebugWriter(const char*, void*); - -// The %p field width for printf() functions is two characters per byte. -// For some environments, add two extra bytes for the leading "0x". -static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*); - -static void DebugWriteToStderr(const char* data, void *) { - // This one is signal-safe. - if (write(STDERR_FILENO, data, strlen(data)) < 0) { - // Ignore errors. - } -} - -void DebugWriteToString(const char* data, void *arg) { - reinterpret_cast(arg)->append(data); -} - -#ifdef HAVE_SYMBOLIZE -// Print a program counter and its symbol name. -static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char tmp[1024]; - const char *symbol = "(unknown)"; - // Symbolizes the previous address of pc because pc may be in the - // next function. The overrun happens when the function ends with - // a call to a function annotated noreturn (e.g. CHECK). - if (Symbolize(reinterpret_cast(pc) - 1, tmp, sizeof(tmp))) { - symbol = tmp; - } - char buf[1024]; - snprintf(buf, sizeof(buf), "%s@ %*p %s\n", - prefix, kPrintfPointerFieldWidth, pc, symbol); - writerfn(buf, arg); -} -#endif - -static void DumpPC(DebugWriter *writerfn, void *arg, void *pc, - const char * const prefix) { - char buf[100]; - snprintf(buf, sizeof(buf), "%s@ %*p\n", - prefix, kPrintfPointerFieldWidth, pc); - writerfn(buf, arg); -} - -// Dump current stack trace as directed by writerfn -static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { - // Print stack trace - void* stack[32]; - int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1); - for (int i = 0; i < depth; i++) { -#if defined(HAVE_SYMBOLIZE) - if (FLAGS_symbolize_stacktrace) { - DumpPCAndSymbol(writerfn, arg, stack[i], " "); - } else { - DumpPC(writerfn, arg, stack[i], " "); - } -#else - DumpPC(writerfn, arg, stack[i], " "); -#endif - } -} - -static void DumpStackTraceAndExit() { - DumpStackTrace(1, DebugWriteToStderr, NULL); - - // Set the default signal handler for SIGABRT, to avoid invoking our - // own signal handler installed by InstallFailedSignalHandler(). - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sig_action.sa_handler = SIG_DFL; - sigaction(SIGABRT, &sig_action, NULL); - - abort(); -} - -_END_GOOGLE_NAMESPACE_ - -#endif // HAVE_STACKTRACE - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -const char* ProgramInvocationShortName() { - if (g_program_invocation_short_name != NULL) { - return g_program_invocation_short_name; - } else { - // TODO(hamaji): Use /proc/self/cmdline and so? - return "UNKNOWN"; - } -} - -bool IsGoogleLoggingInitialized() { - return g_program_invocation_short_name != NULL; -} - -bool is_default_thread() { - if (g_program_invocation_short_name == NULL) { - // InitGoogleLogging() not yet called, so unlikely to be in a different - // thread - return true; - } else { - return pthread_equal(pthread_self(), g_main_thread_id); - } -} - -#ifdef OS_WINDOWS -struct timeval { - long tv_sec, tv_usec; -}; - -// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd -// See COPYING for copyright information. -static int gettimeofday(struct timeval *tv, void* tz) { -#define EPOCHFILETIME (116444736000000000ULL) - FILETIME ft; - LARGE_INTEGER li; - uint64 tt; - - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - tt = (li.QuadPart - EPOCHFILETIME) / 10; - tv->tv_sec = tt / 1000000; - tv->tv_usec = tt % 1000000; - - return 0; -} -#endif - -int64 CycleClock_Now() { - // TODO(hamaji): temporary impementation - it might be too slow. - struct timeval tv; - gettimeofday(&tv, NULL); - return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; -} - -int64 UsecToCycles(int64 usec) { - return usec; -} - -WallTime WallTime_Now() { - // Now, cycle clock is retuning microseconds since the epoch. - return CycleClock_Now() * 0.000001; -} - -static int32 g_main_thread_pid = getpid(); -int32 GetMainThreadPid() { - return g_main_thread_pid; -} - -bool PidHasChanged() { - int32 pid = getpid(); - if (g_main_thread_pid == pid) { - return false; - } - g_main_thread_pid = pid; - return true; -} - -pid_t GetTID() { - // On Linux and MacOSX, we try to use gettid(). -#if defined OS_LINUX || defined OS_MACOSX -#ifndef __NR_gettid -#ifdef OS_MACOSX -#define __NR_gettid SYS_gettid -#elif ! defined __i386__ -#error "Must define __NR_gettid for non-x86 platforms" -#else -#define __NR_gettid 224 -#endif -#endif - static bool lacks_gettid = false; - if (!lacks_gettid) { - pid_t tid = syscall(__NR_gettid); - if (tid != -1) { - return tid; - } - // Technically, this variable has to be volatile, but there is a small - // performance penalty in accessing volatile variables and there should - // not be any serious adverse effect if a thread does not immediately see - // the value change to "true". - lacks_gettid = true; - } -#endif // OS_LINUX || OS_MACOSX - - // If gettid() could not be used, we use one of the following. -#if defined OS_LINUX - return getpid(); // Linux: getpid returns thread ID when gettid is absent -#elif defined OS_WINDOWS || defined OS_CYGWIN - return GetCurrentThreadId(); -#else - // If none of the techniques above worked, we use pthread_self(). - return (pid_t)(uintptr_t)pthread_self(); -#endif -} - -const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef OS_WINDOWS // Look for either path separator in Windows - if (!base) - base = strrchr(filepath, '\\'); -#endif - return base ? (base+1) : filepath; -} - -static string g_my_user_name; -const string& MyUserName() { - return g_my_user_name; -} -static void MyUserNameInitializer() { - // TODO(hamaji): Probably this is not portable. -#if defined(OS_WINDOWS) - const char* user = getenv("USERNAME"); -#else - const char* user = getenv("USER"); -#endif - if (user != NULL) { - g_my_user_name = user; - } else { - g_my_user_name = "invalid-user"; - } -} -REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()); - -#ifdef HAVE_STACKTRACE -void DumpStackTraceToString(string* stacktrace) { - DumpStackTrace(1, DebugWriteToString, stacktrace); -} -#endif - -// We use an atomic operation to prevent problems with calling CrashReason -// from inside the Mutex implementation (potentially through RAW_CHECK). -static const CrashReason* g_reason = 0; - -void SetCrashReason(const CrashReason* r) { - sync_val_compare_and_swap(&g_reason, - reinterpret_cast(0), - r); -} - -void InitGoogleLoggingUtilities(const char* argv0) { - CHECK(!IsGoogleLoggingInitialized()) - << "You called InitGoogleLogging() twice!"; - const char* slash = strrchr(argv0, '/'); -#ifdef OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); -#endif - g_program_invocation_short_name = slash ? slash + 1 : argv0; - g_main_thread_id = pthread_self(); - -#ifdef HAVE_STACKTRACE - InstallFailureFunction(&DumpStackTraceAndExit); -#endif -} - -void ShutdownGoogleLoggingUtilities() { - CHECK(IsGoogleLoggingInitialized()) - << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!"; - g_program_invocation_short_name = NULL; -#ifdef HAVE_SYSLOG_H - closelog(); -#endif -} - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -// Make an implementation of stacktrace compiled. -#ifdef STACKTRACE_H -# include STACKTRACE_H -#endif diff --git a/third_party/src/glog/src/windows/utilities.h b/third_party/src/glog/src/windows/utilities.h deleted file mode 100644 index 5f79968e..00000000 --- a/third_party/src/glog/src/windows/utilities.h +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2008, 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: Shinichiro Hamaji -// -// Define utilties for glog internal usage. - -#ifndef UTILITIES_H__ -#define UTILITIES_H__ - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# define OS_WINDOWS -#elif defined(__CYGWIN__) || defined(__CYGWIN32__) -# define OS_CYGWIN -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define OS_LINUX -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) -# define OS_MACOSX -#elif defined(__FreeBSD__) -# define OS_FREEBSD -#elif defined(__NetBSD__) -# define OS_NETBSD -#elif defined(__OpenBSD__) -# define OS_OPENBSD -#else -// TODO(hamaji): Add other platforms. -#endif - -// printf macros for size_t, in the style of inttypes.h -#ifdef _LP64 -#define __PRIS_PREFIX "z" -#else -#define __PRIS_PREFIX -#endif - -// Use these macros after a % in a printf format string -// to get correct 32/64 bit behavior, like this: -// size_t size = records.size(); -// printf("%"PRIuS"\n", size); - -#define PRIdS __PRIS_PREFIX "d" -#define PRIxS __PRIS_PREFIX "x" -#define PRIuS __PRIS_PREFIX "u" -#define PRIXS __PRIS_PREFIX "X" -#define PRIoS __PRIS_PREFIX "o" - -#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE - -#include - -#if defined(OS_WINDOWS) -# include "port.h" -#endif - -#include "config.h" -#include "glog/logging.h" - -// There are three different ways we can try to get the stack trace: -// -// 1) The libunwind library. This is still in development, and as a -// separate library adds a new dependency, but doesn't need a frame -// pointer. It also doesn't call malloc. -// -// 2) Our hand-coded stack-unwinder. This depends on a certain stack -// layout, which is used by gcc (and those systems using a -// gcc-compatible ABI) on x86 systems, at least since gcc 2.95. -// It uses the frame pointer to do its work. -// -// 3) The gdb unwinder -- also the one used by the c++ exception code. -// It's obviously well-tested, but has a fatal flaw: it can call -// malloc() from the unwinder. This is a problem because we're -// trying to use the unwinder to instrument malloc(). -// -// Note: if you add a new implementation here, make sure it works -// correctly when GetStackTrace() is called with max_depth == 0. -// Some code may do that. - -#if defined(HAVE_LIB_UNWIND) -# define STACKTRACE_H "stacktrace_libunwind-inl.h" -#elif !defined(NO_FRAME_POINTER) -# if defined(__i386__) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_x86-inl.h" -# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H -# define STACKTRACE_H "stacktrace_x86_64-inl.h" -# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_powerpc-inl.h" -# endif -#endif - -#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H) -# define STACKTRACE_H "stacktrace_generic-inl.h" -#endif - -#if defined(STACKTRACE_H) -# define HAVE_STACKTRACE -#endif - -// defined by gcc -#if defined(__ELF__) && defined(OS_LINUX) -# define HAVE_SYMBOLIZE -#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) -// Use dladdr to symbolize. -# define HAVE_SYMBOLIZE -#endif - -#ifndef ARRAYSIZE -// There is a better way, but this is good enough for our purpose. -# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) -#endif - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -#ifdef HAVE___ATTRIBUTE__ -# define ATTRIBUTE_NOINLINE __attribute__ ((noinline)) -# define HAVE_ATTRIBUTE_NOINLINE -#else -# define ATTRIBUTE_NOINLINE -#endif - -const char* ProgramInvocationShortName(); - -bool IsGoogleLoggingInitialized(); - -bool is_default_thread(); - -int64 CycleClock_Now(); - -int64 UsecToCycles(int64 usec); - -typedef double WallTime; -WallTime WallTime_Now(); - -int32 GetMainThreadPid(); -bool PidHasChanged(); - -pid_t GetTID(); - -const std::string& MyUserName(); - -// Get the part of filepath after the last path separator. -// (Doesn't modify filepath, contrary to basename() in libgen.h.) -const char* const_basename(const char* filepath); - -// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't -// defined, we try the CPU specific logics (we only support x86 and -// x86_64 for now) first, then use a naive implementation, which has a -// race condition. -template -inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) { -#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP) - return __sync_val_compare_and_swap(ptr, oldval, newval); -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - T ret; - __asm__ __volatile__("lock; cmpxchg %1, (%2);" - :"=a"(ret) - // GCC may produces %sil or %dil for - // constraint "r", but some of apple's gas - // dosn't know the 8 bit registers. - // We use "q" to avoid these registers. - :"q"(newval), "q"(ptr), "a"(oldval) - :"memory", "cc"); - return ret; -#else - T ret = *ptr; - if (ret == oldval) { - *ptr = newval; - } - return ret; -#endif -} - -void DumpStackTraceToString(std::string* stacktrace); - -struct CrashReason { - CrashReason() : filename(0), line_number(0), message(0), depth(0) {} - - const char* filename; - int line_number; - const char* message; - - // We'll also store a bit of stack trace context at the time of crash as - // it may not be available later on. - void* stack[32]; - int depth; -}; - -void SetCrashReason(const CrashReason* r); - -void InitGoogleLoggingUtilities(const char* argv0); -void ShutdownGoogleLoggingUtilities(); - -} // namespace glog_internal_namespace_ - -_END_GOOGLE_NAMESPACE_ - -using namespace GOOGLE_NAMESPACE::glog_internal_namespace_; - -#endif // UTILITIES_H__ diff --git a/third_party/src/glog/src/windows/vlog_is_on.cc b/third_party/src/glog/src/windows/vlog_is_on.cc deleted file mode 100644 index 8a79df50..00000000 --- a/third_party/src/glog/src/windows/vlog_is_on.cc +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 1999, 2007, 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: Ray Sidney and many others -// -// Broken out from logging.cc by Soren Lassen -// logging_unittest.cc covers the functionality herein - -#include "utilities.h" - -#include -#include -#include -#include -#include -#include "base/commandlineflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" -#include "base/googleinit.h" - -// glog doesn't have annotation -#define ANNOTATE_BENIGN_RACE(address, description) - -using std::string; - -GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this." -" Overridable by --vmodule."); - -GLOG_DEFINE_string(vmodule, "", "per-module verbose level." -" Argument is a comma-separated list of =." -" is a glob pattern, matched against the filename base" -" (that is, name ignoring .cc/.h./-inl.h)." -" overrides any value given by --v."); - -_START_GOOGLE_NAMESPACE_ - -namespace glog_internal_namespace_ { - -// Implementation of fnmatch that does not need 0-termination -// of arguments and does not allocate any memory, -// but we only support "*" and "?" wildcards, not the "[...]" patterns. -// It's not a static function for the unittest. -GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, - size_t patt_len, - const char* str, - size_t str_len) { - size_t p = 0; - size_t s = 0; - while (1) { - if (p == patt_len && s == str_len) return true; - if (p == patt_len) return false; - if (s == str_len) return p+1 == patt_len && pattern[p] == '*'; - if (pattern[p] == str[s] || pattern[p] == '?') { - p += 1; - s += 1; - continue; - } - if (pattern[p] == '*') { - if (p+1 == patt_len) return true; - do { - if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) { - return true; - } - s += 1; - } while (s != str_len); - return false; - } - return false; - } -} - -} // namespace glog_internal_namespace_ - -using glog_internal_namespace_::SafeFNMatch_; - -int32 kLogSiteUninitialized = 1000; - -// List of per-module log levels from FLAGS_vmodule. -// Once created each element is never deleted/modified -// except for the vlog_level: other threads will read VModuleInfo blobs -// w/o locks and we'll store pointers to vlog_level at VLOG locations -// that will never go away. -// We can't use an STL struct here as we wouldn't know -// when it's safe to delete/update it: other threads need to use it w/o locks. -struct VModuleInfo { - string module_pattern; - mutable int32 vlog_level; // Conceptually this is an AtomicWord, but it's - // too much work to use AtomicWord type here - // w/o much actual benefit. - const VModuleInfo* next; -}; - -// This protects the following global variables. -static Mutex vmodule_lock; -// Pointer to head of the VModuleInfo list. -// It's a map from module pattern to logging level for those module(s). -static VModuleInfo* vmodule_list = 0; -// Boolean initialization flag. -static bool inited_vmodule = false; - -// L >= vmodule_lock. -static void VLOG2Initializer() { - vmodule_lock.AssertHeld(); - // Can now parse --vmodule flag and initialize mapping of module-specific - // logging levels. - inited_vmodule = false; - const char* vmodule = FLAGS_vmodule.c_str(); - const char* sep; - VModuleInfo* head = NULL; - VModuleInfo* tail = NULL; - while ((sep = strchr(vmodule, '=')) != NULL) { - string pattern(vmodule, sep - vmodule); - int module_level; - if (sscanf(sep, "=%d", &module_level) == 1) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = pattern; - info->vlog_level = module_level; - if (head) tail->next = info; - else head = info; - tail = info; - } - // Skip past this entry - vmodule = strchr(sep, ','); - if (vmodule == NULL) break; - vmodule++; // Skip past "," - } - if (head) { // Put them into the list at the head: - tail->next = vmodule_list; - vmodule_list = head; - } - inited_vmodule = true; -} - -// This can be called very early, so we use SpinLock and RAW_VLOG here. -int SetVLOGLevel(const char* module_pattern, int log_level) { - int result = FLAGS_v; - int const pattern_len = strlen(module_pattern); - bool found = false; - MutexLock l(&vmodule_lock); // protect whole read-modify-write - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (info->module_pattern == module_pattern) { - if (!found) { - result = info->vlog_level; - found = true; - } - info->vlog_level = log_level; - } else if (!found && - SafeFNMatch_(info->module_pattern.c_str(), - info->module_pattern.size(), - module_pattern, pattern_len)) { - result = info->vlog_level; - found = true; - } - } - if (!found) { - VModuleInfo* info = new VModuleInfo; - info->module_pattern = module_pattern; - info->vlog_level = log_level; - info->next = vmodule_list; - vmodule_list = info; - } - RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level); - return result; -} - -// NOTE: Individual VLOG statements cache the integer log level pointers. -// NOTE: This function must not allocate memory or require any locks. -bool InitVLOG3__(int32** site_flag, int32* site_default, - const char* fname, int32 verbose_level) { - MutexLock l(&vmodule_lock); - bool read_vmodule_flag = inited_vmodule; - if (!read_vmodule_flag) { - VLOG2Initializer(); - } - - // protect the errno global in case someone writes: - // VLOG(..) << "The last error was " << strerror(errno) - int old_errno = errno; - - // site_default normally points to FLAGS_v - int32* site_flag_value = site_default; - - // Get basename for file - const char* base = strrchr(fname, '/'); - base = base ? (base+1) : fname; - const char* base_end = strchr(base, '.'); - size_t base_length = base_end ? size_t(base_end - base) : strlen(base); - - // Trim out trailing "-inl" if any - if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) { - base_length -= 4; - } - - // TODO: Trim out _unittest suffix? Perhaps it is better to have - // the extra control and just leave it there. - - // find target in vector of modules, replace site_flag_value with - // a module-specific verbose level, if any. - for (const VModuleInfo* info = vmodule_list; - info != NULL; info = info->next) { - if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(), - base, base_length)) { - site_flag_value = &info->vlog_level; - // value at info->vlog_level is now what controls - // the VLOG at the caller site forever - break; - } - } - - // Cache the vlog value pointer if --vmodule flag has been parsed. - ANNOTATE_BENIGN_RACE(site_flag, - "*site_flag may be written by several threads," - " but the value will be the same"); - if (read_vmodule_flag) *site_flag = site_flag_value; - - // restore the errno in case something recoverable went wrong during - // the initialization of the VLOG mechanism (see above note "protect the..") - errno = old_errno; - return *site_flag_value >= verbose_level; -} - -_END_GOOGLE_NAMESPACE_