diff --git a/.gitea/workflows/linux-aarch64-gcc.yml b/.gitea/workflows/linux-aarch64-gcc.yml index cb9514b..7102486 100644 --- a/.gitea/workflows/linux-aarch64-gcc.yml +++ b/.gitea/workflows/linux-aarch64-gcc.yml @@ -38,10 +38,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y g++-aarch64-linux-gnu qemu-user-binfmt + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y g++-aarch64-linux-gnu qemu-user-binfmt - name: configure run: | mkdir build && cd build @@ -53,6 +53,6 @@ jobs: - name: test run: |- cd build - # sudo ln -sf /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1 - # export LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib + sudo ln -sf /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1 + export LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib ctest --output-on-failure -j $(nproc) diff --git a/.gitea/workflows/linux-arm-gcc.yml b/.gitea/workflows/linux-arm-gcc.yml index 24506b0..0e747bb 100644 --- a/.gitea/workflows/linux-arm-gcc.yml +++ b/.gitea/workflows/linux-arm-gcc.yml @@ -79,6 +79,6 @@ jobs: - name: test run: |- cd build - # sudo ln -sf /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib/ld-linux-armhf.so.3 - #export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib/ + sudo ln -sf /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib/ld-linux-armhf.so.3 + export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib/ ctest --output-on-failure -j $(nproc) diff --git a/.gitea/workflows/linux-mips-gcc.yml b/.gitea/workflows/linux-mips-gcc.yml index 3b191b3..c59edef 100644 --- a/.gitea/workflows/linux-mips-gcc.yml +++ b/.gitea/workflows/linux-mips-gcc.yml @@ -35,10 +35,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y g++-mipsel-linux-gnu qemu-user-binfmt + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y g++-mipsel-linux-gnu qemu-user-binfmt - name: configure run: | mkdir build && cd build @@ -48,6 +48,6 @@ jobs: - name: test run: |- cd build - # sudo ln -sf /usr/mipsel-linux-gnu/lib/ld.so.1 /lib/ld.so.1 - # export LD_LIBRARY_PATH=/usr/mipsel-linux-gnu/lib/ + sudo ln -sf /usr/mipsel-linux-gnu/lib/ld.so.1 /lib/ld.so.1 + export LD_LIBRARY_PATH=/usr/mipsel-linux-gnu/lib/ ctest --output-on-failure -j $(nproc) diff --git a/.gitea/workflows/linux-mips64-gcc.yml b/.gitea/workflows/linux-mips64-gcc.yml index 96d82c5..a199aa9 100644 --- a/.gitea/workflows/linux-mips64-gcc.yml +++ b/.gitea/workflows/linux-mips64-gcc.yml @@ -36,10 +36,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y g++-mips64el-linux-gnuabi64 qemu-user-binfmt + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y g++-mips64el-linux-gnuabi64 qemu-user-binfmt - name: configure run: | mkdir build && cd build @@ -49,6 +49,6 @@ jobs: - name: test run: |- cd build - # sudo ln -sf /usr/mips64el-linux-gnuabi64/lib64/ld.so.1 /lib64/ld.so.1 - # export LD_LIBRARY_PATH=/usr/mips64el-linux-gnuabi64/lib + sudo ln -sf /usr/mips64el-linux-gnuabi64/lib64/ld.so.1 /lib64/ld.so.1 + export LD_LIBRARY_PATH=/usr/mips64el-linux-gnuabi64/lib ctest --output-on-failure -j $(nproc) diff --git a/.gitea/workflows/linux-riscv64-gcc.yml b/.gitea/workflows/linux-riscv64-gcc.yml index 61a829b..9e8be76 100644 --- a/.gitea/workflows/linux-riscv64-gcc.yml +++ b/.gitea/workflows/linux-riscv64-gcc.yml @@ -37,10 +37,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y g++-riscv64-linux-gnu qemu-user-binfmt + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y g++-riscv64-linux-gnu qemu-user-binfmt - name: configure run: | mkdir build && cd build @@ -50,6 +50,6 @@ jobs: - name: test run: |- cd build - # sudo ln -sf /usr/riscv64-linux-gnu/lib/ld-linux-riscv64-lp64d.so.1 /lib/ld-linux-riscv64-lp64d.so.1 - # export LD_LIBRARY_PATH=/usr/riscv64-linux-gnu/lib + sudo ln -sf /usr/riscv64-linux-gnu/lib/ld-linux-riscv64-lp64d.so.1 /lib/ld-linux-riscv64-lp64d.so.1 + export LD_LIBRARY_PATH=/usr/riscv64-linux-gnu/lib ctest --output-on-failure -j $(nproc) diff --git a/.gitea/workflows/linux-x64-clang.yml b/.gitea/workflows/linux-x64-clang.yml index 68373d5..0f282d0 100644 --- a/.gitea/workflows/linux-x64-clang.yml +++ b/.gitea/workflows/linux-x64-clang.yml @@ -29,10 +29,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y cmake make + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y cmake make - name: configure env: CC: clang diff --git a/.gitea/workflows/linux-x64-gcc.yml b/.gitea/workflows/linux-x64-gcc.yml index 0751dc1..752dcbd 100644 --- a/.gitea/workflows/linux-x64-gcc.yml +++ b/.gitea/workflows/linux-x64-gcc.yml @@ -33,10 +33,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - # - name: install-tools - # run: | - # sudo apt-get update -y - # sudo apt-get install -y cmake make + - name: install-tools + run: | + sudo apt-get update -y + sudo apt-get install -y cmake make - name: configure run: | mkdir build && cd build diff --git a/.gitignore b/.gitignore index 253e16b..6e95f64 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ out/ build/ .cache/ compile_commands.json +.gdb_history diff --git a/CMakeLists.txt b/CMakeLists.txt index 7631cc6..ea5994c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(tile_VERSION_BUILD $ENV{CI_STEP_NUMBER}) if (NOT tile_VERSION_BUILD) set(tile_VERSION_BUILD "0") endif() +set(TILE_VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}.${tile_VERSION_BUILD}") project( tile VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}" @@ -30,7 +31,7 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) endif() if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Debug") + set(CMAKE_BUILD_TYPE "Release") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -88,7 +89,7 @@ add_subdirectory("third_party/googletest") add_subdirectory("third_party/gflags") set(GFLAGS_USE_TARGET_NAMESPACE ON) set(gflags_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags") -add_subdirectory("third_party/glog") +# add_subdirectory("third_party/glog") # add_subdirectory("third_party/context") set(CURL_DISABLE_TESTS ON) @@ -166,6 +167,9 @@ set(TILE_SRCS "tile/base/internal/thread_pool.cc" "tile/base/internal/time_keeper.cc" "tile/base/internal/time_keeper.h" + "tile/base/logging/basic_file_sink.cc" + "tile/base/logging/splitter_sink.cc" + "tile/base/logging/console_sink.cc" "tile/base/net/endpoint.cc" "tile/base/object_pool/disabled.cc" "tile/base/object_pool/global.cc" @@ -216,7 +220,7 @@ if((NOT TILE_HAVE_GETIFADDRS) OR (NOT TILE_HAVE_FREEIFADDRS)) list(APPEND TILE_SRCS "tile/base/net/detail/android/ifaddrs.c") endif() -add_library(tile OBJECT ${TILE_SRCS}) +add_library(tile SHARED ${TILE_SRCS}) set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION} target_precompile_headers(tile PUBLIC inja/inja.h) target_precompile_headers(tile PUBLIC inja/string_view.h) @@ -229,8 +233,8 @@ target_include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/third_party/mustache.hpp" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include" - "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog" - "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src" + # "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog" + # "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src" "${CMAKE_CURRENT_SOURCE_DIR}" ${THIRD_PARTY_INCLUDE_DIRS} RPIVATE @@ -240,7 +244,7 @@ target_link_libraries( tile PUBLIC # -Wl,--start-group # nova_context - zlib gflags::gflags glog::glog + zlib gflags::gflags # glog::glog jsoncpp_static # -Wl,--end-group libcurl fmt) @@ -301,6 +305,7 @@ function(add_test_group prefix group_name) # convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}") file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}") string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}") + string(REPLACE "_test.cc" "_test" TEST_NAME "${TEST_NAME}") # if group_name is not empty, add suffix _ if (NOT group_name STREQUAL "") set(TEST_NAME "${group_name}_${TEST_NAME}") diff --git a/README.md b/README.md index d170901..4a0bddb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,3 @@ ## TILE 一个`C++11`工具库,集成常见的编码工具 - -## 编译状态 -[![status-badge](https://ci.uocat.com/api/badges/2/status.svg)](https://ci.uocat.com/repos/2) - - diff --git a/third_party/glog/.bazelci/presubmit.yml b/third_party/glog/.bazelci/presubmit.yml deleted file mode 100644 index 9065173..0000000 --- a/third_party/glog/.bazelci/presubmit.yml +++ /dev/null @@ -1,58 +0,0 @@ ---- -tasks: - ubuntu1804: - name: "Ubuntu 18.04" - platform: ubuntu1804 - build_flags: - - "--features=layering_check" - - "--copt=-Werror" - build_targets: - - "//..." - test_flags: - - "--features=layering_check" - - "--copt=-Werror" - test_targets: - - "//..." - macos: - name: "macOS: latest Xcode" - platform: macos - build_flags: - - "--features=layering_check" - - "--copt=-Werror" - build_targets: - - "//..." - test_flags: - - "--features=layering_check" - - "--copt=-Werror" - test_targets: - - "//..." - windows-msvc: - name: "Windows: MSVC 2017" - platform: windows - environment: - BAZEL_VC: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC" - build_flags: - - "--features=layering_check" - - "--copt=/WX" - build_targets: - - "//..." - test_flags: - - "--features=layering_check" - - "--copt=/WX" - test_targets: - - "//..." - windows-clang-cl: - name: "Windows: Clang" - platform: windows - environment: - BAZEL_VC: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC" - build_flags: - - "--compiler=clang-cl" - - "--features=layering_check" - build_targets: - - "//..." - test_flags: - - "--compiler=clang-cl" - - "--features=layering_check" - test_targets: - - "//..." diff --git a/third_party/glog/.clang-format b/third_party/glog/.clang-format deleted file mode 100644 index f2dd0de..0000000 --- a/third_party/glog/.clang-format +++ /dev/null @@ -1,168 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: Google -AccessModifierOffset: -1 -AlignAfterOpenBracket: Align -AlignConsecutiveMacros: false -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Left -AlignOperands: true -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllConstructorInitializersOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: Yes -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DeriveLineEnding: true -DerivePointerAlignment: true -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IncludeBlocks: Regroup -IncludeCategories: - - Regex: '^' - Priority: 2 - SortPriority: 0 - - Regex: '^<.*\.h>' - Priority: 1 - SortPriority: 0 - - Regex: '^<.*' - Priority: 2 - SortPriority: 0 - - Regex: '.*' - Priority: 3 - SortPriority: 0 -IncludeIsMainRegex: '([-_](test|unittest))?$' -IncludeIsMainSourceRegex: '' -IndentCaseLabels: true -IndentGotoLabels: true -IndentPPDirectives: None -IndentWidth: 2 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: false -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBinPackProtocolList: Never -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left -RawStringFormats: - - Language: Cpp - Delimiters: - - cc - - CC - - cpp - - Cpp - - CPP - - 'c++' - - 'C++' - CanonicalDelimiter: '' - BasedOnStyle: google - - Language: TextProto - Delimiters: - - pb - - PB - - proto - - PROTO - EnclosingFunctions: - - EqualsProto - - EquivToProto - - PARSE_PARTIAL_TEXT_PROTO - - PARSE_TEST_PROTO - - PARSE_TEXT_PROTO - - ParseTextOrDie - - ParseTextProtoOrDie - CanonicalDelimiter: '' - BasedOnStyle: google -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 2 -SpacesInAngles: false -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -Standard: Auto -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 8 -UseCRLF: false -UseTab: Never -... - diff --git a/third_party/glog/.clang-tidy b/third_party/glog/.clang-tidy deleted file mode 100644 index 19082cd..0000000 --- a/third_party/glog/.clang-tidy +++ /dev/null @@ -1,59 +0,0 @@ ---- -Checks: 'clang-diagnostic-*,clang-analyzer-*,google-*' -WarningsAsErrors: '' -HeaderFilterRegex: '' -AnalyzeTemporaryDtors: false -FormatStyle: file -CheckOptions: - - key: cert-dcl16-c.NewSuffixes - value: 'L;LL;LU;LLU' - - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField - value: '0' - - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - value: '1' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - value: '1' - - key: google-build-namespaces.HeaderFileExtensions - value: ',h,hh,hpp,hxx' - - key: google-global-names-in-headers.HeaderFileExtensions - value: ',h,hh,hpp,hxx' - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: google-readability-function-size.BranchThreshold - value: '4294967295' - - key: google-readability-function-size.LineThreshold - value: '4294967295' - - key: google-readability-function-size.NestingThreshold - value: '4294967295' - - key: google-readability-function-size.ParameterThreshold - value: '4294967295' - - key: google-readability-function-size.StatementThreshold - value: '800' - - key: google-readability-function-size.VariableThreshold - value: '4294967295' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - - key: google-runtime-int.SignedTypePrefix - value: int - - key: google-runtime-int.TypeSuffix - value: '' - - key: google-runtime-int.UnsignedTypePrefix - value: uint - - key: google-runtime-references.WhiteListTypes - value: '' - - key: modernize-loop-convert.MaxCopySize - value: '16' - - key: modernize-loop-convert.MinConfidence - value: reasonable - - key: modernize-loop-convert.NamingStyle - value: CamelCase - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: modernize-replace-auto-ptr.IncludeStyle - value: llvm - - key: modernize-use-nullptr.NullMacros - value: 'NULL' -... - diff --git a/third_party/glog/.gitattributes b/third_party/glog/.gitattributes deleted file mode 100644 index 2f6d494..0000000 --- a/third_party/glog/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.h linguist-language=C++ diff --git a/third_party/glog/.github/workflows/android.yml b/third_party/glog/.github/workflows/android.yml deleted file mode 100644 index e5f8c2e..0000000 --- a/third_party/glog/.github/workflows/android.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Android - -on: [push, pull_request] - -jobs: - build-android: - name: NDK-C++${{matrix.std}}-${{matrix.abi}}-${{matrix.build_type}} - runs-on: ubuntu-latest - defaults: - run: - shell: bash - strategy: - fail-fast: true - matrix: - std: [98, 11, 14, 17, 20] - abi: [arm64-v8a, armeabi-v7a, x86_64, x86] - build_type: [Debug, Release] - - steps: - - uses: actions/checkout@v2 - - - name: Setup Ninja - uses: ashutoshvarma/setup-ninja@master - with: - version: 1.10.0 - - - name: Setup C++98 Environment - if: matrix.std == '98' - run: | - echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV - - - name: Configure - env: - CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}} - run: | - cmake -S . -B build_${{matrix.abi}} \ - -DANDROID_ABI=${{matrix.abi}} \ - -DANDROID_NATIVE_API_LEVEL=28 \ - -DANDROID_STL=c++_shared \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_CXX_EXTENSIONS=OFF \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -G Ninja \ - -Werror - - - name: Build - run: | - cmake --build build_${{matrix.abi}} \ - --config ${{matrix.build_type}} diff --git a/third_party/glog/.github/workflows/linux.yml b/third_party/glog/.github/workflows/linux.yml deleted file mode 100644 index c9ac1a4..0000000 --- a/third_party/glog/.github/workflows/linux.yml +++ /dev/null @@ -1,150 +0,0 @@ -name: Linux - -on: [push, pull_request] - -jobs: - build-linux: - defaults: - run: - shell: bash - name: GCC-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} - runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - build_type: [Release, Debug] - extra: [no-custom-prefix, custom-prefix] - lib: [shared, static] - std: [98, 11, 14, 17, 20] - - steps: - - uses: actions/checkout@v2 - - - name: Setup Dependencies - run: | - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ - build-essential \ - cmake \ - lcov \ - libgflags-dev \ - libunwind-dev \ - ninja-build - - - name: Cache GTest - id: cache-gtest - uses: actions/cache@v2 - with: - path: gtest/ - key: ${{runner.os}}-gtest-1.11 - - - name: Download GTest - if: steps.cache-gtest.outputs.cache-hit != 'true' - run: | - wget https://github.com/google/googletest/archive/refs/tags/release-1.11.0.tar.gz - tar xvf release-1.11.0.tar.gz - - - name: Build GTest - if: steps.cache-gtest.outputs.cache-hit != 'true' - run: | - cmake -S googletest-release-1.11.0 -B build-googletest \ - -DBUILD_SHARED_LIBS=${{matrix.shared}} \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gtest \ - -G Ninja - cmake --build build-googletest --target install - - - name: Setup Environment - if: matrix.build_type == 'Debug' - run: | - echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV - echo 'GTest_ROOT=${{github.workspace}}/gtest' >> $GITHUB_ENV - - - name: Setup C++98 Environment - if: matrix.std == '98' - run: | - echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV - - - name: Configure - env: - CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}} - run: | - cmake -S . -B build_${{matrix.build_type}} \ - -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install \ - -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \ - -G Ninja \ - -Werror - - - name: Build - run: | - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} - - - name: Install - run: | - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} \ - --target install - - cmake build_${{matrix.build_type}} \ - -DCMAKE_INSTALL_INCLUDEDIR=${{runner.workspace}}/foo/include \ - -DCMAKE_INSTALL_LIBDIR=${{runner.workspace}}/foo/lib \ - -DCMAKE_INSTALL_DATAROOTDIR=${{runner.workspace}}/foo/share - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} \ - --target install - - - name: Test CMake Package (relative GNUInstallDirs) - run: | - cmake -S src/package_config_unittest/working_config \ - -B build_${{matrix.build_type}}_package \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_PREFIX_PATH=${{github.workspace}}/install \ - -G Ninja - cmake --build build_${{matrix.build_type}}_package \ - --config ${{matrix.build_type}} - - - name: Test CMake Package (absolute GNUInstallDirs) - run: | - cmake -S src/package_config_unittest/working_config \ - -B build_${{matrix.build_type}}_package_foo \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_PREFIX_PATH=${{runner.workspace}}/foo \ - -G Ninja - cmake --build build_${{matrix.build_type}}_package_foo \ - --config ${{matrix.build_type}} - - - name: Test - run: | - ctest --test-dir build_${{matrix.build_type}} -j$(nproc) --output-on-failure - - - name: Generate Coverage - if: matrix.build_type == 'Debug' - run: | - lcov --directory . --capture --output-file coverage.info - lcov --remove coverage.info \ - '${{github.workspace}}/gtest/*' \ - '*/src/*_unittest.cc' \ - '*/src/googletest.h' \ - '*/src/mock-log.h' \ - '/usr/*' \ - --output-file coverage.info - - for file in src/glog/*.h.in; do - name=$(basename ${file}) - name_we=${name%.h.in} - sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info - done - - lcov --list coverage.info - - - name: Upload Coverage to Codecov - if: matrix.build_type == 'Debug' - uses: codecov/codecov-action@v2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - verbose: true diff --git a/third_party/glog/.github/workflows/macos.yml b/third_party/glog/.github/workflows/macos.yml deleted file mode 100644 index 0b20ed2..0000000 --- a/third_party/glog/.github/workflows/macos.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: macOS - -on: [push, pull_request] - -jobs: - build-macos: - name: AppleClang-C++${{matrix.std}}-${{matrix.build_type}} - runs-on: macos-10.15 - strategy: - fail-fast: true - matrix: - std: [98, 11, 14, 17, 20] - include: - - generator: Ninja - - build_type: Debug - - steps: - - uses: actions/checkout@v2 - - - name: Setup Ninja - uses: ashutoshvarma/setup-ninja@master - with: - version: 1.10.0 - - - name: Setup Dependencies - run: | - brew install lcov - - - name: Setup Environment - if: matrix.build_type == 'Debug' - run: | - echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV - - - name: Configure - shell: bash - env: - CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}} - run: | - cmake -S . -B build_${{matrix.build_type}} \ - -DCMAKE_CXX_EXTENSIONS=OFF \ - -DCMAKE_CXX_FLAGS_DEBUG=-pedantic-errors \ - -DCMAKE_CXX_FLAGS_RELEASE=-pedantic-errors \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -G "${{matrix.generator}}" \ - -Werror - - - name: Build - run: | - cmake --build build_${{matrix.build_type}} \ - --config ${{matrix.build_type}} - - - name: Test - run: | - ctest --test-dir build_${{matrix.build_type}} \ - --output-on-failure - - - name: Generate Coverage - if: matrix.build_type == 'Debug' - run: | - lcov --directory . --capture --output-file coverage.info - lcov --remove coverage.info \ - '*/src/*_unittest.cc' \ - '*/src/googletest.h' \ - '*/src/mock-log.h' \ - '*/usr/*' \ - --output-file coverage.info - - for file in src/glog/*.h.in; do - name=$(basename ${file}) - name_we=${name%.h.in} - sed -i "" "s|${{github.workspace}}/glog/${name_we}.h\$|${file}|g" coverage.info - done - - lcov --list coverage.info - - - name: Upload Coverage to Codecov - if: matrix.build_type == 'Debug' - uses: codecov/codecov-action@v2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - verbose: true diff --git a/third_party/glog/.github/workflows/windows.yml b/third_party/glog/.github/workflows/windows.yml deleted file mode 100644 index de3b05d..0000000 --- a/third_party/glog/.github/workflows/windows.yml +++ /dev/null @@ -1,234 +0,0 @@ -name: Windows - -on: [push, pull_request] - -jobs: - build-msvc: - name: ${{matrix.msvc}}-${{matrix.arch}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} - runs-on: ${{matrix.os}} - defaults: - run: - shell: powershell - env: - CL: /MP - CXXFLAGS: /WX /permissive- - strategy: - fail-fast: true - matrix: - arch: [Win32, x64] - build_type: [Debug, Release] - extra: [no-custom-prefix, custom-prefix] - lib: [shared, static] - msvc: [VS-16-2019, VS-17-2022] - # Visual Studio 17 2022 does not support C++11 and older language standard - std: [14, 17, 20] - include: - - msvc: VS-16-2019 - os: windows-2019 - generator: 'Visual Studio 16 2019' - - msvc: VS-17-2022 - os: windows-2022 - generator: 'Visual Studio 17 2022' - - steps: - - uses: actions/checkout@v2 - - - name: Cache GTest - id: cache-gtest - uses: actions/cache@v2 - with: - path: gtest/ - key: ${{runner.os}}-gtest-1.11-${{matrix.lib}}-${{matrix.arch}}-${{matrix.build_type}} - - - name: Download GTest - if: steps.cache-gtest.outputs.cache-hit != 'true' - run: | - (New-Object System.Net.WebClient).DownloadFile("https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip", "release-1.11.0.zip") - Expand-Archive release-1.11.0.zip . - - - name: Build GTest - if: steps.cache-gtest.outputs.cache-hit != 'true' - run: | - cmake -S googletest-release-1.11.0 -B build-googletest ` - -A ${{matrix.arch}} ` - -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} ` - -Dgtest_force_shared_crt=ON ` - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gtest - cmake --build build-googletest ` - --config ${{matrix.build_type}} ` - --target install - - - name: Cache gflags - id: cache-gflags - uses: actions/cache@v2 - with: - path: gflags/ - key: ${{runner.os}}-gflags-2.2.2-${{matrix.lib}}-${{matrix.arch}}-${{matrix.build_type}} - - - name: Download gflags - if: steps.cache-gflags.outputs.cache-hit != 'true' - run: | - (New-Object System.Net.WebClient).DownloadFile("https://github.com/gflags/gflags/archive/refs/tags/v2.2.2.zip", "v2.2.2.zip") - Expand-Archive v2.2.2.zip . - - - name: Build gflags - if: steps.cache-gflags.outputs.cache-hit != 'true' - run: | - cmake -S gflags-2.2.2 -B build-gflags ` - -A ${{matrix.arch}} ` - -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} ` - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/gflags - cmake --build build-gflags ` - --config ${{matrix.build_type}} ` - --target install - - - name: Setup Environment - run: | - echo "GTest_ROOT=$((Get-Item .).FullName)/gtest" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "gflags_ROOT=$((Get-Item .).FullName)/gflags" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "${{github.workspace}}/gtest/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo "${{github.workspace}}/gflags/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Setup Release Environment - if: matrix.build_type != 'Debug' - run: | - echo "CXXFLAGS=/Zi ${{env.CXXFLAGS}}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Configure - run: | - cmake -S . -B build_${{matrix.build_type}} ` - -A ${{matrix.arch}} ` - -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} ` - -DCMAKE_CXX_EXTENSIONS=OFF ` - -DCMAKE_CXX_STANDARD=${{matrix.std}} ` - -DCMAKE_CXX_STANDARD_REQUIRED=ON ` - -DCMAKE_EXE_LINKER_FLAGS='/NOIMPLIB' ` - -DCMAKE_EXE_LINKER_FLAGS_RELEASE='/INCREMENTAL:NO /DEBUG' ` - -DCMAKE_INSTALL_PREFIX:PATH=./install ` - -DCMAKE_MSVC_RUNTIME_LIBRARY='MultiThreaded$<$:Debug>DLL' ` - -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} ` - -G "${{matrix.generator}}" ` - -Werror - - - name: Build - run: cmake --build build_${{matrix.build_type}} ` - --config ${{matrix.build_type}} - - - name: Test - env: - CTEST_OUTPUT_ON_FAILURE: 1 - run: | - cmake --build build_${{matrix.build_type}}/ ` - --config ${{matrix.build_type}} ` - --target RUN_TESTS - - - name: Install - run: | - cmake --build build_${{matrix.build_type}}/ ` - --config ${{matrix.build_type}} ` - --target install - - build-mingw: - name: ${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}} - runs-on: windows-2022 - env: - BUILDDIR: 'build_${{matrix.sys}}-${{matrix.env}}-C++${{matrix.std}}-${{matrix.build_type}}-${{matrix.lib}}-${{matrix.extra}}' - defaults: - run: - shell: msys2 {0} - strategy: - fail-fast: true - matrix: - build_type: [Debug] - extra: [no-custom-prefix, custom-prefix] - lib: [shared, static] - std: [98, 11, 14, 17, 20] - sys: [mingw32, mingw64] - include: - - sys: mingw32 - env: i686 - - sys: mingw64 - env: x86_64 - - steps: - - uses: actions/checkout@v2 - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{matrix.sys}} - install: >- - lcov - mingw-w64-${{matrix.env}}-cmake - mingw-w64-${{matrix.env}}-gcc - mingw-w64-${{matrix.env}}-gflags - mingw-w64-${{matrix.env}}-ninja - - - name: Setup C++98 Environment - if: matrix.std == '98' - run: | - echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV - - - name: Setup Environment - if: matrix.build_type == 'Debug' - run: | - echo 'CXXFLAGS=--coverage ${{env.CXXFLAGS}}' >> $GITHUB_ENV - - - name: Configure - env: - CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}} - run: | - cmake -S . -B build_${{matrix.build_type}}/ \ - -DBUILD_SHARED_LIBS=${{matrix.lib == 'shared'}} \ - -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - -DCMAKE_CXX_EXTENSIONS=OFF \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_STANDARD_REQUIRED=ON \ - -DCMAKE_INSTALL_PREFIX:PATH=./install \ - -DWITH_CUSTOM_PREFIX=${{matrix.extra == 'custom-prefix'}} \ - -G Ninja \ - -Werror - - - name: Build - run: | - cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}} - - - name: Test - env: - CTEST_OUTPUT_ON_FAILURE: 1 - run: | - cmake --build build_${{matrix.build_type}}/ --config ${{matrix.build_type}} \ - --target test - - - name: Install - run: | - cmake --build build_${{matrix.build_type}}/ \ - --config ${{matrix.build_type}} \ - --target install - - - name: Generate Coverage - if: matrix.build_type == 'Debug' - run: | - lcov --directory . --capture --output-file coverage.info - lcov --remove coverage.info \ - '*/install/include/*' \ - '*/msys64/mingw32/*' \ - '*/msys64/mingw64/*' \ - '*/src/*_unittest.cc' \ - '*/src/googletest.h' \ - '*/src/mock-log.h' \ - --output-file coverage.info - - for file in src/glog/*.h.in; do - name=$(basename ${file}) - name_we=${name%.h.in} - sed -i "s|build_${{matrix.build_type}}/glog/${name_we}.h\$|${file}|g" coverage.info - done - - lcov --list coverage.info - - - name: Upload Coverage to Codecov - if: matrix.build_type == 'Debug' - uses: codecov/codecov-action@v2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - verbose: true diff --git a/third_party/glog/.gitignore b/third_party/glog/.gitignore deleted file mode 100644 index 2678271..0000000 --- a/third_party/glog/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.orig -/build*/ -bazel-* diff --git a/third_party/glog/AUTHORS b/third_party/glog/AUTHORS deleted file mode 100644 index 9d711ec..0000000 --- a/third_party/glog/AUTHORS +++ /dev/null @@ -1,29 +0,0 @@ -# This is the official list of glog authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. -# -# Names should be added to this file as: -# Name or Organization -# The email address is not required for organizations. -# -# Please keep the list sorted. - -Abhishek Dasgupta -Abhishek Parmar -Andrew Schwartzmeyer -Andy Ying -Brian Silverman -Dmitriy Arbitman -Google Inc. -Guillaume Dumont -Marco Wang -Michael Tanner -MiniLight -romange -Roman Perepelitsa -Sergiu Deitsch -tbennun -Teddy Reed -Vijaymahantesh Sattigeri -Zhongming Qu -Zhuoran Shen diff --git a/third_party/glog/BUILD.bazel b/third_party/glog/BUILD.bazel deleted file mode 100644 index 0acdc72..0000000 --- a/third_party/glog/BUILD.bazel +++ /dev/null @@ -1,22 +0,0 @@ -licenses(["notice"]) - -exports_files(["COPYING"]) - -load(":bazel/glog.bzl", "glog_library") - -glog_library() - -# platform() to build with clang-cl on Bazel CI. This is enabled with -# the flags in .bazelci/presubmit.yml: -# -# --incompatible_enable_cc_toolchain_resolution -# --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl -# --extra_execution_platforms=//:x64_windows-clang-cl -platform( - name = "x64_windows-clang-cl", - constraint_values = [ - "@platforms//cpu:x86_64", - "@platforms//os:windows", - "@bazel_tools//tools/cpp:clang-cl", - ], -) diff --git a/third_party/glog/CMakeLists.txt b/third_party/glog/CMakeLists.txt deleted file mode 100644 index c1c3ac5..0000000 --- a/third_party/glog/CMakeLists.txt +++ /dev/null @@ -1,1139 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project( - glog - VERSION 0.6.0 - DESCRIPTION "C++ implementation of the Google logging module" - HOMEPAGE_URL https://github.com/google/glog - LANGUAGES CXX) - -set(CPACK_PACKAGE_NAME glog) -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Google logging library") -set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) -set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) -set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) -set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) - -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) - -include(CheckCXXCompilerFlag) -include(CheckCXXSourceCompiles) -include(CheckCXXSourceRuns) -include(CheckCXXSymbolExists) -include(CheckFunctionExists) -include(CheckIncludeFileCXX) -include(CheckLibraryExists) -include(CheckStructHasMember) -include(CheckTypeSize) -include(CMakeDependentOption) -include(CMakePackageConfigHelpers) -include(CMakePushCheckState) -include(CPack) -include(CTest) -# include (DetermineGflagsNamespace) -include(GenerateExportHeader) -include(GetCacheVariables) -include(GNUInstallDirs) - -option(BUILD_SHARED_LIBS "Build shared libraries" OFF) -option(PRINT_UNSYMBOLIZED_STACK_TRACES - "Print file offsets in traces instead of symbolizing" OFF) -option(WITH_CUSTOM_PREFIX "Enable support for user-generated message prefixes" - ON) -option(WITH_GFLAGS "Use gflags" OFF) -option(WITH_GTEST "Use Google Test" OFF) -option(WITH_PKGCONFIG "Enable pkg-config support" OFF) -option(WITH_SYMBOLIZE "Enable symbolize module" ON) -option(WITH_THREADS "Enable multithreading support" ON) -option(WITH_TLS "Enable Thread Local Storage (TLS) support" ON) -option(WITH_UNWIND "Enable libunwind support" ON) - -cmake_dependent_option(WITH_GMOCK "Use Google Mock" ON WITH_GTEST OFF) - -if(NOT WITH_UNWIND) - set(CMAKE_DISABLE_FIND_PACKAGE_Unwind ON) -endif(NOT WITH_UNWIND) - -if(NOT WITH_GTEST) - set(CMAKE_DISABLE_FIND_PACKAGE_GTest ON) -endif(NOT WITH_GTEST) - -if(NOT WITH_THREADS) - set(CMAKE_DISABLE_FIND_PACKAGE_Threads ON) -endif(NOT WITH_THREADS) - -set(CMAKE_C_VISIBILITY_PRESET hidden) -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) - -set(CMAKE_DEBUG_POSTFIX d) -set(CMAKE_THREAD_PREFER_PTHREAD 1) - -find_package(GTest NO_MODULE) - -if(GTest_FOUND) - set(HAVE_LIB_GTEST 1) -endif(GTest_FOUND) - -if(WITH_GMOCK AND TARGET GTest::gmock) - set(HAVE_LIB_GMOCK 1) -endif(WITH_GMOCK AND TARGET GTest::gmock) - -if(WITH_GFLAGS) - # find_package (gflags 2.2.2) - - # if (gflags_FOUND) - set(HAVE_LIB_GFLAGS 1) - set(gflags_FOUND 1) - set(gflags_NAMESPACE - gflags - CACHE INTERNAL "gflags namespace") - # determine_gflags_namespace (gflags_NAMESPACE) endif (gflags_FOUND) -endif(WITH_GFLAGS) - -find_package(Threads) -find_package(Unwind) - -if(Unwind_FOUND) - set(HAVE_LIB_UNWIND 1) -else(Unwind_FOUND) - check_include_file_cxx(unwind.h HAVE_UNWIND_H) - # Check whether linking actually succeeds. ARM toolchains of LLVM unwind - # implementation do not necessarily provide the _Unwind_Backtrace function - # which causes the previous check to succeed but the linking to fail. - check_cxx_symbol_exists(_Unwind_Backtrace unwind.h HAVE__UNWIND_BACKTRACE) -endif(Unwind_FOUND) - -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(memory.h HAVE_MEMORY_H) -check_include_file_cxx(pwd.h HAVE_PWD_H) -check_include_file_cxx(stdint.h HAVE_STDINT_H) -check_include_file_cxx(strings.h HAVE_STRINGS_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/utsname.h HAVE_SYS_UTSNAME_H) -check_include_file_cxx(sys/wait.h HAVE_SYS_WAIT_H) -check_include_file_cxx(syscall.h HAVE_SYSCALL_H) -check_include_file_cxx(syslog.h HAVE_SYSLOG_H) -check_include_file_cxx(ucontext.h HAVE_UCONTEXT_H) -check_include_file_cxx(unistd.h HAVE_UNISTD_H) - -check_include_file_cxx("ext/hash_map" HAVE_EXT_HASH_MAP) -check_include_file_cxx("ext/hash_set" HAVE_EXT_HASH_SET) -check_include_file_cxx("ext/slist" HAVE_EXT_SLIST) -check_include_file_cxx("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP) -check_include_file_cxx("tr1/unordered_set" HAVE_TR1_UNORDERED_SET) -check_include_file_cxx("unordered_map" HAVE_UNORDERED_MAP) -check_include_file_cxx("unordered_set" HAVE_UNORDERED_SET) - -check_type_size("unsigned __int16" HAVE___UINT16 LANGUAGE CXX) -check_type_size(u_int16_t HAVE_U_INT16_T LANGUAGE CXX) -check_type_size(uint16_t HAVE_UINT16_T LANGUAGE CXX) - -check_function_exists(dladdr HAVE_DLADDR) -check_function_exists(fcntl HAVE_FCNTL) -check_function_exists(pread HAVE_PREAD) -check_function_exists(pwrite HAVE_PWRITE) -check_function_exists(sigaction HAVE_SIGACTION) -check_function_exists(sigaltstack HAVE_SIGALTSTACK) - -# NOTE gcc does not fail if you pass a non-existent -Wno-* option as an -# argument. However, it will happily fail if you pass the corresponding -W* -# option. So, we check whether options that disable warnings exist by testing -# the availability of the corresponding option that enables the warning. This -# eliminates the need to check for compiler for several (mainly Clang) options. - -check_cxx_compiler_flag(-Wdeprecated HAVE_NO_DEPRECATED) -check_cxx_compiler_flag(-Wunnamed-type-template-args - HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS) - -cmake_push_check_state(RESET) - -if(Threads_FOUND) - set(CMAKE_REQUIRED_LIBRARIES Threads::Threads) -endif(Threads_FOUND) - -check_cxx_symbol_exists(pthread_threadid_np "pthread.h" - HAVE_PTHREAD_THREADID_NP) -cmake_pop_check_state() - -# NOTE: Cannot use check_function_exists here since >=vc-14.0 can define -# snprintf as an inline function -check_cxx_symbol_exists(snprintf cstdio HAVE_SNPRINTF) - -check_library_exists(dbghelp UnDecorateSymbolName "" HAVE_DBGHELP) - -check_cxx_source_compiles( - " -#include -static void foo(void) __attribute__ ((unused)); -int main(void) { return 0; } -" - HAVE___ATTRIBUTE__) - -check_cxx_source_compiles( - " -#include -static void foo(void) __attribute__ ((visibility(\"default\"))); -int main(void) { return 0; } -" - HAVE___ATTRIBUTE__VISIBILITY_DEFAULT) - -check_cxx_source_compiles( - " -#include -static void foo(void) __attribute__ ((visibility(\"hidden\"))); -int main(void) { return 0; } -" - HAVE___ATTRIBUTE__VISIBILITY_HIDDEN) - -check_cxx_source_compiles( - " -int main(void) { if (__builtin_expect(0, 0)) return 1; return 0; } -" HAVE___BUILTIN_EXPECT) - -check_cxx_source_compiles( - " -int main(void) -{ - int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0; -} -" - HAVE___SYNC_VAL_COMPARE_AND_SWAP) - -cmake_push_check_state(RESET) -set(CMAKE_REQUIRED_LIBRARIES Threads::Threads) -check_cxx_source_compiles( - " -#define _XOPEN_SOURCE 500 -#include -int main(void) -{ - pthread_rwlock_t l; - pthread_rwlock_init(&l, NULL); - pthread_rwlock_rdlock(&l); - return 0; -} -" - HAVE_RWLOCK) -cmake_pop_check_state() - -check_cxx_source_compiles( - " -__declspec(selectany) int a; -int main(void) { return 0; } -" - HAVE___DECLSPEC) - -check_cxx_source_compiles( - " -#include -vector t; int main() { } -" - STL_NO_NAMESPACE) - -check_cxx_source_compiles( - " -#include -std::vector t; int main() { } -" - STL_STD_NAMESPACE) - -check_cxx_source_compiles( - " -#include -std::ostream& operator<<(std::ostream&, struct s); -using ::operator<<; -int main() { } -" - HAVE_USING_OPERATOR) - -check_cxx_source_compiles( - " -namespace Outer { namespace Inner { int i = 0; }} -using namespace Outer::Inner;; -int main() { return i; } -" - HAVE_NAMESPACES) - -check_cxx_source_compiles( - " -__thread int tls; -int main() { } -" - HAVE_GCC_TLS) - -check_cxx_source_compiles( - " -__declspec(thread) int tls; -int main() { } -" - HAVE_MSVC_TLS) - -check_cxx_source_compiles( - " -thread_local int tls; -int main() { } -" - HAVE_CXX11_TLS) - -check_cxx_source_compiles( - " -#include -std::aligned_storage::type data; -int main() { } -" - HAVE_ALIGNED_STORAGE) - -check_cxx_source_compiles( - " -#include -std::atomic i; -int main() { } -" - HAVE_CXX11_ATOMIC) - -check_cxx_source_compiles( - " -constexpr int x = 0; -int main() { } -" - HAVE_CXX11_CONSTEXPR) - -check_cxx_source_compiles( - " -#include -std::chrono::seconds s; -int main() { } -" - HAVE_CXX11_CHRONO) - -check_cxx_source_compiles( - " -#include -void foo(std::nullptr_t) {} -int main(void) { foo(nullptr); } -" - HAVE_CXX11_NULLPTR_T) - -if(WITH_TLS) - # Cygwin does not support the thread attribute. Don't bother. - if(HAVE_GCC_TLS) - set(GLOG_THREAD_LOCAL_STORAGE "__thread") - elseif(HAVE_MSVC_TLS) - set(GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)") - elseif(HAVE_CXX11_TLS) - set(GLOG_THREAD_LOCAL_STORAGE thread_local) - endif(HAVE_GCC_TLS) -endif(WITH_TLS) - -set(_PC_FIELDS - "gregs[REG_PC]" - "gregs[REG_EIP]" - "gregs[REG_RIP]" - "sc_ip" - "uc_regs->gregs[PT_NIP]" - "gregs[R15]" - "arm_pc" - "mc_eip" - "mc_rip" - "__gregs[REG_EIP]" - "__gregs[REG_RIP]" - "ss.eip" - "__ss.__eip" - "ss.rip" - "__ss.__rip" - "ss.srr0" - "__ss.__srr0") - -set(_PC_HEADERS ucontext.h signal.h) - -if(HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT) - foreach(_PC_FIELD ${_PC_FIELDS}) - foreach(_PC_HEADER ${_PC_HEADERS}) - set(_TMP - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/uctfield.cpp - ) - file( - WRITE ${_TMP} - " -#define _GNU_SOURCE 1 -#include <${_PC_HEADER}> -int main(void) -{ - ucontext_t u; - return u.${_PC_FIELD} == 0; -} -") - try_compile( - HAVE_PC_FROM_UCONTEXT ${CMAKE_CURRENT_BINARY_DIR} - ${_TMP} - COMPILE_DEFINITIONS _GNU_SOURCE=1) - - if(HAVE_PC_FROM_UCONTEXT) - set(PC_FROM_UCONTEXT - ${_PC_FIELD} - CACHE) - endif(HAVE_PC_FROM_UCONTEXT) - endforeach(_PC_HEADER) - endforeach(_PC_FIELD) -endif(HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT) - -if(STL_STD_NAMESPACE) - set(STL_NAMESPACE std) -else(STL_STD_NAMESPACE) - set(STL_NAMESPACE "") -endif(STL_STD_NAMESPACE) - -set(GOOGLE_NAMESPACE google) -set(_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {") -set(_END_GOOGLE_NAMESPACE_ "}") -set(ac_cv_have_glog_export 1) - -if(HAVE___UINT16) - set(ac_cv_have___uint16 1) -else(HAVE___UINT16) - set(ac_cv_have___uint16 0) -endif(HAVE___UINT16) - -if(HAVE_INTTYPES_H) - set(ac_cv_have_inttypes_h 1) -else(HAVE_INTTYPES_H) - set(ac_cv_have_inttypes_h 0) -endif(HAVE_INTTYPES_H) - -if(HAVE_LIB_GFLAGS) - set(ac_cv_have_libgflags 1) -else(HAVE_LIB_GFLAGS) - set(ac_cv_have_libgflags 0) -endif(HAVE_LIB_GFLAGS) - -if(HAVE_STDINT_H) - set(ac_cv_have_stdint_h 1) -else(HAVE_STDINT_H) - set(ac_cv_have_stdint_h 0) -endif(HAVE_STDINT_H) - -if(HAVE_SYS_TYPES_H) - set(ac_cv_have_systypes_h 1) -else(HAVE_SYS_TYPES_H) - set(ac_cv_have_systypes_h 0) -endif(HAVE_SYS_TYPES_H) - -if(HAVE_U_INT16_T) - set(ac_cv_have_u_int16_t 1) -else(HAVE_U_INT16_T) - set(ac_cv_have_u_int16_t 0) -endif(HAVE_U_INT16_T) - -if(HAVE_UINT16_T) - set(ac_cv_have_uint16_t 1) -else(HAVE_UINT16_T) - set(ac_cv_have_uint16_t 0) -endif(HAVE_UINT16_T) - -if(HAVE_UNISTD_H) - set(ac_cv_have_unistd_h 1) -else(HAVE_UNISTD_H) - set(ac_cv_have_unistd_h 0) -endif(HAVE_UNISTD_H) - -set(ac_google_namespace ${GOOGLE_NAMESPACE}) -set(ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_}) -set(ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_}) - -if(HAVE___ATTRIBUTE__) - set(ac_cv___attribute___noreturn "__attribute__((noreturn))") - set(ac_cv___attribute___noinline "__attribute__((noinline))") - set(ac_cv___attribute___printf_4_5 - "__attribute__((__format__(__printf__, 4, 5)))") -elseif(HAVE___DECLSPEC) - set(ac_cv___attribute___noreturn "__declspec(noreturn)") - # set (ac_cv___attribute___noinline "__declspec(noinline)") -endif(HAVE___ATTRIBUTE__) - -if(HAVE___BUILTIN_EXPECT) - set(ac_cv_have___builtin_expect 1) -else(HAVE___BUILTIN_EXPECT) - set(ac_cv_have___builtin_expect 0) -endif(HAVE___BUILTIN_EXPECT) - -if(HAVE_USING_OPERATOR) - set(ac_cv_cxx_using_operator 1) -else(HAVE_USING_OPERATOR) - set(ac_cv_cxx_using_operator 0) -endif(HAVE_USING_OPERATOR) - -if(HAVE_CXX11_CONSTEXPR) - set(ac_cv_cxx11_constexpr 1) -else(HAVE_CXX11_CONSTEXPR) - set(ac_cv_cxx11_constexpr 0) -endif(HAVE_CXX11_CONSTEXPR) - -if(HAVE_CXX11_CHRONO) - set(ac_cv_cxx11_chrono 1) -else(HAVE_CXX11_CHRONO) - set(ac_cv_cxx11_chrono 0) -endif(HAVE_CXX11_CHRONO) - -if(HAVE_CXX11_NULLPTR_T) - set(ac_cv_cxx11_nullptr_t 1) -else(HAVE_CXX11_NULLPTR_T) - set(ac_cv_cxx11_nullptr_t 0) -endif(HAVE_CXX11_NULLPTR_T) - -if(HAVE_EXECINFO_H) - set(HAVE_STACKTRACE 1) -endif(HAVE_EXECINFO_H) - -if(HAVE_CXX11_ATOMIC) - set(ac_cv_cxx11_atomic 1) -else(HAVE_CXX11_ATOMIC) - set(ac_cv_cxx11_atomic 0) -endif(HAVE_CXX11_ATOMIC) - -if(WITH_SYMBOLIZE) - if(WIN32 OR CYGWIN) - cmake_push_check_state(RESET) - set(CMAKE_REQUIRED_LIBRARIES DbgHelp) - - check_cxx_source_runs( - [=[ - #include - #include - #include - - void foobar() { } - - int main() - { - HANDLE process = GetCurrentProcess(); - - if (!SymInitialize(process, NULL, TRUE)) - return EXIT_FAILURE; - - char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; - SYMBOL_INFO *symbol = reinterpret_cast(buf); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; - - void* const pc = reinterpret_cast(&foobar); - BOOL ret = SymFromAddr(process, reinterpret_cast(pc), 0, symbol); - - return ret ? EXIT_SUCCESS : EXIT_FAILURE; - } - ]=] - HAVE_SYMBOLIZE) - - cmake_pop_check_state() - - if(HAVE_SYMBOLIZE) - set(HAVE_STACKTRACE 1) - endif(HAVE_SYMBOLIZE) - elseif(UNIX OR (APPLE AND HAVE_DLADDR)) - set(HAVE_SYMBOLIZE 1) - endif(WIN32 OR CYGWIN) -endif(WITH_SYMBOLIZE) - -# CMake manages symbolize availability. The definition is necessary only when -# building the library. Switch to add_compile_definitions once we drop support -# for CMake below version 3.12. -add_definitions(-DGLOG_NO_SYMBOLIZE_DETECTION) - -check_cxx_source_compiles( - " -#include -#include -int main() -{ - time_t timep; - struct tm result; - localtime_r(&timep, &result); - return EXIT_SUCCESS; -} -" - HAVE_LOCALTIME_R) - -set(SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) - -if(WITH_THREADS AND Threads_FOUND) - if(CMAKE_USE_PTHREADS_INIT) - set(HAVE_PTHREAD 1) - endif(CMAKE_USE_PTHREADS_INIT) -else(WITH_THREADS AND Threads_FOUND) - set(NO_THREADS 1) -endif(WITH_THREADS AND Threads_FOUND) - -# fopen/open on Cygwin can not handle unix-type paths like /home/.... therefore -# we translate TEST_SRC_DIR to windows-path. -if(CYGWIN) - execute_process( - COMMAND cygpath.exe -m ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE TEST_SRC_DIR) - set(TEST_SRC_DIR \"${TEST_SRC_DIR}\") -else(CYGWIN) - set(TEST_SRC_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\") -endif(CYGWIN) - -configure_file(src/config.h.cmake.in config.h) -configure_file(src/glog/logging.h.in glog/logging.h @ONLY) -configure_file(src/glog/raw_logging.h.in glog/raw_logging.h @ONLY) -configure_file(src/glog/stl_logging.h.in glog/stl_logging.h @ONLY) -configure_file(src/glog/vlog_is_on.h.in glog/vlog_is_on.h @ONLY) - -add_compile_options( - $<$,$>>:-Wno-unnamed-type-template-args> -) - -set(_glog_CMake_BINDIR ${CMAKE_INSTALL_BINDIR}) -set(_glog_CMake_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}) -set(_glog_CMake_LIBDIR ${CMAKE_INSTALL_LIBDIR}) -set(_glog_CMake_INSTALLDIR ${_glog_CMake_LIBDIR}/cmake/glog) - -set(_glog_CMake_DIR glog/cmake) -set(_glog_CMake_DATADIR ${CMAKE_INSTALL_DATAROOTDIR}/${_glog_CMake_DIR}) -set(_glog_BINARY_CMake_DATADIR - ${CMAKE_CURRENT_BINARY_DIR}/${_glog_CMake_DATADIR}) - -# Add additional CMake find modules here. -set(_glog_CMake_MODULES) - -if(Unwind_FOUND) - # Copy the module only if libunwind is actually used. - list(APPEND _glog_CMake_MODULES - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindUnwind.cmake) -endif(Unwind_FOUND) - -# Generate file name for each module in the binary directory -foreach(_file ${_glog_CMake_MODULES}) - get_filename_component(_module "${_file}" NAME) - - list(APPEND _glog_BINARY_CMake_MODULES - ${_glog_BINARY_CMake_DATADIR}/${_module}) -endforeach(_file) - -if(_glog_CMake_MODULES) - # Copy modules to binary directory during the build - add_custom_command( - OUTPUT ${_glog_BINARY_CMake_MODULES} - COMMAND ${CMAKE_COMMAND} -E make_directory ${_glog_BINARY_CMake_DATADIR} - COMMAND ${CMAKE_COMMAND} -E copy ${_glog_CMake_MODULES} - ${_glog_BINARY_CMake_DATADIR} - DEPENDS ${_glog_CMake_MODULES} - COMMENT "Copying find modules...") -endif(_glog_CMake_MODULES) - -set(GLOG_PUBLIC_H - ${CMAKE_CURRENT_BINARY_DIR}/glog/export.h - ${CMAKE_CURRENT_BINARY_DIR}/glog/logging.h - ${CMAKE_CURRENT_BINARY_DIR}/glog/raw_logging.h - ${CMAKE_CURRENT_BINARY_DIR}/glog/stl_logging.h - ${CMAKE_CURRENT_BINARY_DIR}/glog/vlog_is_on.h - src/glog/log_severity.h - src/glog/platform.h) - -set(GLOG_SRCS - ${GLOG_PUBLIC_H} - src/base/commandlineflags.h - src/base/googleinit.h - src/base/mutex.h - src/demangle.cc - src/demangle.h - src/logging.cc - src/raw_logging.cc - src/symbolize.cc - src/symbolize.h - src/utilities.cc - src/utilities.h - src/vlog_is_on.cc) - -if(HAVE_PTHREAD - OR WIN32 - OR CYGWIN) - list(APPEND GLOG_SRCS src/signalhandler.cc) -endif( - HAVE_PTHREAD - OR WIN32 - OR CYGWIN) - -if(CYGWIN OR WIN32) - list(APPEND GLOG_SRCS src/windows/port.cc src/windows/port.h) -endif(CYGWIN OR WIN32) - -add_library(glogbase OBJECT ${_glog_BINARY_CMake_MODULES} ${GLOG_SRCS}) - -add_library(glog $) - -add_library(glog::glog ALIAS glog) - -set(glog_libraries_options_for_static_linking) - -if(Unwind_FOUND) - target_link_libraries(glog PRIVATE unwind::unwind) - set(glog_libraries_options_for_static_linking - "${glog_libraries_options_for_static_linking} -lunwind") - set(Unwind_DEPENDENCY "find_dependency (Unwind ${Unwind_VERSION})") -endif(Unwind_FOUND) - -if(HAVE_DBGHELP) - target_link_libraries(glog PRIVATE dbghelp) - set(glog_libraries_options_for_static_linking - "${glog_libraries_options_for_static_linking} -ldbghelp") -endif(HAVE_DBGHELP) - -if(HAVE_PTHREAD) - target_link_libraries(glog PRIVATE ${CMAKE_THREAD_LIBS_INIT}) - - if(CMAKE_THREAD_LIBS_INIT) - set(glog_libraries_options_for_static_linking - "${glog_libraries_options_for_static_linking} ${CMAKE_THREAD_LIBS_INIT}" - ) - endif(CMAKE_THREAD_LIBS_INIT) -endif(HAVE_PTHREAD) - -if(gflags_FOUND) - # Prefer the gflags target that uses double colon convention - # target_link_libraries(glog PRIVATE gflags::gflags) - # if (TARGET - # gflags::gflags) target_link_libraries (glog PUBLIC gflags::gflags) else - # (TARGET gflags::gflags) target_link_libraries (glog PUBLIC gflags) endif - # (TARGET gflags::gflags) - - # set (glog_libraries_options_for_static_linking - # "${glog_libraries_options_for_static_linking} -lgflags") -endif(gflags_FOUND) - -if(ANDROID) - target_link_libraries(glog PRIVATE log) - set(glog_libraries_options_for_static_linking - "${glog_libraries_options_for_static_linking} -llog") -endif(ANDROID) - -set_target_properties(glog PROPERTIES VERSION ${PROJECT_VERSION}) -set_target_properties(glog PROPERTIES SOVERSION 1) - -if(CYGWIN OR WIN32) - target_compile_definitions(glog PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES) -endif(CYGWIN OR WIN32) - -if(WITH_CUSTOM_PREFIX) - target_compile_definitions(glog PUBLIC GLOG_CUSTOM_PREFIX_SUPPORT) -endif(WITH_CUSTOM_PREFIX) - -set_target_properties(glog PROPERTIES PUBLIC_HEADER "${GLOG_PUBLIC_H}") - -target_include_directories( - glog BEFORE - PUBLIC "$" - "$" - "$" - PRIVATE ${CMAKE_CURRENT_BINARY_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) - -if(CYGWIN OR WIN32) - target_include_directories( - glogbase - PUBLIC "$" - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows) - - target_include_directories( - glog - PUBLIC "$" - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows) -endif(CYGWIN OR WIN32) - -set_target_properties(glog PROPERTIES DEFINE_SYMBOL GOOGLE_GLOG_IS_A_DLL) - -target_include_directories(glogbase - PUBLIC $) -target_compile_definitions( - glogbase - PUBLIC $ - PRIVATE GOOGLE_GLOG_IS_A_DLL) - -generate_export_header(glog EXPORT_MACRO_NAME GLOG_EXPORT EXPORT_FILE_NAME - ${CMAKE_CURRENT_BINARY_DIR}/glog/export.h) - -string(STRIP "${glog_libraries_options_for_static_linking}" - glog_libraries_options_for_static_linking) - -if(WITH_PKGCONFIG) - set(VERSION ${PROJECT_VERSION}) - set(prefix ${CMAKE_INSTALL_PREFIX}) - set(exec_prefix ${CMAKE_INSTALL_FULL_BINDIR}) - set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) - set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) - - configure_file("${PROJECT_SOURCE_DIR}/libglog.pc.in" - "${PROJECT_BINARY_DIR}/libglog.pc" @ONLY) - - unset(VERSION) - unset(prefix) - unset(exec_prefix) - unset(libdir) - unset(includedir) -endif(WITH_PKGCONFIG) - -# Unit testing - -# if(BUILD_TESTING) -if(FALSE) - add_library(glogtest STATIC $) - - target_include_directories(glogtest - PUBLIC $) - target_compile_definitions( - glogtest PUBLIC $ - GLOG_STATIC_DEFINE) - target_link_libraries(glogtest PUBLIC $) - - set(_GLOG_TEST_LIBS glogtest) - - if(HAVE_LIB_GTEST) - list(APPEND _GLOG_TEST_LIBS GTest::gtest) - endif(HAVE_LIB_GTEST) - - if(HAVE_LIB_GMOCK) - list(APPEND _GLOG_TEST_LIBS GTest::gmock) - endif(HAVE_LIB_GMOCK) - - add_executable(logging_unittest src/logging_unittest.cc) - - target_link_libraries(logging_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - if(WITH_CUSTOM_PREFIX) - add_executable(logging_custom_prefix_unittest - src/logging_custom_prefix_unittest.cc) - - target_link_libraries(logging_custom_prefix_unittest - PRIVATE ${_GLOG_TEST_LIBS}) - - add_test(NAME logging_custom_prefix COMMAND logging_custom_prefix_unittest) - - # FIXME: Skip flaky test - set_tests_properties( - logging_custom_prefix - PROPERTIES - SKIP_REGULAR_EXPRESSION - "Check failed: time_ns within LogTimes::LOG_PERIOD_TOL_NS of LogTimes::LOG_PERIOD_NS" - ) - - if(APPLE) - # FIXME: Skip flaky test - set_property( - TEST logging_custom_prefix - APPEND - PROPERTY - SKIP_REGULAR_EXPRESSION - "unexpected new.*PASS\nTest with golden file failed. We'll try to show the diff:" - ) - endif(APPLE) - endif(WITH_CUSTOM_PREFIX) - - add_executable(stl_logging_unittest src/stl_logging_unittest.cc) - - target_link_libraries(stl_logging_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - if(HAVE_NO_DEPRECATED) - set_property( - TARGET stl_logging_unittest - APPEND - PROPERTY COMPILE_OPTIONS -Wno-deprecated) - endif(HAVE_NO_DEPRECATED) - - if(HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET) - target_compile_definitions(stl_logging_unittest - PRIVATE GLOG_STL_LOGGING_FOR_UNORDERED) - endif(HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET) - - if(HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET) - target_compile_definitions(stl_logging_unittest - PRIVATE GLOG_STL_LOGGING_FOR_TR1_UNORDERED) - endif(HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET) - - if(HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET) - target_compile_definitions(stl_logging_unittest - PRIVATE GLOG_STL_LOGGING_FOR_EXT_HASH) - endif(HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET) - - if(HAVE_EXT_SLIST) - target_compile_definitions(stl_logging_unittest - PRIVATE GLOG_STL_LOGGING_FOR_EXT_SLIST) - endif(HAVE_EXT_SLIST) - - if(HAVE_SYMBOLIZE) - add_executable(symbolize_unittest src/symbolize_unittest.cc) - - target_link_libraries(symbolize_unittest PRIVATE ${_GLOG_TEST_LIBS}) - endif(HAVE_SYMBOLIZE) - - add_executable(demangle_unittest src/demangle_unittest.cc) - - target_link_libraries(demangle_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - if(HAVE_STACKTRACE) - add_executable(stacktrace_unittest src/stacktrace_unittest.cc) - - target_link_libraries(stacktrace_unittest PRIVATE ${_GLOG_TEST_LIBS}) - endif(HAVE_STACKTRACE) - - add_executable(utilities_unittest src/utilities_unittest.cc) - - target_link_libraries(utilities_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - if(HAVE_STACKTRACE AND HAVE_SYMBOLIZE) - add_executable(signalhandler_unittest src/signalhandler_unittest.cc) - - target_link_libraries(signalhandler_unittest PRIVATE ${_GLOG_TEST_LIBS}) - endif(HAVE_STACKTRACE AND HAVE_SYMBOLIZE) - - add_test(NAME demangle COMMAND demangle_unittest) - add_test(NAME logging COMMAND logging_unittest) - - set_tests_properties(logging PROPERTIES TIMEOUT 30) - - # FIXME: Skip flaky test - set_tests_properties( - logging - PROPERTIES - SKIP_REGULAR_EXPRESSION - "Check failed: time_ns within LogTimes::LOG_PERIOD_TOL_NS of LogTimes::LOG_PERIOD_NS" - ) - - if(APPLE) - # FIXME: Skip flaky test - set_property( - TEST logging - APPEND - PROPERTY - SKIP_REGULAR_EXPRESSION - "unexpected new.*PASS\nTest with golden file failed. We'll try to show the diff:" - ) - endif(APPLE) - - if(TARGET signalhandler_unittest) - add_test(NAME signalhandler COMMAND signalhandler_unittest) - endif(TARGET signalhandler_unittest) - - if(TARGET stacktrace_unittest) - add_test(NAME stacktrace COMMAND stacktrace_unittest) - set_tests_properties(stacktrace PROPERTIES TIMEOUT 30) - endif(TARGET stacktrace_unittest) - - add_test(NAME stl_logging COMMAND stl_logging_unittest) - - if(TARGET symbolize_unittest) - add_test(NAME symbolize COMMAND symbolize_unittest) - endif(TARGET symbolize_unittest) - - if(HAVE_LIB_GMOCK) - add_executable(mock-log_unittest src/mock-log_unittest.cc src/mock-log.h) - - target_link_libraries(mock-log_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - add_test(NAME mock-log COMMAND mock-log_unittest) - endif(HAVE_LIB_GMOCK) - - # Generate an initial cache - - get_cache_variables(_CACHEVARS) - - set(_INITIAL_CACHE - ${CMAKE_CURRENT_BINARY_DIR}/test_package_config/glog_package_config_initial_cache.cmake - ) - - # Package config test - - add_test( - NAME cmake_package_config_init - COMMAND - ${CMAKE_COMMAND} - -DTEST_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/test_package_config - -DINITIAL_CACHE=${_INITIAL_CACHE} -DCACHEVARS=${_CACHEVARS} -P - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TestInitPackageConfig.cmake) - - add_test( - NAME cmake_package_config_generate - COMMAND - ${CMAKE_COMMAND} -DGENERATOR=${CMAKE_GENERATOR} - -DGENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} - -DGENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET} - -DINITIAL_CACHE=${_INITIAL_CACHE} - -DPACKAGE_DIR=${CMAKE_CURRENT_BINARY_DIR} -DPATH=$ENV{PATH} - -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/src/package_config_unittest/working_config - -DTEST_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/test_package_config/working_config - -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TestPackageConfig.cmake) - - add_test( - NAME cmake_package_config_build - COMMAND - ${CMAKE_COMMAND} --build - ${CMAKE_CURRENT_BINARY_DIR}/test_package_config/working_config --config - $) - - add_test(NAME cmake_package_config_cleanup - COMMAND ${CMAKE_COMMAND} -E remove_directory - ${CMAKE_CURRENT_BINARY_DIR}/test_package_config) - - # Fixtures setup - set_tests_properties(cmake_package_config_init - PROPERTIES FIXTURES_SETUP cmake_package_config) - set_tests_properties(cmake_package_config_generate - PROPERTIES FIXTURES_SETUP cmake_package_config_working) - - # Fixtures cleanup - set_tests_properties(cmake_package_config_cleanup - PROPERTIES FIXTURES_CLEANUP cmake_package_config) - - # Fixture requirements - set_tests_properties(cmake_package_config_generate - PROPERTIES FIXTURES_REQUIRED cmake_package_config) - set_tests_properties( - cmake_package_config_build - PROPERTIES FIXTURES_REQUIRED - "cmake_package_config;cmake_package_config_working") - - add_executable(cleanup_immediately_unittest - src/cleanup_immediately_unittest.cc) - - target_link_libraries(cleanup_immediately_unittest PRIVATE ${_GLOG_TEST_LIBS}) - - add_executable(cleanup_with_absolute_prefix_unittest - src/cleanup_with_absolute_prefix_unittest.cc) - - target_link_libraries(cleanup_with_absolute_prefix_unittest - PRIVATE ${_GLOG_TEST_LIBS}) - - add_executable(cleanup_with_relative_prefix_unittest - src/cleanup_with_relative_prefix_unittest.cc) - - target_link_libraries(cleanup_with_relative_prefix_unittest - PRIVATE ${_GLOG_TEST_LIBS}) - - set(CLEANUP_LOG_DIR ${CMAKE_CURRENT_BINARY_DIR}/cleanup_tests) - - add_test(NAME cleanup_init COMMAND ${CMAKE_COMMAND} -E make_directory - ${CLEANUP_LOG_DIR}) - add_test(NAME cleanup_logdir COMMAND ${CMAKE_COMMAND} -E remove_directory - ${CLEANUP_LOG_DIR}) - add_test( - NAME cleanup_immediately - COMMAND - ${CMAKE_COMMAND} -DLOGCLEANUP=$ - # NOTE The trailing slash is important - -DTEST_DIR=${CLEANUP_LOG_DIR}/ -P - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest1.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - add_test( - NAME cleanup_with_absolute_prefix - COMMAND - ${CMAKE_COMMAND} - -DLOGCLEANUP=$ - -DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}/ -P - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest2.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - add_test( - NAME cleanup_with_relative_prefix - COMMAND - ${CMAKE_COMMAND} - -DLOGCLEANUP=$ - -DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}/ -DTEST_SUBDIR=test_subdir/ -P - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunCleanerTest3.cmake - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - # Fixtures setup - set_tests_properties(cleanup_init PROPERTIES FIXTURES_SETUP logcleanuptest) - # Fixtures cleanup - set_tests_properties(cleanup_logdir PROPERTIES FIXTURES_CLEANUP - logcleanuptest) - # Fixture requirements - set_tests_properties(cleanup_immediately PROPERTIES FIXTURES_REQUIRED - logcleanuptest) - set_tests_properties(cleanup_with_absolute_prefix PROPERTIES FIXTURES_REQUIRED - logcleanuptest) - set_tests_properties(cleanup_with_relative_prefix PROPERTIES FIXTURES_REQUIRED - logcleanuptest) -endif() -# endif(BUILD_TESTING) - -# install (TARGETS glog EXPORT glog-targets RUNTIME DESTINATION -# ${_glog_CMake_BINDIR} PUBLIC_HEADER DESTINATION -# ${_glog_CMake_INCLUDE_DIR}/glog LIBRARY DESTINATION ${_glog_CMake_LIBDIR} -# ARCHIVE DESTINATION ${_glog_CMake_LIBDIR}) -# -if(WITH_PKGCONFIG) - install(FILES "${PROJECT_BINARY_DIR}/libglog.pc" - DESTINATION "${_glog_CMake_LIBDIR}/pkgconfig") -endif(WITH_PKGCONFIG) - -set(glog_CMake_VERSION 3.0) - -# if (gflags_FOUND) # Ensure clients locate only the package config and not -# third party find # modules having the same name. This avoid cmake_policy -# PUSH/POP errors. if (CMAKE_VERSION VERSION_LESS 3.9) set (gflags_DEPENDENCY -# "find_dependency (gflags ${gflags_VERSION})") else (CMAKE_VERSION VERSION_LESS -# 3.9) # Passing additional find_package arguments to find_dependency is -# possible # starting with CMake 3.9. set (glog_CMake_VERSION 3.9) set -# (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION} NO_MODULE)") -# endif (CMAKE_VERSION VERSION_LESS 3.9) endif (gflags_FOUND) - -# configure_package_config_file( glog-config.cmake.in -# ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake INSTALL_DESTINATION -# ${_glog_CMake_INSTALLDIR} NO_CHECK_REQUIRED_COMPONENTS_MACRO) -# -# write_basic_package_version_file( -# ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake COMPATIBILITY -# SameMajorVersion) - -# export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake) export (PACKAGE -# glog) - -get_filename_component(_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) - -# Directory containing the find modules relative to the config install -# directory. -file(RELATIVE_PATH glog_REL_CMake_MODULES ${_PREFIX}/${_glog_CMake_INSTALLDIR} - ${_PREFIX}/${_glog_CMake_DATADIR}/glog-modules.cmake) - -get_filename_component(glog_REL_CMake_DATADIR ${glog_REL_CMake_MODULES} - DIRECTORY) - -set(glog_FULL_CMake_DATADIR ${CMAKE_CURRENT_BINARY_DIR}/${_glog_CMake_DATADIR}) - -# configure_file(glog-modules.cmake.in -# ${CMAKE_CURRENT_BINARY_DIR}/glog-modules.cmake @ONLY) - -install( - CODE " -set (glog_FULL_CMake_DATADIR \"\\\${CMAKE_CURRENT_LIST_DIR}/${glog_REL_CMake_DATADIR}\") -set (glog_DATADIR_DESTINATION ${_glog_CMake_INSTALLDIR}) - -if (NOT IS_ABSOLUTE ${_glog_CMake_INSTALLDIR}) - set (glog_DATADIR_DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${glog_DATADIR_DESTINATION}\") -endif (NOT IS_ABSOLUTE ${_glog_CMake_INSTALLDIR}) - -configure_file (\"${CMAKE_CURRENT_SOURCE_DIR}/glog-modules.cmake.in\" - \"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/glog-modules.cmake\" @ONLY) -file (INSTALL - \"${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/glog-modules.cmake\" - DESTINATION - \"\${glog_DATADIR_DESTINATION}\") -" - COMPONENT Development) - -# install (FILES ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake -# ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake DESTINATION -# ${_glog_CMake_INSTALLDIR}) - -# Find modules in share/glog/cmake install (DIRECTORY -# ${_glog_BINARY_CMake_DATADIR} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/glog -# COMPONENT Development FILES_MATCHING PATTERN "*.cmake" ) - -# install (EXPORT glog-targets NAMESPACE glog:: DESTINATION -# ${_glog_CMake_INSTALLDIR}) diff --git a/third_party/glog/CONTRIBUTORS b/third_party/glog/CONTRIBUTORS deleted file mode 100644 index 05cb688..0000000 --- a/third_party/glog/CONTRIBUTORS +++ /dev/null @@ -1,52 +0,0 @@ -# People who have agreed to one of the CLAs and can contribute patches. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# -# Names should be added to this file only after verifying that -# the individual or the individual's organization has agreed to -# the appropriate Contributor License Agreement, found here: -# -# https://developers.google.com/open-source/cla/individual -# https://developers.google.com/open-source/cla/corporate -# -# The agreement for individuals can be filled out on the web. -# -# When adding J Random Contributor's name to this file, -# either J's name or J's organization's name should be -# added to the AUTHORS file, depending on whether the -# individual or corporate CLA was used. -# -# Names should be added to this file as: -# Name -# -# Please keep the list sorted. - -Abhishek Dasgupta -Abhishek Parmar -Andrew Schwartzmeyer -Andy Ying -Bret McKee -Brian Silverman -Dmitriy Arbitman -Fumitoshi Ukai -Guillaume Dumont -Håkan L. S. Younes -Ivan Penkov -Jacob Trimble -Jim Ray -Marco Wang -Michael Darr -Michael Tanner -MiniLight -Peter Collingbourne -Rodrigo Queiro -romange -Roman Perepelitsa -Sergiu Deitsch -Shinichiro Hamaji -tbennun -Teddy Reed -Vijaymahantesh Sattigeri -Zhongming Qu -Zhuoran Shen diff --git a/third_party/glog/COPYING b/third_party/glog/COPYING deleted file mode 100644 index 38396b5..0000000 --- a/third_party/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/glog/ChangeLog b/third_party/glog/ChangeLog deleted file mode 100644 index a107e93..0000000 --- a/third_party/glog/ChangeLog +++ /dev/null @@ -1,109 +0,0 @@ -2022-04-05 Google Inc. - - * google-glog: version 0.6.0. - * See git log for the details. - -2021-05-08 Google Inc. - - * google-glog: version 0.5.0. - * See git log for the details. - -2019-01-22 Google Inc. - - * google-glog: version 0.4.0. - * See git log for the details. - -2017-05-09 Google Inc. - - * google-glog: version 0.3.5 - * See git log for the details. - -2015-03-09 Google Inc. - - * google-glog: version 0.3.4 - * See git log for the details. - -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/glog/README.rst b/third_party/glog/README.rst deleted file mode 100644 index 0131f49..0000000 --- a/third_party/glog/README.rst +++ /dev/null @@ -1,879 +0,0 @@ -Google Logging Library -====================== - -|Linux Github actions| |Windows Github actions| |macOS Github actions| |Total alerts| |Language grade: C++| |Codecov| - -Google Logging (glog) is a C++98 library that implements application-level -logging. The library provides logging APIs based on C++-style streams and -various helper macros. - -.. role:: cmake(code) - :language: cmake - -.. role:: cmd(code) - :language: bash - -.. role:: cpp(code) - :language: cpp - -.. role:: bazel(code) - :language: starlark - - -Getting Started ---------------- - -You can log a message by simply streaming things to ``LOG``\ (`__>), e.g., - -.. code:: cpp - - #include - - int main(int argc, char* argv[]) { - // Initialize Google’s logging library. - google::InitGoogleLogging(argv[0]); - - // ... - LOG(INFO) << "Found " << num_cookies << " cookies"; - } - - -For a detailed overview of glog features and their usage, please refer -to the `user guide <#user-guide>`__. - -.. contents:: Table of Contents - - -Building from Source --------------------- - -glog supports multiple build systems for compiling the project from -source: `Bazel <#bazel>`__, `CMake <#cmake>`__, and `vcpkg <#vcpkg>`__. - -Bazel -~~~~~ - -To use glog within a project which uses the -`Bazel `__ build tool, add the following lines to -your ``WORKSPACE`` file: - -.. code:: bazel - - load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - - http_archive( - name = "com_github_gflags_gflags", - sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", - strip_prefix = "gflags-2.2.2", - urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"], - ) - - http_archive( - name = "com_github_google_glog", - sha256 = "21bc744fb7f2fa701ee8db339ded7dce4f975d0d55837a97be7d46e8382dea5a", - strip_prefix = "glog-0.5.0", - urls = ["https://github.com/google/glog/archive/v0.5.0.zip"], - ) - -You can then add :bazel:`@com_github_google_glog//:glog` to the deps section -of a :bazel:`cc_binary` or :bazel:`cc_library` rule, and :code:`#include -` to include it in your source code. Here’s a simple example: - -.. code:: bazel - - cc_binary( - name = "main", - srcs = ["main.cc"], - deps = ["@com_github_google_glog//:glog"], - ) - -CMake -~~~~~ - -glog also supports CMake that can be used to build the project on a wide -range of platforms. If you don’t have CMake installed already, you can -download it for from CMake’s `official -website `__. - -CMake works by generating native makefiles or build projects that can be -used in the compiler environment of your choice. You can either build -glog with CMake as a standalone project or it can be incorporated into -an existing CMake build for another project. - -Building glog with CMake -^^^^^^^^^^^^^^^^^^^^^^^^ - -When building glog as a standalone project, on Unix-like systems with -GNU Make as build tool, the typical workflow is: - -1. Get the source code and change to it. e.g., cloning with git: - - .. code:: bash - - git clone https://github.com/google/glog.git - cd glog - -2. Run CMake to configure the build tree. - - .. code:: bash - - cmake -S . -B build -G "Unix Makefiles" - - CMake provides different generators, and by default will pick the most - relevant one to your environment. If you need a specific version of Visual - Studio, use :cmd:`cmake . -G `, and see :cmd:`cmake --help` - for the available generators. Also see :cmd:`-T `, which can - be used to request the native x64 toolchain with :cmd:`-T host=x64`. - -3. Afterwards, generated files can be used to compile the project. - - .. code:: bash - - cmake --build build - -4. Test the build software (optional). - - .. code:: bash - - cmake --build build --target test - -5. Install the built files (optional). - - .. code:: bash - - cmake --build build --target install - -Consuming glog in a CMake Project -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you have glog installed in your system, you can use the CMake command -:cmake:`find_package` to build against glog in your CMake Project as follows: - -.. code:: cmake - - cmake_minimum_required (VERSION 3.16) - project (myproj VERSION 1.0) - - find_package (glog 0.6.0 REQUIRED) - - add_executable (myapp main.cpp) - target_link_libraries (myapp glog::glog) - -Compile definitions and options will be added automatically to your -target as needed. - -Incorporating glog into a CMake Project -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can also use the CMake command :cmake:`add_subdirectory` to include glog -directly from a subdirectory of your project by replacing the -:cmake:`find_package` call from the previous example by -:cmake:`add_subdirectory`. The :cmake:`glog::glog` target is in this case an -:cmake:`ALIAS` library target for the ``glog`` library target. - -Again, compile definitions and options will be added automatically to -your target as needed. - -vcpkg -~~~~~ - -You can download and install glog using the `vcpkg -`__ dependency manager: - -.. code:: bash - - git clone https://github.com/Microsoft/vcpkg.git - cd vcpkg - ./bootstrap-vcpkg.sh - ./vcpkg integrate install - ./vcpkg install glog - -The glog port in vcpkg is kept up to date by Microsoft team members and -community contributors. If the version is out of date, please create an -issue or pull request on the vcpkg repository. - -User Guide ----------- - -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, customize the prefix attached to log messages, and more. - -Following sections describe the functionality supported by glog. Please note -this description may not be complete but limited to the most useful ones. If you -want to find less common features, please check header files under `src/glog -`__ directory. - -Severity Levels -~~~~~~~~~~~~~~~ - -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/\.\.\.log.\.\-\.\`` -(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 build -system will automatically detect and use it, allowing you to pass flags on the -command line. For example, if you want to turn the flag :cmd:`--logtostderr` on, -you can start your application with the following command line: - -.. code:: bash - - ./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., - -.. code:: bash - - 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 :cmd:`--vmodule`. See `the section about - verbose logging <#verbose-logging>`__ for more detail. - -``vmodule`` (``string``, default="") - Per-module verbose level. The argument has to contain a - comma-separated list of =. 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). overrides any value given by :cmd:`--v`. - See also `the section about verbose logging <#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 :cpp:`google::InitGoogleLogging` . Here is an example: - -.. code:: cpp - - 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: - -.. code:: cpp - - 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. - -.. code:: cpp - - 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. - -.. code:: cpp - - 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: - -.. code:: cpp - - 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. - -Other times, it is desired to only log a message periodically based on a time. -So for example, to log a message every 10ms: - -.. code:: cpp - - LOG_EVERY_T(INFO, 0.01) << "Got a cookie"; - -Or every 2.35s: - -.. code:: cpp - - LOG_EVERY_T(INFO, 2.35) << "Got a cookie"; - -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. - -.. code:: cpp - - 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: - -.. code:: cpp - - 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 :cpp:`operator<<(ostream, ...)` defined. - -You may append to the error message like so: - -.. code:: cpp - - 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: - -.. code:: cpp - - CHECK_EQ(string("abc")[1], ’b’); - -The compiler reports an error if one of the arguments is a pointer and the other -is :cpp:`NULL`. To work around this, simply :cpp:`static_cast` :cpp:`NULL` to -the type of the desired pointer. - -.. code:: cpp - - CHECK_EQ(some_ptr, static_cast(NULL)); - -Better yet, use the ``CHECK_NOTNULL`` macro: - -.. code:: cpp - - CHECK_NOTNULL(some_ptr); - some_ptr->DoSomething(); - -Since this macro returns the given pointer, this is very useful in -constructor initializer lists. - -.. code:: cpp - - 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 (:cpp:`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 :cpp:`NULL` pointers for this macro. They -treat :cpp:`NULL` and any non-:cpp:`NULL` string as not equal. Two :cpp:`NULL`\ -s are equal. - -Note that both arguments may be temporary strings which are destructed -at the end of the current "full expression" (e.g., -:cpp:`CHECK_STREQ(Foo().c_str(), Bar().c_str())` where ``Foo`` and ``Bar`` -return C++’s :cpp:`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 :cmd:`--v` command line option -controls which verbose messages are logged: - -.. code:: cpp - - 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 :cmd:`--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. :cmd:`--minloglevel` of 1 will log ``WARNING`` and above. Though -you can specify any integers for both ``VLOG`` macro and :cmd:`--v` flag, the -common values for them are small positive integers. For example, if you write -``VLOG(0)``, you should specify :cmd:`--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: - -.. code:: bash - - --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 <#setting-flags>`__. - -There’s also ``VLOG_IS_ON(n)`` "verbose level" condition macro. This -macro returns true when the :cmd:`--v` is equal or greater than ``n``. To -be used as - -.. code:: cpp - - 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. - -.. code:: cpp - - 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; - - -Custom Log Prefix Format -~~~~~~~~~~~~~~~~~~~~~~~~ - -glog supports changing the format of the prefix attached to log messages by -receiving a user-provided callback to be used to generate such strings. That -feature must be enabled at compile time by the ``WITH_CUSTOM_PREFIX`` flag. - -For each log entry, the callback will be invoked with a ``LogMessageInfo`` -struct containing the severity, filename, line number, thread ID, and time of -the event. It will also be given a reference to the output stream, whose -contents will be prepended to the actual message in the final log line. - -For example: - -.. code:: cpp - - /* This function writes a prefix that matches glog's default format. - * (The third parameter can be used to receive user-supplied data, and is - * NULL by default.) - */ - void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) { - s << l.severity[0] - << setw(4) << 1900 + l.time.year() - << setw(2) << 1 + l.time.month() - << setw(2) << l.time.day() - << ' ' - << setw(2) << l.time.hour() << ':' - << setw(2) << l.time.min() << ':' - << setw(2) << l.time.sec() << "." - << setw(6) << l.time.usec() - << ' ' - << setfill(' ') << setw(5) - << l.thread_id << setfill('0') - << ' ' - << l.filename << ':' << l.line_number << "]"; - } - - -To enable the use of ``CustomPrefix()``, simply give glog a pointer to it -during initialization: ``InitGoogleLogging(argv[0], &CustomPrefix);``. - -Optionally, ``InitGoogleLogging()`` takes a third argument of type ``void*`` -to pass on to the callback function. - -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 :cpp:`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 :cpp:`InstallFailureWriter()`. - -Performance of Messages -~~~~~~~~~~~~~~~~~~~~~~~ - -The conditional logging macros provided by glog (e.g., ``CHECK``, -``LOG_IF``, ``VLOG``, etc.) 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. - -.. code:: cpp - - 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 :cpp:`InstallFailureFunction`. - -.. code:: cpp - - void YourFailureFunction() { - // Reports something... - exit(EXIT_FAILURE); - } - - 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 ```` 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. - -.. code:: cpp - - 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: - -.. code:: cpp - - #define GOOGLE_STRIP_LOG 1 // this must go before the #include! - #include - -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 ``VLOG``\ s as well as -``INFO`` log statements. - -Automatically Remove Old Logs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To enable the log cleaner: - -.. code:: cpp - - google::EnableLogCleaner(3); // keep your logs for 3 days - -And then glog will check if there are overdue logs whenever a flush is -performed. In this example, any log file from your project whose last -modified time is greater than 3 days will be unlink()ed. - -This feature can be disabled at any time (if it has been enabled) - -.. code:: cpp - - google::DisableLogCleaner(); - -Notes for Windows Users -~~~~~~~~~~~~~~~~~~~~~~~ - -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: - -.. code:: cpp - - #define GLOG_NO_ABBREVIATED_SEVERITIES - #include - #include - - // ... - - 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`` . - -.. code:: cpp - - #define GLOG_NO_ABBREVIATED_SEVERITIES - #include - #include - - // ... - - // 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. - - -Installation Notes for 64-bit Linux Systems -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The glibc built-in stack-unwinder on 64-bit systems has some problems with glog. -(In particular, if you are using :cpp:`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 -:cpp:`InstallFailureSignalHandler()`, we strongly recommend you install -``libunwind`` before trying to configure or install google glog. -libunwind can be found -`here `__. - -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 -:cmd:`-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 :cmd:`-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 :cpp:`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. - - -How to Contribute ------------------ - -We’d love to accept your patches and contributions to this project. -There are a just a few small guidelines you need to follow. - -Contributor License Agreement (CLA) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Contributions to any Google project must be accompanied by a Contributor -License Agreement. This is not a copyright **assignment**, it simply -gives Google permission to use and redistribute your contributions as -part of the project. - -* If you are an individual writing original source code and you’re sure - you own the intellectual property, then you’ll need to sign an - `individual - CLA `__. -* If you work for a company that wants to allow you to contribute your - work, then you’ll need to sign a `corporate - CLA `__. - -You generally only need to submit a CLA once, so if you’ve already -submitted one (even if it was for a different project), you probably -don’t need to do it again. - -Once your CLA is submitted (or if you already submitted one for another -Google project), make a commit adding yourself to the -`AUTHORS <./AUTHORS>`__ and `CONTRIBUTORS <./CONTRIBUTORS>`__ files. This -commit can be part of your first `pull -request `__. - -Submitting a Patch -~~~~~~~~~~~~~~~~~~ - -1. It’s generally best to start by opening a new issue describing the - bug or feature you’re intending to fix. Even if you think it’s - relatively minor, it’s helpful to know what people are working on. - Mention in the initial issue that you are planning to work on that - bug or feature so that it can be assigned to you. -2. Follow the normal process of - `forking `__ the - project, and setup a new branch to work in. It’s important that each - group of changes be done in separate branches in order to ensure that - a pull request only includes the commits related to that bug or - feature. -3. Do your best to have `well-formed commit - messages `__ - for each change. This provides consistency throughout the project, - and ensures that commit messages are able to be formatted properly by - various git tools. -4. Finally, push the commits to your fork and submit a `pull - request `__. - - -.. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux.yml/badge.svg - :target: https://github.com/google/glog/actions -.. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows.yml/badge.svg - :target: https://github.com/google/glog/actions -.. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos.yml/badge.svg - :target: https://github.com/google/glog/actions -.. |Total alerts| image:: https://img.shields.io/lgtm/alerts/g/google/glog.svg?logo=lgtm&logoWidth=18 - :target: https://lgtm.com/projects/g/google/glog/alerts/ -.. |Language grade: C++| image:: https://img.shields.io/lgtm/grade/cpp/g/google/glog.svg?logo=lgtm&logoWidth=18) - :target: https://lgtm.com/projects/g/google/glog/context:cpp -.. |Codecov| image:: https://codecov.io/gh/google/glog/branch/master/graph/badge.svg?token=8an420vNju - :target: https://codecov.io/gh/google/glog diff --git a/third_party/glog/WORKSPACE b/third_party/glog/WORKSPACE deleted file mode 100644 index 10c89f6..0000000 --- a/third_party/glog/WORKSPACE +++ /dev/null @@ -1,11 +0,0 @@ -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "com_github_gflags_gflags", - sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", - strip_prefix = "gflags-2.2.2", - urls = [ - "https://mirror.bazel.build/github.com/gflags/gflags/archive/v2.2.2.tar.gz", - "https://github.com/gflags/gflags/archive/v2.2.2.tar.gz", - ], -) diff --git a/third_party/glog/bazel/example/BUILD.bazel b/third_party/glog/bazel/example/BUILD.bazel deleted file mode 100644 index 05ab0f3..0000000 --- a/third_party/glog/bazel/example/BUILD.bazel +++ /dev/null @@ -1,9 +0,0 @@ -cc_test( - name = "main", - size = "small", - srcs = ["main.cc"], - deps = [ - "//:glog", - "@com_github_gflags_gflags//:gflags", - ], -) diff --git a/third_party/glog/bazel/example/main.cc b/third_party/glog/bazel/example/main.cc deleted file mode 100644 index fef01dc..0000000 --- a/third_party/glog/bazel/example/main.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int main(int argc, char* argv[]) { - // Initialize Google's logging library. - google::InitGoogleLogging(argv[0]); - - // Optional: parse command line flags - gflags::ParseCommandLineFlags(&argc, &argv, true); - - LOG(INFO) << "Hello, world!"; - - // glog/stl_logging.h allows logging STL containers. - std::vector x; - x.push_back(1); - x.push_back(2); - x.push_back(3); - LOG(INFO) << "ABC, it's easy as " << x; - - return 0; -} diff --git a/third_party/glog/bazel/glog.bzl b/third_party/glog/bazel/glog.bzl deleted file mode 100644 index 4208d9e..0000000 --- a/third_party/glog/bazel/glog.bzl +++ /dev/null @@ -1,276 +0,0 @@ -# Implement a macro glog_library() that the BUILD.bazel file can load. - -# By default, glog is built with gflags support. You can change this behavior -# by using glog_library(with_gflags=0) -# -# This file is inspired by the following sample BUILD files: -# https://github.com/google/glog/issues/61 -# https://github.com/google/glog/files/393474/BUILD.txt -# -# Known issue: the namespace parameter is not supported on Win32. - -def expand_template_impl(ctx): - ctx.actions.expand_template( - template = ctx.file.template, - output = ctx.outputs.out, - substitutions = ctx.attr.substitutions, - ) - -expand_template = rule( - implementation = expand_template_impl, - attrs = { - "template": attr.label(mandatory = True, allow_single_file = True), - "substitutions": attr.string_dict(mandatory = True), - "out": attr.output(mandatory = True), - }, -) - -def dict_union(x, y): - z = {} - z.update(x) - z.update(y) - return z - -def glog_library(namespace = "google", with_gflags = 1, **kwargs): - if native.repository_name() != "@": - repo_name = native.repository_name().lstrip("@") - gendir = "$(GENDIR)/external/" + repo_name - src_windows = "external/%s/src/windows" % repo_name - else: - gendir = "$(GENDIR)" - src_windows = "src/windows" - - # Config setting for WebAssembly target. - native.config_setting( - name = "wasm", - values = {"cpu": "wasm"}, - ) - - # Detect when building with clang-cl on Windows. - native.config_setting( - name = "clang-cl", - values = {"compiler": "clang-cl"}, - ) - - common_copts = [ - "-DGLOG_BAZEL_BUILD", - # Inject a C++ namespace. - "-DGOOGLE_NAMESPACE='%s'" % namespace, - "-DHAVE_CXX11_NULLPTR_T", - "-DHAVE_STDINT_H", - "-DHAVE_STRING_H", - "-DGLOG_CUSTOM_PREFIX_SUPPORT", - "-I%s/glog_internal" % gendir, - ] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else []) - - wasm_copts = [ - # Disable warnings that exists in glog. - "-Wno-sign-compare", - "-Wno-unused-function", - "-Wno-unused-local-typedefs", - "-Wno-unused-variable", - # Allows src/base/mutex.h to include pthread.h. - "-DHAVE_PTHREAD", - # Allows src/logging.cc to determine the host name. - "-DHAVE_SYS_UTSNAME_H", - # For src/utilities.cc. - "-DHAVE_SYS_TIME_H", - "-DHAVE_UNWIND_H", - # Enable dumping stacktrace upon sigaction. - "-DHAVE_SIGACTION", - # For logging.cc. - "-DHAVE_PREAD", - "-DHAVE___ATTRIBUTE__", - ] - - linux_or_darwin_copts = wasm_copts + [ - "-DGLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))", - # For src/utilities.cc. - "-DHAVE_SYS_SYSCALL_H", - # For src/logging.cc to create symlinks. - "-DHAVE_UNISTD_H", - "-fvisibility-inlines-hidden", - "-fvisibility=hidden", - ] - - freebsd_only_copts = [ - # Enable declaration of _Unwind_Backtrace - "-D_GNU_SOURCE", - ] - - darwin_only_copts = [ - # For stacktrace. - "-DHAVE_DLADDR", - # Avoid deprecated syscall(). - "-DHAVE_PTHREAD_THREADID_NP", - ] - - windows_only_copts = [ - # Override -DGLOG_EXPORT= from the cc_library's defines. - "-DGLOG_EXPORT=__declspec(dllexport)", - "-DGLOG_NO_ABBREVIATED_SEVERITIES", - "-DHAVE_SNPRINTF", - "-I" + src_windows, - ] - - clang_cl_only_copts = [ - # Allow the override of -DGLOG_EXPORT. - "-Wno-macro-redefined", - ] - - windows_only_srcs = [ - "src/glog/log_severity.h", - "src/windows/dirent.h", - "src/windows/port.cc", - "src/windows/port.h", - ] - - gflags_deps = ["@com_github_gflags_gflags//:gflags"] if with_gflags else [] - - native.cc_library( - name = "glog", - visibility = ["//visibility:public"], - srcs = [ - ":config_h", - "src/base/commandlineflags.h", - "src/base/googleinit.h", - "src/base/mutex.h", - "src/demangle.cc", - "src/demangle.h", - "src/logging.cc", - "src/raw_logging.cc", - "src/signalhandler.cc", - "src/stacktrace.h", - "src/stacktrace_generic-inl.h", - "src/stacktrace_libunwind-inl.h", - "src/stacktrace_powerpc-inl.h", - "src/stacktrace_unwind-inl.h", - "src/stacktrace_windows-inl.h", - "src/stacktrace_x86-inl.h", - "src/symbolize.cc", - "src/symbolize.h", - "src/utilities.cc", - "src/utilities.h", - "src/vlog_is_on.cc", - ] + select({ - "@bazel_tools//src/conditions:windows": windows_only_srcs, - "//conditions:default": [], - }), - hdrs = [ - "src/glog/log_severity.h", - "src/glog/platform.h", - ":logging_h", - ":raw_logging_h", - ":stl_logging_h", - ":vlog_is_on_h", - ], - strip_include_prefix = "src", - defines = select({ - # GLOG_EXPORT is normally set by export.h, but that's not - # generated for Bazel. - "@bazel_tools//src/conditions:windows": [ - "GLOG_EXPORT=", - "GLOG_DEPRECATED=__declspec(deprecated)", - "GLOG_NO_ABBREVIATED_SEVERITIES", - ], - "//conditions:default": [ - "GLOG_DEPRECATED=__attribute__((deprecated))", - "GLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))", - ], - }), - copts = - select({ - "@bazel_tools//src/conditions:windows": common_copts + windows_only_copts, - "@bazel_tools//src/conditions:darwin": common_copts + linux_or_darwin_copts + darwin_only_copts, - "@bazel_tools//src/conditions:freebsd": common_copts + linux_or_darwin_copts + freebsd_only_copts, - ":wasm": common_copts + wasm_copts, - "//conditions:default": common_copts + linux_or_darwin_copts, - }) + - select({ - ":clang-cl": clang_cl_only_copts, - "//conditions:default": [] - }), - deps = gflags_deps + select({ - "@bazel_tools//src/conditions:windows": [":strip_include_prefix_hack"], - "//conditions:default": [], - }), - **kwargs - ) - - # Workaround https://github.com/bazelbuild/bazel/issues/6337 by declaring - # the dependencies without strip_include_prefix. - native.cc_library( - name = "strip_include_prefix_hack", - hdrs = [ - "src/glog/log_severity.h", - ":logging_h", - ":raw_logging_h", - ":stl_logging_h", - ":vlog_is_on_h", - ], - ) - - expand_template( - name = "config_h", - template = "src/config.h.cmake.in", - out = "glog_internal/config.h", - substitutions = {"#cmakedefine": "//cmakedefine"}, - ) - - common_config = { - "@ac_cv_cxx11_atomic@": "1", - "@ac_cv_cxx11_constexpr@": "1", - "@ac_cv_cxx11_chrono@": "1", - "@ac_cv_cxx11_nullptr_t@": "1", - "@ac_cv_cxx_using_operator@": "1", - "@ac_cv_have_inttypes_h@": "0", - "@ac_cv_have_u_int16_t@": "0", - "@ac_cv_have_glog_export@": "0", - "@ac_google_start_namespace@": "namespace google {", - "@ac_google_end_namespace@": "}", - "@ac_google_namespace@": "google", - } - - posix_config = dict_union(common_config, { - "@ac_cv_have_unistd_h@": "1", - "@ac_cv_have_stdint_h@": "1", - "@ac_cv_have_systypes_h@": "1", - "@ac_cv_have_uint16_t@": "1", - "@ac_cv_have___uint16@": "0", - "@ac_cv_have___builtin_expect@": "1", - "@ac_cv_have_libgflags@": "1" if with_gflags else "0", - "@ac_cv___attribute___noinline@": "__attribute__((noinline))", - "@ac_cv___attribute___noreturn@": "__attribute__((noreturn))", - "@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))", - }) - - windows_config = dict_union(common_config, { - "@ac_cv_have_unistd_h@": "0", - "@ac_cv_have_stdint_h@": "0", - "@ac_cv_have_systypes_h@": "0", - "@ac_cv_have_uint16_t@": "0", - "@ac_cv_have___uint16@": "1", - "@ac_cv_have___builtin_expect@": "0", - "@ac_cv_have_libgflags@": "0", - "@ac_cv___attribute___noinline@": "", - "@ac_cv___attribute___noreturn@": "__declspec(noreturn)", - "@ac_cv___attribute___printf_4_5@": "", - }) - - [ - expand_template( - name = "%s_h" % f, - template = "src/glog/%s.h.in" % f, - out = "src/glog/%s.h" % f, - substitutions = select({ - "@bazel_tools//src/conditions:windows": windows_config, - "//conditions:default": posix_config, - }), - ) - for f in [ - "vlog_is_on", - "stl_logging", - "raw_logging", - "logging", - ] - ] diff --git a/third_party/glog/cmake/DetermineGflagsNamespace.cmake b/third_party/glog/cmake/DetermineGflagsNamespace.cmake deleted file mode 100644 index 3dde42b..0000000 --- a/third_party/glog/cmake/DetermineGflagsNamespace.cmake +++ /dev/null @@ -1,69 +0,0 @@ -macro(determine_gflags_namespace VARIABLE) - if (NOT DEFINED "${VARIABLE}") - if (CMAKE_REQUIRED_INCLUDES) - set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}") - else () - set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS) - endif () - - set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS}) - - set(_NAMESPACES gflags google) - set(_check_code -" -#include - -int main(int argc, char**argv) -{ - GLOG_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true); -} -") - if (NOT CMAKE_REQUIRED_QUIET) - message (STATUS "Looking for gflags namespace") - endif () - if (${ARGC} EQUAL 3) - set (CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS}) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}") - endif () - - set (_check_file - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/DetermineGflagsNamespace.cxx) - - foreach (_namespace ${_NAMESPACES}) - file (WRITE "${_check_file}" "${_check_code}") - try_compile (${VARIABLE} - "${CMAKE_BINARY_DIR}" "${_check_file}" - COMPILE_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}" -DGLOG_GFLAGS_NAMESPACE=${_namespace} - LINK_LIBRARIES gflags - CMAKE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - OUTPUT_VARIABLE OUTPUT) - - if (${VARIABLE}) - set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace" FORCE) - break () - else () - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining the gflags namespace ${_namespace} failed with the following output:\n" - "${OUTPUT}\n\n") - endif () - endforeach (_namespace) - - if (${ARGC} EQUAL 3) - set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE}) - endif () - - if (${VARIABLE}) - if (NOT CMAKE_REQUIRED_QUIET) - message (STATUS "Looking for gflags namespace - ${${VARIABLE}}") - endif () - file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining the gflags namespace passed with the following output:\n" - "${OUTPUT}\n\n") - else () - if (NOT CMAKE_REQUIRED_QUIET) - message (STATUS "Looking for gflags namespace - failed") - endif () - set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace") - endif () - endif () -endmacro () diff --git a/third_party/glog/cmake/FindUnwind.cmake b/third_party/glog/cmake/FindUnwind.cmake deleted file mode 100644 index a7a976b..0000000 --- a/third_party/glog/cmake/FindUnwind.cmake +++ /dev/null @@ -1,61 +0,0 @@ -# - Try to find libunwind -# Once done this will define -# -# Unwind_FOUND - system has libunwind -# unwind::unwind - cmake target for libunwind - -include (FindPackageHandleStandardArgs) - -find_path (Unwind_INCLUDE_DIR NAMES unwind.h libunwind.h DOC "unwind include directory") -find_library (Unwind_LIBRARY NAMES unwind DOC "unwind library") - -mark_as_advanced (Unwind_INCLUDE_DIR Unwind_LIBRARY) - -# Extract version information -if (Unwind_LIBRARY) - set (_Unwind_VERSION_HEADER ${Unwind_INCLUDE_DIR}/libunwind-common.h) - - if (EXISTS ${_Unwind_VERSION_HEADER}) - file (READ ${_Unwind_VERSION_HEADER} _Unwind_VERSION_CONTENTS) - - string (REGEX REPLACE ".*#define UNW_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" - Unwind_VERSION_MAJOR "${_Unwind_VERSION_CONTENTS}") - string (REGEX REPLACE ".*#define UNW_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" - Unwind_VERSION_MINOR "${_Unwind_VERSION_CONTENTS}") - string (REGEX REPLACE ".*#define UNW_VERSION_EXTRA[ \t]+([0-9]+).*" "\\1" - Unwind_VERSION_PATCH "${_Unwind_VERSION_CONTENTS}") - - set (Unwind_VERSION ${Unwind_VERSION_MAJOR}.${Unwind_VERSION_MINOR}) - - if (CMAKE_MATCH_0) - # Third version component may be empty - set (Unwind_VERSION ${Unwind_VERSION}.${Unwind_VERSION_PATCH}) - set (Unwind_VERSION_COMPONENTS 3) - else (CMAKE_MATCH_0) - set (Unwind_VERSION_COMPONENTS 2) - endif (CMAKE_MATCH_0) - endif (EXISTS ${_Unwind_VERSION_HEADER}) -endif (Unwind_LIBRARY) - -# handle the QUIETLY and REQUIRED arguments and set Unwind_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args (Unwind - REQUIRED_VARS Unwind_INCLUDE_DIR Unwind_LIBRARY - VERSION_VAR Unwind_VERSION -) - -if (Unwind_FOUND) - if (NOT TARGET unwind::unwind) - add_library (unwind::unwind INTERFACE IMPORTED) - - set_property (TARGET unwind::unwind PROPERTY - INTERFACE_INCLUDE_DIRECTORIES ${Unwind_INCLUDE_DIR} - ) - set_property (TARGET unwind::unwind PROPERTY - INTERFACE_LINK_LIBRARIES ${Unwind_LIBRARY} - ) - set_property (TARGET unwind::unwind PROPERTY - IMPORTED_CONFIGURATIONS RELEASE - ) - endif (NOT TARGET unwind::unwind) -endif (Unwind_FOUND) diff --git a/third_party/glog/cmake/GetCacheVariables.cmake b/third_party/glog/cmake/GetCacheVariables.cmake deleted file mode 100644 index ead3589..0000000 --- a/third_party/glog/cmake/GetCacheVariables.cmake +++ /dev/null @@ -1,70 +0,0 @@ -cmake_policy (PUSH) -cmake_policy (VERSION 3.3) - -include (CMakeParseArguments) - -function (get_cache_variables _CACHEVARS) - set (_SINGLE) - set (_MULTI EXCLUDE) - set (_OPTIONS) - - cmake_parse_arguments (_ARGS "${_OPTIONS}" "${_SINGLE}" "${_MULTI}" ${ARGS} ${ARGN}) - - get_cmake_property (_VARIABLES VARIABLES) - - set (CACHEVARS) - - foreach (_VAR ${_VARIABLES}) - if (DEFINED _ARGS_EXCLUDE) - if ("${_VAR}" IN_LIST _ARGS_EXCLUDE) - continue () - endif ("${_VAR}" IN_LIST _ARGS_EXCLUDE) - endif (DEFINED _ARGS_EXCLUDE) - - get_property (_CACHEVARTYPE CACHE ${_VAR} PROPERTY TYPE) - - if ("${_CACHEVARTYPE}" STREQUAL INTERNAL OR - "${_CACHEVARTYPE}" STREQUAL STATIC OR - "${_CACHEVARTYPE}" STREQUAL UNINITIALIZED) - continue () - endif ("${_CACHEVARTYPE}" STREQUAL INTERNAL OR - "${_CACHEVARTYPE}" STREQUAL STATIC OR - "${_CACHEVARTYPE}" STREQUAL UNINITIALIZED) - - get_property (_CACHEVARVAL CACHE ${_VAR} PROPERTY VALUE) - - if ("${_CACHEVARVAL}" STREQUAL "") - continue () - endif ("${_CACHEVARVAL}" STREQUAL "") - - get_property (_CACHEVARDOC CACHE ${_VAR} PROPERTY HELPSTRING) - - # Escape " in values - string (REPLACE "\"" "\\\"" _CACHEVARVAL "${_CACHEVARVAL}") - # Escape " in help strings - string (REPLACE "\"" "\\\"" _CACHEVARDOC "${_CACHEVARDOC}") - # Escape ; in values - string (REPLACE ";" "\\\;" _CACHEVARVAL "${_CACHEVARVAL}") - # Escape ; in help strings - string (REPLACE ";" "\\\;" _CACHEVARDOC "${_CACHEVARDOC}") - # Escape backslashes in values except those that are followed by a - # quote. - string (REGEX REPLACE "\\\\([^\"])" "\\\\\\1" _CACHEVARVAL "${_CACHEVARVAL}") - # Escape backslashes in values that are followed by a letter to avoid - # invalid escape sequence errors. - string (REGEX REPLACE "\\\\([a-zA-Z])" "\\\\\\\\1" _CACHEVARVAL "${_CACHEVARVAL}") - string (REPLACE "\\\\" "\\\\\\\\" _CACHEVARDOC "${_CACHEVARDOC}") - - if (NOT "${_CACHEVARTYPE}" STREQUAL BOOL) - set (_CACHEVARVAL "\"${_CACHEVARVAL}\"") - endif (NOT "${_CACHEVARTYPE}" STREQUAL BOOL) - - if (NOT "${_CACHEVARTYPE}" STREQUAL "" AND NOT "${_CACHEVARVAL}" STREQUAL "") - set (CACHEVARS "${CACHEVARS}set (${_VAR} ${_CACHEVARVAL} CACHE ${_CACHEVARTYPE} \"${_CACHEVARDOC}\")\n") - endif (NOT "${_CACHEVARTYPE}" STREQUAL "" AND NOT "${_CACHEVARVAL}" STREQUAL "") - endforeach (_VAR) - - set (${_CACHEVARS} ${CACHEVARS} PARENT_SCOPE) -endfunction (get_cache_variables) - -cmake_policy (POP) diff --git a/third_party/glog/cmake/RunCleanerTest1.cmake b/third_party/glog/cmake/RunCleanerTest1.cmake deleted file mode 100644 index 7fbf463..0000000 --- a/third_party/glog/cmake/RunCleanerTest1.cmake +++ /dev/null @@ -1,22 +0,0 @@ -set (RUNS 3) - -foreach (iter RANGE 1 ${RUNS}) - set (ENV{GOOGLE_LOG_DIR} ${TEST_DIR}) - execute_process (COMMAND ${LOGCLEANUP} RESULT_VARIABLE _RESULT) - - if (NOT _RESULT EQUAL 0) - message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})") - endif (NOT _RESULT EQUAL 0) - - # Ensure the log files to have different modification timestamps such that - # exactly one log file remains at the end. Otherwise all log files will be - # retained. - execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 1) -endforeach (iter) - -file (GLOB LOG_FILES ${TEST_DIR}/*.foobar) -list (LENGTH LOG_FILES NUM_FILES) - -if (NOT NUM_FILES EQUAL 1) - message (SEND_ERROR "Expected 1 log file in log directory but found ${NUM_FILES}") -endif (NOT NUM_FILES EQUAL 1) diff --git a/third_party/glog/cmake/RunCleanerTest2.cmake b/third_party/glog/cmake/RunCleanerTest2.cmake deleted file mode 100644 index d3b51e3..0000000 --- a/third_party/glog/cmake/RunCleanerTest2.cmake +++ /dev/null @@ -1,22 +0,0 @@ -set (RUNS 3) - -foreach (iter RANGE 1 ${RUNS}) - execute_process (COMMAND ${LOGCLEANUP} -log_dir=${TEST_DIR} - RESULT_VARIABLE _RESULT) - - if (NOT _RESULT EQUAL 0) - message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})") - endif (NOT _RESULT EQUAL 0) - - # Ensure the log files to have different modification timestamps such that - # exactly one log file remains at the end. Otherwise all log files will be - # retained. - execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 1) -endforeach (iter) - -file (GLOB LOG_FILES ${TEST_DIR}/test_cleanup_*.barfoo) -list (LENGTH LOG_FILES NUM_FILES) - -if (NOT NUM_FILES EQUAL 1) - message (SEND_ERROR "Expected 1 log file in build directory ${TEST_DIR} but found ${NUM_FILES}") -endif (NOT NUM_FILES EQUAL 1) diff --git a/third_party/glog/cmake/RunCleanerTest3.cmake b/third_party/glog/cmake/RunCleanerTest3.cmake deleted file mode 100644 index e8105d1..0000000 --- a/third_party/glog/cmake/RunCleanerTest3.cmake +++ /dev/null @@ -1,28 +0,0 @@ -set (RUNS 3) - -# Create the subdirectory required by this unit test. -file (MAKE_DIRECTORY ${TEST_DIR}/${TEST_SUBDIR}) - -foreach (iter RANGE 1 ${RUNS}) - execute_process (COMMAND ${LOGCLEANUP} -log_dir=${TEST_DIR} - RESULT_VARIABLE _RESULT) - - if (NOT _RESULT EQUAL 0) - message (FATAL_ERROR "Failed to run logcleanup_unittest (error: ${_RESULT})") - endif (NOT _RESULT EQUAL 0) - - # Ensure the log files to have different modification timestamps such that - # exactly one log file remains at the end. Otherwise all log files will be - # retained. - execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 2) -endforeach (iter) - -file (GLOB LOG_FILES ${TEST_DIR}/${TEST_SUBDIR}/test_cleanup_*.relativefoo) -list (LENGTH LOG_FILES NUM_FILES) - -if (NOT NUM_FILES EQUAL 1) - message (SEND_ERROR "Expected 1 log file in build directory ${TEST_DIR}${TEST_SUBDIR} but found ${NUM_FILES}") -endif (NOT NUM_FILES EQUAL 1) - -# Remove the subdirectory required by this unit test. -file (REMOVE_RECURSE ${TEST_DIR}/${TEST_SUBDIR}) diff --git a/third_party/glog/cmake/TestInitPackageConfig.cmake b/third_party/glog/cmake/TestInitPackageConfig.cmake deleted file mode 100644 index 01d3a40..0000000 --- a/third_party/glog/cmake/TestInitPackageConfig.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# Create the build directory -execute_process ( - COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_BINARY_DIR} - RESULT_VARIABLE _DIRECTORY_CREATED_SUCCEEDED -) - -if (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0) - message (FATAL_ERROR "Failed to create build directory") -endif (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0) - -file (WRITE ${INITIAL_CACHE} "${CACHEVARS}") diff --git a/third_party/glog/cmake/TestPackageConfig.cmake b/third_party/glog/cmake/TestPackageConfig.cmake deleted file mode 100644 index 97244ab..0000000 --- a/third_party/glog/cmake/TestPackageConfig.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# Create the build directory -execute_process ( - COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_BINARY_DIR} - RESULT_VARIABLE _DIRECTORY_CREATED_SUCCEEDED -) - -if (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0) - message (FATAL_ERROR "Failed to create build directory") -endif (NOT _DIRECTORY_CREATED_SUCCEEDED EQUAL 0) - -if (GENERATOR_TOOLSET) - list (APPEND _ADDITIONAL_ARGS -T ${GENERATOR_TOOLSET}) -endif (GENERATOR_TOOLSET) - -if (GENERATOR_PLATFORM) - list (APPEND _ADDITIONAL_ARGS -A ${GENERATOR_PLATFORM}) -endif (GENERATOR_PLATFORM) - -# Run CMake -execute_process ( - # Capture the PATH environment variable content set during project generation - # stage. This is required because later during the build stage the PATH is - # modified again (e.g., for MinGW AppVeyor CI builds) by adding back the - # directory containing git.exe. Incidently, the Git installation directory - # also contains sh.exe which causes MinGW Makefile generation to fail. - COMMAND ${CMAKE_COMMAND} -E env PATH=${PATH} - ${CMAKE_COMMAND} -C ${INITIAL_CACHE} - -G ${GENERATOR} - ${_ADDITIONAL_ARGS} - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON - -DCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY=ON - -DCMAKE_PREFIX_PATH=${PACKAGE_DIR} - ${SOURCE_DIR} - WORKING_DIRECTORY ${TEST_BINARY_DIR} - RESULT_VARIABLE _GENERATE_SUCCEEDED -) - -if (NOT _GENERATE_SUCCEEDED EQUAL 0) - message (FATAL_ERROR "Failed to generate project files using CMake") -endif (NOT _GENERATE_SUCCEEDED EQUAL 0) diff --git a/third_party/glog/glog-config.cmake.in b/third_party/glog/glog-config.cmake.in deleted file mode 100644 index 5c5c9c0..0000000 --- a/third_party/glog/glog-config.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -if (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@) - message (FATAL_ERROR "CMake >= @glog_CMake_VERSION@ required") -endif (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@) - -@PACKAGE_INIT@ - -include (CMakeFindDependencyMacro) -include (${CMAKE_CURRENT_LIST_DIR}/glog-modules.cmake) - -@gflags_DEPENDENCY@ -@Unwind_DEPENDENCY@ - -include (${CMAKE_CURRENT_LIST_DIR}/glog-targets.cmake) diff --git a/third_party/glog/glog-modules.cmake.in b/third_party/glog/glog-modules.cmake.in deleted file mode 100644 index 71c5160..0000000 --- a/third_party/glog/glog-modules.cmake.in +++ /dev/null @@ -1,18 +0,0 @@ -cmake_policy (PUSH) -cmake_policy (SET CMP0057 NEW) - -if (CMAKE_VERSION VERSION_LESS 3.3) - message (FATAL_ERROR "glog-modules.cmake requires the consumer " - "to use CMake 3.3 (or newer)") -endif (CMAKE_VERSION VERSION_LESS 3.3) - -set (glog_MODULE_PATH "@glog_FULL_CMake_DATADIR@") -list (APPEND CMAKE_MODULE_PATH ${glog_MODULE_PATH}) - -if (NOT glog_MODULE_PATH IN_LIST CMAKE_MODULE_PATH) - message (FATAL_ERROR "Cannot add '${glog_MODULE_PATH}' to " - "CMAKE_MODULE_PATH. This will cause glog-config.cmake to fail at " - "locating required find modules. Make sure CMAKE_MODULE_PATH is not a cache variable.") -endif (NOT glog_MODULE_PATH IN_LIST CMAKE_MODULE_PATH) - -cmake_policy (POP) diff --git a/third_party/glog/libglog.pc.in b/third_party/glog/libglog.pc.in deleted file mode 100644 index 2303e2e..0000000 --- a/third_party/glog/libglog.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libglog -Description: Google Log (glog) C++ logging framework -Version: @VERSION@ -Libs: -L${libdir} -lglog -Libs.private: @glog_libraries_options_for_static_linking@ -Cflags: -I${includedir} diff --git a/third_party/glog/src/base/commandlineflags.h b/third_party/glog/src/base/commandlineflags.h deleted file mode 100644 index bcb12de..0000000 --- a/third_party/glog/src/base/commandlineflags.h +++ /dev/null @@ -1,147 +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 // for getenv -#include // for memchr -#include - -#ifdef HAVE_LIB_GFLAGS - -#include - -#else - -#include - -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GLOG_EXPORT type FLAGS_##name; \ - } \ - using fL##shorttype::FLAGS_##name -#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \ - namespace fL##shorttype { \ - GLOG_EXPORT 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) - -// uint32 specialization -#ifndef DECLARE_uint32 -#define DECLARE_uint32(name) \ - DECLARE_VARIABLE(GOOGLE_NAMESPACE::uint32, U, name, uint32) -#endif // DECLARE_uint64 -#define DEFINE_uint32(name, value, meaning) \ - DEFINE_VARIABLE(GOOGLE_NAMESPACE::uint32, U, name, value, meaning, uint32) - -// 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 GLOG_EXPORT std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#define DEFINE_string(name, value, meaning) \ - namespace fLS { \ - std::string FLAGS_##name##_buf(value); \ - GLOG_EXPORT 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_uint32(name, value, meaning) \ - DEFINE_uint32(name, EnvToUInt("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)) - -#define EnvToUInt(envname, dflt) \ - (!getenv(envname) ? (dflt) : strtoul(getenv(envname), NULL, 10)) - -#endif // BASE_COMMANDLINEFLAGS_H__ diff --git a/third_party/glog/src/base/googleinit.h b/third_party/glog/src/base/googleinit.h deleted file mode 100644 index 5a8b515..0000000 --- a/third_party/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/glog/src/base/mutex.h b/third_party/glog/src/base/mutex.h deleted file mode 100644 index e82c597..0000000 --- a/third_party/glog/src/base/mutex.h +++ /dev/null @@ -1,333 +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(__CYGWIN__) -# 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__ -# ifndef _XOPEN_SOURCE // Some other header might have already set it for us. -# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls -# endif -# 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(__CYGWIN__) - -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/glog/src/cleanup_immediately_unittest.cc b/third_party/glog/src/cleanup_immediately_unittest.cc deleted file mode 100644 index 89d008e..0000000 --- a/third_party/glog/src/cleanup_immediately_unittest.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2021, 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 -#include - -#include "base/commandlineflags.h" -#include "googletest.h" - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -#ifdef HAVE_LIB_GMOCK -#include - -#include "mock-log.h" -// Introduce several symbols from gmock. -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using testing::_; -using testing::AllOf; -using testing::AnyNumber; -using testing::HasSubstr; -using testing::InitGoogleMock; -using testing::StrictMock; -using testing::StrNe; -#endif - -using namespace GOOGLE_NAMESPACE; - -TEST(CleanImmediately, logging) { - google::SetLogFilenameExtension(".foobar"); - google::EnableLogCleaner(0); - - for (unsigned i = 0; i < 1000; ++i) { - LOG(INFO) << "cleanup test"; - } - - google::DisableLogCleaner(); -} - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; - FLAGS_timestamp_in_logfile_name = true; -#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(); - const string early_stderr = GetCapturedTestStderr(); - - EXPECT_FALSE(IsGoogleLoggingInitialized()); - - InitGoogleLogging(argv[0]); - - EXPECT_TRUE(IsGoogleLoggingInitialized()); - - 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); -} diff --git a/third_party/glog/src/cleanup_with_absolute_prefix_unittest.cc b/third_party/glog/src/cleanup_with_absolute_prefix_unittest.cc deleted file mode 100644 index d4bb47e..0000000 --- a/third_party/glog/src/cleanup_with_absolute_prefix_unittest.cc +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2021, 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 -#include - -#include "base/commandlineflags.h" -#include "googletest.h" - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -#ifdef HAVE_LIB_GMOCK -#include - -#include "mock-log.h" -// Introduce several symbols from gmock. -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using testing::_; -using testing::AllOf; -using testing::AnyNumber; -using testing::HasSubstr; -using testing::InitGoogleMock; -using testing::StrictMock; -using testing::StrNe; -#endif - -using namespace GOOGLE_NAMESPACE; - -TEST(CleanImmediatelyWithAbsolutePrefix, logging) { - google::EnableLogCleaner(0); - google::SetLogFilenameExtension(".barfoo"); - google::SetLogDestination(GLOG_INFO, "test_cleanup_"); - - for (unsigned i = 0; i < 1000; ++i) { - LOG(INFO) << "cleanup test"; - } - - for (unsigned i = 0; i < 10; ++i) { - LOG(ERROR) << "cleanup test"; - } - - google::DisableLogCleaner(); -} - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; - FLAGS_timestamp_in_logfile_name = true; -#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(); - const string early_stderr = GetCapturedTestStderr(); - - EXPECT_FALSE(IsGoogleLoggingInitialized()); - - InitGoogleLogging(argv[0]); - - EXPECT_TRUE(IsGoogleLoggingInitialized()); - - 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); -} diff --git a/third_party/glog/src/cleanup_with_relative_prefix_unittest.cc b/third_party/glog/src/cleanup_with_relative_prefix_unittest.cc deleted file mode 100644 index 330f465..0000000 --- a/third_party/glog/src/cleanup_with_relative_prefix_unittest.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2021, 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 -#include - -#include "base/commandlineflags.h" -#include "googletest.h" - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -#ifdef HAVE_LIB_GMOCK -#include - -#include "mock-log.h" -// Introduce several symbols from gmock. -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using testing::_; -using testing::AllOf; -using testing::AnyNumber; -using testing::HasSubstr; -using testing::InitGoogleMock; -using testing::StrictMock; -using testing::StrNe; -#endif - -using namespace GOOGLE_NAMESPACE; - -TEST(CleanImmediatelyWithRelativePrefix, logging) { - google::EnableLogCleaner(0); - google::SetLogFilenameExtension(".relativefoo"); - google::SetLogDestination(GLOG_INFO, "test_subdir/test_cleanup_"); - - for (unsigned i = 0; i < 1000; ++i) { - LOG(INFO) << "cleanup test"; - } - - google::DisableLogCleaner(); -} - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; - FLAGS_timestamp_in_logfile_name = true; -#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(); - const string early_stderr = GetCapturedTestStderr(); - - EXPECT_FALSE(IsGoogleLoggingInitialized()); - - InitGoogleLogging(argv[0]); - - EXPECT_TRUE(IsGoogleLoggingInitialized()); - - 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); -} diff --git a/third_party/glog/src/config.h.cmake.in b/third_party/glog/src/config.h.cmake.in deleted file mode 100644 index b225b7e..0000000 --- a/third_party/glog/src/config.h.cmake.in +++ /dev/null @@ -1,231 +0,0 @@ -#ifndef GLOG_CONFIG_H -#define GLOG_CONFIG_H - -/* define if glog doesn't use RTTI */ -#cmakedefine DISABLE_RTTI - -/* Namespace for Google classes */ -#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE} - -/* Define if you have the `dladdr' function */ -#cmakedefine HAVE_DLADDR - -/* Define if you have the `snprintf' function */ -#cmakedefine HAVE_SNPRINTF - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_EXECINFO_H - -/* Define if you have the `fcntl' function */ -#cmakedefine HAVE_FCNTL - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GLOB_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#cmakedefine HAVE_LIBPTHREAD - -/* define if you have google gflags library */ -#cmakedefine HAVE_LIB_GFLAGS - -/* define if you have google gmock library */ -#cmakedefine HAVE_LIB_GMOCK - -/* define if you have google gtest library */ -#cmakedefine HAVE_LIB_GTEST - -/* define if you have dbghelp library */ -#cmakedefine HAVE_DBGHELP - -/* define if you have libunwind */ -#cmakedefine HAVE_LIB_UNWIND - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H - -/* define to disable multithreading support. */ -#cmakedefine NO_THREADS - -/* define if the compiler implements namespaces */ -#cmakedefine HAVE_NAMESPACES - -/* Define if you have the 'pread' function */ -#cmakedefine HAVE_PREAD - -/* Define if you have POSIX threads libraries and header files. */ -#cmakedefine HAVE_PTHREAD - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PWD_H - -/* Define if you have the 'pwrite' function */ -#cmakedefine HAVE_PWRITE - -/* define if the compiler implements pthread_rwlock_* */ -#cmakedefine HAVE_RWLOCK - -/* Define if you have the 'sigaction' function */ -#cmakedefine HAVE_SIGACTION - -/* Define if you have the `sigaltstack' function */ -#cmakedefine HAVE_SIGALTSTACK - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYSLOG_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTSNAME_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_WAIT_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} - -/* Define if you have the header file. */ -#cmakedefine HAVE_UNWIND_H - -/* Define if you linking to _Unwind_Backtrace is possible. */ -#cmakedefine HAVE__UNWIND_BACKTRACE - -/* define if the compiler supports using expression for operator */ -#cmakedefine HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#cmakedefine HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#cmakedefine HAVE___BUILTIN_EXPECT ${HAVE___BUILTIN_EXPECT} - -/* define if your compiler has __sync_val_compare_and_swap */ -#cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* define if symbolize support is available */ -#cmakedefine HAVE_SYMBOLIZE - -/* define if localtime_r is available in time.h */ -#cmakedefine HAVE_LOCALTIME_R - -/* define if gmtime_r is available in time.h */ -#cmakedefine HAVE_GMTIME_R - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#cmakedefine LT_OBJDIR - -/* Name of package */ -#cmakedefine PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#cmakedefine PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#cmakedefine PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#cmakedefine PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#cmakedefine PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#cmakedefine PACKAGE_URL - -/* Define to the version of this package. */ -#cmakedefine PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#cmakedefine PC_FROM_UCONTEXT - -/* define if we should print file offsets in traces instead of symbolizing. */ -#cmakedefine PRINT_UNSYMBOLIZED_STACK_TRACES - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#cmakedefine PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P} - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#cmakedefine STL_NAMESPACE ${STL_NAMESPACE} - -/* location of source code */ -#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR} - -/* Define to necessary thread-local storage attribute. */ -#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE} - -/* Check whether aligned_storage and alignof present */ -#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE} - -/* Check whether C++11 atomic is available */ -#cmakedefine HAVE_CXX11_ATOMIC ${HAVE_CXX11_ATOMIC} - -/* Check whether C++11 chrono is available */ -#cmakedefine HAVE_CXX11_CHRONO ${HAVE_CXX11_CHRONO} - -/* Check whether C++11 nullptr_t is available */ -#cmakedefine HAVE_CXX11_NULLPTR_T ${HAVE_CXX11_NULLPTR_T} - -/* Version number of package */ -#cmakedefine VERSION - -#ifdef GLOG_BAZEL_BUILD - -/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved: - * https://github.com/bazelbuild/bazel/issues/3979 */ -#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE { - -#define _END_GOOGLE_NAMESPACE_ } - -#else - -/* Stops putting the code inside the Google namespace */ -#cmakedefine _END_GOOGLE_NAMESPACE_ ${_END_GOOGLE_NAMESPACE_} - -/* Puts following code inside the Google namespace */ -#cmakedefine _START_GOOGLE_NAMESPACE_ ${_START_GOOGLE_NAMESPACE_} - -#endif - -/* Replacement for deprecated syscall(SYS_gettid) on macOS. */ -#cmakedefine HAVE_PTHREAD_THREADID_NP ${HAVE_PTHREAD_THREADID_NP} - -#endif // GLOG_CONFIG_H diff --git a/third_party/glog/src/demangle.cc b/third_party/glog/src/demangle.cc deleted file mode 100644 index 2ee9da0..0000000 --- a/third_party/glog/src/demangle.cc +++ /dev/null @@ -1,1364 +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://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling -// -// Note that we only have partial C++0x support yet. - -#include // for NULL - -#include "demangle.h" -#include "utilities.h" - -#if defined(GLOG_OS_WINDOWS) -#include -#endif - -_START_GOOGLE_NAMESPACE_ - -#if !defined(GLOG_OS_WINDOWS) -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, size_t 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 > - static_cast(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 ParseAbiTags(State *state); -static bool ParseAbiTag(State *state); -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) && Optional(ParseAbiTags(state))) || - (ParseLocalSourceName(state) && Optional(ParseAbiTags(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; -} - -// ::= [] -static bool ParseAbiTags(State *state) { - State copy = *state; - DisableAppend(state); - if (OneOrMore(ParseAbiTag, state)) { - RestoreAppend(state, copy.append); - return true; - } - *state = copy; - return false; -} - -// ::= B -static bool ParseAbiTag(State *state) { - return ParseOneCharToken(state, 'B') && ParseSourceName(state); -} - -// ::= 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 -// ::= J * E # argument pack -// ::= X E -static bool ParseTemplateArg(State *state) { - State copy = *state; - if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) && - 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; -} -#endif - -// The demangler entry point. -bool Demangle(const char *mangled, char *out, size_t out_size) { -#if defined(GLOG_OS_WINDOWS) -#if defined(HAVE_DBGHELP) - // When built with incremental linking, the Windows debugger - // library provides a more complicated `Symbol->Name` with the - // Incremental Linking Table offset, which looks like - // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects - // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the - // mangled symbol is guaranteed not to have parentheses, - // so we search for `(` and extract up to `)`. - // - // Since we may be in a signal handler here, we cannot use `std::string`. - char buffer[1024]; // Big enough for a sane symbol. - const char *lparen = strchr(mangled, '('); - if (lparen) { - // Extract the string `(?...)` - const char *rparen = strchr(lparen, ')'); - size_t length = static_cast(rparen - lparen) - 1; - strncpy(buffer, lparen + 1, length); - buffer[length] = '\0'; - mangled = buffer; - } // Else the symbol wasn't inside a set of parentheses - // We use the ANSI version to ensure the string type is always `char *`. - return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE); -#else - (void)mangled; - (void)out; - (void)out_size; - return false; -#endif -#else - State state; - InitState(&state, mangled, out, out_size); - return ParseTopLevelMangledName(&state) && !state.overflowed; -#endif -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/demangle.h b/third_party/glog/src/demangle.h deleted file mode 100644 index f347b98..0000000 --- a/third_party/glog/src/demangle.h +++ /dev/null @@ -1,85 +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" -#include - -_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 GLOG_EXPORT Demangle(const char *mangled, char *out, size_t out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_DEMANGLE_H_ diff --git a/third_party/glog/src/demangle_unittest.cc b/third_party/glog/src/demangle_unittest.cc deleted file mode 100644 index ddc90b0..0000000 --- a/third_party/glog/src/demangle_unittest.cc +++ /dev/null @@ -1,170 +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 -#include "demangle.h" -#include "googletest.h" -#include "config.h" - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -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; - } -} - -#if defined(GLOG_OS_WINDOWS) - -#if defined(HAVE_DBGHELP) && !defined(NDEBUG) -TEST(Demangle, Windows) { - EXPECT_STREQ( - "public: static void __cdecl Foo::func(int)", - DemangleIt("?func@Foo@@SAXH@Z")); - EXPECT_STREQ( - "public: static void __cdecl Foo::func(int)", - DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)")); - EXPECT_STREQ( - "int __cdecl foobarArray(int * const)", - DemangleIt("?foobarArray@@YAHQAH@Z")); -} -#endif - -#else - -// Test corner cases of bounary conditions. -TEST(Demangle, CornerCases) { - const size_t size = 10; - char tmp[size] = { 0 }; - const char *demangled = "foobar()"; - const char *mangled = "_Z6foobarv"; - EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp))); - // sizeof("foobar()") == size - 1 - EXPECT_STREQ(demangled, tmp); - EXPECT_TRUE(Demangle(mangled, tmp, size - 1)); - EXPECT_STREQ(demangled, tmp); - EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough. - EXPECT_FALSE(Demangle(mangled, tmp, 1)); - EXPECT_FALSE(Demangle(mangled, tmp, 0)); - EXPECT_FALSE(Demangle(mangled, 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())); - } -} - -#endif - -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/glog/src/demangle_unittest.sh b/third_party/glog/src/demangle_unittest.sh deleted file mode 100755 index 91deee2..0000000 --- a/third_party/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/glog/src/demangle_unittest.txt b/third_party/glog/src/demangle_unittest.txt deleted file mode 100644 index 07e28bc..0000000 --- a/third_party/glog/src/demangle_unittest.txt +++ /dev/null @@ -1,145 +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<< <> - -# ABI tags. -_Z1AB3barB3foo A -_ZN3fooL3barB5cxx11E foo::bar - -# 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%() - -# Template argument packs can start with I or J. -_Z3addIIiEEvDpT_ add<>() -_Z3addIJiEEvDpT_ add<>() diff --git a/third_party/glog/src/glog/log_severity.h b/third_party/glog/src/glog/log_severity.h deleted file mode 100644 index aa48f53..0000000 --- a/third_party/glog/src/glog/log_severity.h +++ /dev/null @@ -1,98 +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__ - -// The recommended semantics of the log levels are as follows: -// -// INFO: -// Use for state changes or other major events, or to aid debugging. -// WARNING: -// Use for undesired but relatively expected events, which may indicate a -// problem -// ERROR: -// Use for undesired and unexpected events that the program can recover from. -// All ERRORs should be actionable - it should be appropriate to file a bug -// whenever an ERROR occurs in production. -// FATAL: -// Use for undesired and unexpected events that the program cannot recover -// from. - -// 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 GLOG_EXPORT 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/glog/src/glog/logging.h.in b/third_party/glog/src/glog/logging.h.in deleted file mode 100644 index 95a573b..0000000 --- a/third_party/glog/src/glog/logging.h.in +++ /dev/null @@ -1,2002 +0,0 @@ -// Copyright (c) 2022, 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 GLOG_LOGGING_H -#define GLOG_LOGGING_H - -#if @ac_cv_cxx11_chrono@ && __cplusplus >= 201103L -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if @ac_cv_have_unistd_h@ -# include -#endif -#include - -#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 - -#include - -#if @ac_cv_have_glog_export@ -#include -#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 @ac_cv_have_stdint_h@ -#include // the normal place uint16_t is defined -#endif -#if @ac_cv_have_systypes_h@ -#include // the normal place u_int16_t is defined -#endif -#if @ac_cv_have_inttypes_h@ -#include // a third place for uint16_t or u_int16_t -#endif - -#if @ac_cv_have_libgflags@ -#include -#endif - -#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L -#include -#elif defined(GLOG_OS_WINDOWS) -#include -#endif - -@ac_google_start_namespace@ - -#if @ac_cv_have_uint16_t@ // the C99 format -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -#elif @ac_cv_have_u_int16_t@ // the BSD format -typedef int32_t int32; -typedef u_int32_t uint32; -typedef int64_t int64; -typedef u_int64_t uint64; -#elif @ac_cv_have___uint16@ // 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 - -typedef double WallTime; - -struct GLOG_EXPORT LogMessageTime { - LogMessageTime(); - LogMessageTime(std::tm t); - LogMessageTime(std::time_t timestamp, WallTime now); - - const time_t& timestamp() const { return timestamp_; } - const int& sec() const { return time_struct_.tm_sec; } - const int32_t& usec() const { return usecs_; } - const int&(min)() const { return time_struct_.tm_min; } - const int& hour() const { return time_struct_.tm_hour; } - const int& day() const { return time_struct_.tm_mday; } - const int& month() const { return time_struct_.tm_mon; } - const int& year() const { return time_struct_.tm_year; } - const int& dayOfWeek() const { return time_struct_.tm_wday; } - const int& dayInYear() const { return time_struct_.tm_yday; } - const int& dst() const { return time_struct_.tm_isdst; } - const long int& gmtoff() const { return gmtoffset_; } - const std::tm& tm() const { return time_struct_; } - - private: - void init(const std::tm& t, std::time_t timestamp, WallTime now); - std::tm time_struct_; // Time of creation of LogMessage - time_t timestamp_; // Time of creation of LogMessage in seconds - int32_t usecs_; // Time of creation of LogMessage - microseconds part - long int gmtoffset_; - - void CalcGmtOffset(); -}; - -#ifdef GLOG_CUSTOM_PREFIX_SUPPORT -struct LogMessageInfo { - explicit LogMessageInfo(const char* const severity_, - const char* const filename_, - const int& line_number_, - const int& thread_id_, - const LogMessageTime& time_): - severity(severity_), filename(filename_), line_number(line_number_), - thread_id(thread_id_), time(time_) - {} - - const char* const severity; - const char* const filename; - const int &line_number; - const int &thread_id; - const LogMessageTime& time; -}; - -typedef void(*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l, void* data); - -#endif - -@ac_google_end_namespace@ - - -// 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 @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_FALSE -#if @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_FALSE(x) x -#endif -#endif - -#ifndef GOOGLE_PREDICT_TRUE -#if @ac_cv_have___builtin_expect@ -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#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: -// -// Lyyyymmdd 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) -// yyyy The year -// 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. - -#pragma push_macro("DECLARE_VARIABLE") -#pragma push_macro("DECLARE_bool") -#pragma push_macro("DECLARE_string") -#pragma push_macro("DECLARE_int32") -#pragma push_macro("DECLARE_uint32") - -#ifdef DECLARE_VARIABLE -#undef DECLARE_VARIABLE -#endif - -#ifdef DECLARE_bool -#undef DECLARE_bool -#endif - -#ifdef DECLARE_string -#undef DECLARE_string -#endif - -#ifdef DECLARE_int32 -#undef DECLARE_int32 -#endif - -#ifdef DECLARE_uint32 -#undef DECLARE_uint32 -#endif - -#ifndef DECLARE_VARIABLE -#define DECLARE_VARIABLE(type, shorttype, name, tn) \ - namespace fL##shorttype { \ - extern GLOG_EXPORT 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(@ac_google_namespace@::int32, I, name, int32) - -#if !defined(DECLARE_uint32) -// uint32 specialization -#define DECLARE_uint32(name) \ - DECLARE_VARIABLE(@ac_google_namespace@::uint32, U, name, uint32) -#endif // !defined(DECLARE_uint32) && !(@ac_cv_have_libgflags@) - -// 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 GLOG_EXPORT std::string& FLAGS_##name; \ - } \ - using fLS::FLAGS_##name -#endif - -// Set whether appending a timestamp to the log file name -DECLARE_bool(timestamp_in_logfile_name); - -// Set whether log messages go to stdout instead of logfiles -DECLARE_bool(logtostdout); - -// Set color messages logged to stdout (if supported by terminal). -DECLARE_bool(colorlogtostdout); - -// 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); - -// Set whether the year should be included in the log prefix. -DECLARE_bool(log_year_in_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); - -// Set the log file mode. -DECLARE_int32(logfile_mode); - -// 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 - -DECLARE_string(vmodule); // also in vlog_is_on.cc - -// Sets the maximum log file size (in MB). -DECLARE_uint32(max_log_size); - -// Sets whether to avoid logging to the disk if the disk is full. -DECLARE_bool(stop_logging_if_full_disk); - -// Use UTC time for logging -DECLARE_bool(log_utc_time); - -// 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 @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, message) -#else -#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 1 -#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING) -#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, message) -#else -#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 2 -#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR) -#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, message) -#else -#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::NullStream() -#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::NullStream() -#endif - -#if GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::LogMessageFatal( \ - __FILE__, __LINE__) -#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, message) -#else -#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::NullStreamFatal() -#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::NullStreamFatal() -#endif - -#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) -#define DCHECK_IS_ON() 0 -#else -#define DCHECK_IS_ON() 1 -#endif - -// For DFATAL, we want to use LogMessage (as opposed to -// LogMessageFatal), to be consistent with the original behavior. -#if !DCHECK_IS_ON() -#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR -#elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL) -#else -#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::NullStreamFatal() -#endif - -#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_INFO(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ - &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) -#define GOOGLE_LOG_DFATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) -#define SYSLOG_DFATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \ - &@ac_google_namespace@::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) { \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, 0, \ - &@ac_google_namespace@::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() - -@ac_google_start_namespace@ - -// They need the definitions of integer types. -#include -#include - -// Initialize google's logging library. You will see the program name -// specified by argv0 in log outputs. -GLOG_EXPORT void InitGoogleLogging(const char* argv0); - -#ifdef GLOG_CUSTOM_PREFIX_SUPPORT -GLOG_EXPORT void InitGoogleLogging(const char* argv0, - CustomPrefixCallback prefix_callback, - void* prefix_callback_data = NULL); -#endif - -// Check if google's logging library has been initialized. -GLOG_EXPORT bool IsGoogleLoggingInitialized(); - -// Shutdown google's logging library. -GLOG_EXPORT void ShutdownGoogleLogging(); - -#if defined(__GNUC__) -typedef void (*logging_fail_func_t)() __attribute__((noreturn)); -#else -typedef void (*logging_fail_func_t)(); -#endif - -// Install a function which will be called after LOG(FATAL). -GLOG_EXPORT void InstallFailureFunction(logging_fail_func_t fail_func); - -// Enable/Disable old log cleaner. -GLOG_EXPORT void EnableLogCleaner(unsigned int overdue_days); -GLOG_EXPORT void DisableLogCleaner(); -GLOG_EXPORT void SetApplicationFingerprint(const std::string& fingerprint); - -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) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, \ - @ac_google_namespace@::GLOG_ ## severity, \ - static_cast<@ac_google_namespace@::LogSink*>(sink), true).stream() -#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, \ - @ac_google_namespace@::GLOG_ ## severity, \ - static_cast<@ac_google_namespace@::LogSink*>(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) \ - static_cast(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) -#define SYSLOG_IF(severity, condition) \ - static_cast(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::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 DCHECK_IS_ON(), 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; } -#if __cplusplus >= 201103L -inline long long GetReferenceableValue(long long t) { return t; } -inline unsigned long long GetReferenceableValue(unsigned long long t) { - return t; -} -#endif - -// This is a dummy class to define the following operator. -struct DummyClassToDefineOperator {}; - -@ac_google_end_namespace@ - -// 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; -} - -@ac_google_start_namespace@ - -// 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 <> GLOG_EXPORT -void MakeCheckOpValueString(std::ostream* os, const char& v); -template <> GLOG_EXPORT -void MakeCheckOpValueString(std::ostream* os, const signed char& v); -template <> GLOG_EXPORT -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); - -// This is required because nullptr is only present in c++ 11 and later. -#if @ac_cv_cxx11_nullptr_t@ && __cplusplus >= 201103L -// Provide printable value for nullptr_t -template <> GLOG_EXPORT -void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v); -#endif - -// Build the error message string. Specify no inlining for code size. -template -std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) - @ac_cv___attribute___noinline@; - -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 GLOG_EXPORT 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 DCHECK_IS_ON() -// 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 (@ac_google_namespace@::_Check_string* _result = \ - @ac_google_namespace@::Check##name##Impl( \ - @ac_google_namespace@::GetReferenceableValue(val1), \ - @ac_google_namespace@::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, \ - @ac_google_namespace@::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 (@ac_google_namespace@::CheckOpString _result = \ - @ac_google_namespace@::Check##name##Impl( \ - @ac_google_namespace@::GetReferenceableValue(val1), \ - @ac_google_namespace@::GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ - log(__FILE__, __LINE__, _result).stream() -#endif // STATIC_ANALYSIS, DCHECK_IS_ON() - -#if GOOGLE_STRIP_LOG <= 3 -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::LogMessageFatal) -#else -#define CHECK_OP(name, op, val1, val2) \ - CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::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) \ - @ac_google_namespace@::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) \ - GLOG_EXPORT 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 (@ac_google_namespace@::CheckOpString _result = \ - @ac_google_namespace@::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) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, counter, \ - &@ac_google_namespace@::LogMessage::SendToLog) - -#define PLOG_IF(severity, condition) \ - static_cast(0), \ - !(condition) ? (void) 0 : @ac_google_namespace@::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__) - -#if @ac_cv_cxx11_constexpr@ && __cplusplus >= 201103L -#define GLOG_CONSTEXPR constexpr -#else -#define GLOG_CONSTEXPR const -#endif - -#define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__) -#define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__) -#define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__) -#define LOG_CURRENT_TIME LOG_EVERY_N_VARNAME(currentTime_, __LINE__) -#define LOG_PREVIOUS_TIME LOG_EVERY_N_VARNAME(previousTime_, __LINE__) - -#if defined(__has_feature) -# if __has_feature(thread_sanitizer) -# define GLOG_SANITIZE_THREAD 1 -# endif -#endif - -#if !defined(GLOG_SANITIZE_THREAD) && defined(__SANITIZE_THREAD__) && __SANITIZE_THREAD__ -# define GLOG_SANITIZE_THREAD 1 -#endif - -#if defined(GLOG_SANITIZE_THREAD) -#define GLOG_IFDEF_THREAD_SANITIZER(X) X -#else -#define GLOG_IFDEF_THREAD_SANITIZER(X) -#endif - -#if defined(GLOG_SANITIZE_THREAD) -} // namespace google - -// We need to identify the static variables as "benign" races -// to avoid noisy reports from TSAN. -extern "C" void AnnotateBenignRaceSized( - const char *file, - int line, - const volatile void *mem, - size_t size, - const char *description); - -namespace google { -#endif - -#if __cplusplus >= 201103L && @ac_cv_cxx11_chrono@ && @ac_cv_cxx11_atomic@ // Have and -#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ - GLOG_CONSTEXPR std::chrono::nanoseconds LOG_TIME_PERIOD = std::chrono::duration_cast(std::chrono::duration(seconds)); \ - static std::atomic<@ac_google_namespace@::int64> LOG_PREVIOUS_TIME_RAW; \ - GLOG_IFDEF_THREAD_SANITIZER( \ - AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, sizeof(@ac_google_namespace@::int64), "")); \ - GLOG_IFDEF_THREAD_SANITIZER( \ - AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, sizeof(@ac_google_namespace@::int64), "")); \ - const auto LOG_CURRENT_TIME = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); \ - const auto LOG_PREVIOUS_TIME = LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \ - const auto LOG_TIME_DELTA = LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \ - LOG_PREVIOUS_TIME_RAW.store(std::chrono::duration_cast(LOG_CURRENT_TIME).count(), std::memory_order_relaxed); \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream() -#elif defined(GLOG_OS_WINDOWS) -#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ - GLOG_CONSTEXPR LONGLONG LOG_TIME_PERIOD = (seconds) * LONGLONG(1000000000); \ - static LARGE_INTEGER LOG_PREVIOUS_TIME; \ - LONGLONG LOG_TIME_DELTA; \ - { \ - LARGE_INTEGER currTime; \ - LARGE_INTEGER freq; \ - QueryPerformanceCounter(&currTime); \ - QueryPerformanceFrequency(&freq); \ - InterlockedCompareExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart, 0); \ - LOG_TIME_DELTA = (currTime.QuadPart - LOG_PREVIOUS_TIME.QuadPart) * LONGLONG(1000000000) / freq.QuadPart; \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) InterlockedExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart); \ - } \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream() -#else -#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ - GLOG_CONSTEXPR @ac_google_namespace@::int64 LOG_TIME_PERIOD(seconds * 1000000000); \ - static @ac_google_namespace@::int64 LOG_PREVIOUS_TIME; \ - @ac_google_namespace@::int64 LOG_TIME_DELTA = 0; \ - { \ - timespec currentTime = {}; \ - clock_gettime(CLOCK_MONOTONIC, ¤tTime); \ - LOG_TIME_DELTA = (currentTime.tv_sec * 1000000000 + currentTime.tv_nsec) - LOG_PREVIOUS_TIME; \ - } \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) __sync_add_and_fetch(&LOG_PREVIOUS_TIME, LOG_TIME_DELTA); \ - if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream() -#endif - -#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ - ++LOG_OCCURRENCES; \ - if ((condition) && \ - ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES_MOD_N, sizeof(int), "")); \ - ++LOG_OCCURRENCES; \ - if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static std::atomic LOG_OCCURRENCES(0); \ - GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ - if (LOG_OCCURRENCES <= n) \ - ++LOG_OCCURRENCES; \ - if (LOG_OCCURRENCES <= n) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#elif defined(GLOG_OS_WINDOWS) - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static volatile unsigned LOG_OCCURRENCES = 0; \ - static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \ - InterlockedIncrement(&LOG_OCCURRENCES); \ - if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \ - InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ - static volatile unsigned LOG_OCCURRENCES = 0; \ - static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \ - InterlockedIncrement(&LOG_OCCURRENCES); \ - if ((condition) && \ - ((InterlockedIncrement(&LOG_OCCURRENCES_MOD_N), \ - (LOG_OCCURRENCES_MOD_N > n && InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n))), \ - LOG_OCCURRENCES_MOD_N == 1)) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ - static volatile unsigned LOG_OCCURRENCES = 0; \ - static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \ - InterlockedIncrement(&LOG_OCCURRENCES); \ - if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \ - InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ - static volatile unsigned LOG_OCCURRENCES = 0; \ - if (LOG_OCCURRENCES <= n) \ - InterlockedIncrement(&LOG_OCCURRENCES); \ - if (LOG_OCCURRENCES <= n) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() - -#else - -#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ - static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ - __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ - if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \ - __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::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; \ - __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ - if ((condition) && \ - (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) || true) && \ - ((LOG_OCCURRENCES_MOD_N >= n && __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n)) || true) && \ - LOG_OCCURRENCES_MOD_N == (1 % n)) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::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; \ - __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ - if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \ - __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \ - if (LOG_OCCURRENCES_MOD_N == 1) \ - @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::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) \ - __sync_add_and_fetch(&LOG_OCCURRENCES, 1); \ - if (LOG_OCCURRENCES <= n) \ - @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ - &what_to_do).stream() -#endif - -namespace glog_internal_namespace_ { -template -struct CompileAssert { -}; -struct CrashReason; - -// Returns true if FailureSignalHandler is installed. -// Needs to be exported since it's used by the signalhandler_unittest. -GLOG_EXPORT bool IsFailureSignalHandlerInstalled(); -} // namespace glog_internal_namespace_ - -#define LOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define LOG_EVERY_T(severity, T) SOME_KIND_OF_LOG_EVERY_T(severity, (T)) - -#define SYSLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToSyslogAndLog) - -#define PLOG_EVERY_N(severity, n) \ - SOME_KIND_OF_PLOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define LOG_FIRST_N(severity, n) \ - SOME_KIND_OF_LOG_FIRST_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) - -#define LOG_IF_EVERY_N(severity, condition, n) \ - SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), @ac_google_namespace@::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 - -#if DCHECK_IS_ON() - -#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. executed if DCHECK_IS_ON(). -#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 // !DCHECK_IS_ON() - -#define DLOG(severity) \ - static_cast(0), \ - true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DVLOG(verboselevel) \ - static_cast(0), \ - (true || !VLOG_IS_ON(verboselevel)) ? \ - (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(INFO) - -#define DLOG_IF(severity, condition) \ - static_cast(0), \ - (true || !(condition)) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DLOG_EVERY_N(severity, n) \ - static_cast(0), \ - true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DLOG_IF_EVERY_N(severity, condition, n) \ - static_cast(0), \ - (true || !(condition))? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) - -#define DLOG_ASSERT(condition) \ - static_cast(0), \ - 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 // DCHECK_IS_ON() - -// 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 GLOG_EXPORT LogStreamBuf : public std::streambuf { - public: - // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\0'. - LogStreamBuf(char *buf, int len) { - setp(buf, buf + len - 2); - } - - // This effectively ignores overflow. - int_type overflow(int_type ch) { - return ch; - } - - // Legacy public ostrstream method. - size_t pcount() const { return static_cast(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 GLOG_EXPORT 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. -GLOG_MSVC_PUSH_DISABLE_WARNING(4275) - class GLOG_EXPORT LogStream : public std::ostream { -GLOG_MSVC_POP_WARNING() - public: - LogStream(char *buf, int len, int64 ctr) - : std::ostream(NULL), - streambuf_(buf, len), - ctr_(ctr), - self_(this) { - rdbuf(&streambuf_); - } - - int64 ctr() const { return ctr_; } - void set_ctr(int64 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: - LogStream(const LogStream&); - LogStream& operator=(const LogStream&); - base_logging::LogStreamBuf streambuf_; - int64 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, int64 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 @ac_cv___attribute___noreturn@ 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); - - const LogMessageTime& getLogMessageTime() const; - - 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_; - LogMessageTime logmsgtime_; - - 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 GLOG_EXPORT LogMessageFatal : public LogMessage { - public: - LogMessageFatal(const char* file, int line); - LogMessageFatal(const char* file, int line, const CheckOpString& result); - @ac_cv___attribute___noreturn@ ~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) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream() - -// Check if it's compiled in C++11 mode. -// -// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least -// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 -// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is -// defined according to the language version in effect thereafter. -// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite -// reasonably good C++11 support, so we set LANG_CXX for it and -// newer versions (_MSC_VER >= 1900). -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined(__UCLIBCXX_MAJOR__) -// Helper for CHECK_NOTNULL(). -// -// In C++11, all cases can be handled by a single function. Since the value -// category of the argument is preserved (also for rvalue references), -// member initializer lists like the one below will compile correctly: -// -// Foo() -// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {} -template -T CheckNotNull(const char* file, int line, const char* names, T&& t) { - if (t == nullptr) { - LogMessageFatal(file, line, new std::string(names)); - } - return std::forward(t); -} - -#else - -// 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; -} -#endif - -// 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. -GLOG_EXPORT std::ostream& operator<<(std::ostream &os, - const PRIVATE_Counter&); - - -// Derived class for PLOG*() above. -class GLOG_EXPORT ErrnoLogMessage : public LogMessage { - public: - ErrnoLogMessage(const char* file, int line, LogSeverity severity, int64 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 GLOG_EXPORT 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. -GLOG_EXPORT 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. -GLOG_EXPORT 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. -// -GLOG_EXPORT 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. -// -GLOG_EXPORT 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 GLOG_EXPORT 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 LogMessageTime& logmsgtime, const char* message, - size_t message_len); - // Provide an overload for compatibility purposes - GLOG_DEPRECATED - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const std::tm* t, - const char* message, size_t message_len); - - // 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 LogMessageTime &logmsgtime, - const char* message, size_t message_len); -}; - -// Add or remove a LogSink as a consumer of logging data. Thread-safe. -GLOG_EXPORT void AddLogSink(LogSink *destination); -GLOG_EXPORT 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. -// -GLOG_EXPORT 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. -// -GLOG_EXPORT void SetStderrLogging(LogSeverity min_severity); - -// -// Make it so that all log messages go only to stderr. Thread-safe. -// -GLOG_EXPORT 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. -// -GLOG_EXPORT void SetEmailLogging(LogSeverity min_severity, - const char* addresses); - -// A simple function that sends email. dest is a commma-separated -// list of addressess. Thread-safe. -GLOG_EXPORT bool SendEmail(const char *dest, - const char *subject, const char *body); - -GLOG_EXPORT 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 GetLoggingDirectories(). -// Thread-safe. -GLOG_EXPORT 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. -GLOG_EXPORT 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/* -GLOG_EXPORT void TruncateLogFile(const char* path, uint64 limit, uint64 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. -GLOG_EXPORT void TruncateStdoutStderr(); - -// Return the string representation of the provided LogSeverity level. -// Thread-safe. -GLOG_EXPORT 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 GLOG_EXPORT 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, - size_t 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 GLOG_EXPORT 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 GLOG_EXPORT 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. -// DEPRECATED: Use StrError(int) instead. -GLOG_EXPORT int posix_strerror_r(int err, char *buf, size_t len); - -// A thread-safe replacement for strerror(). Returns a string describing the -// given POSIX error code. -GLOG_EXPORT std::string StrError(int err); - -// A class for which we define operator<<, which does nothing. -class GLOG_EXPORT 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 GLOG_EXPORT NullStreamFatal : public NullStream { - public: - NullStreamFatal() { } - NullStreamFatal(const char* file, int line, const CheckOpString& result) : - NullStream(file, line, result) { } -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4722) -#endif // _MSC_VER - @ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(EXIT_FAILURE); } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif // _MSC_VER -}; - -// 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. -GLOG_EXPORT 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'. -GLOG_EXPORT void InstallFailureWriter( - void (*writer)(const char* data, size_t size)); - -@ac_google_end_namespace@ - -#pragma pop_macro("DECLARE_VARIABLE") -#pragma pop_macro("DECLARE_bool") -#pragma pop_macro("DECLARE_string") -#pragma pop_macro("DECLARE_int32") -#pragma pop_macro("DECLARE_uint32") - -#endif // GLOG_LOGGING_H diff --git a/third_party/glog/src/glog/platform.h b/third_party/glog/src/glog/platform.h deleted file mode 100644 index e614411..0000000 --- a/third_party/glog/src/glog/platform.h +++ /dev/null @@ -1,58 +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 -// -// Detect supported platforms. - -#ifndef GLOG_PLATFORM_H -#define GLOG_PLATFORM_H - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -#define GLOG_OS_WINDOWS -#elif defined(__CYGWIN__) || defined(__CYGWIN32__) -#define GLOG_OS_CYGWIN -#elif defined(linux) || defined(__linux) || defined(__linux__) -#ifndef GLOG_OS_LINUX -#define GLOG_OS_LINUX -#endif -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) -#define GLOG_OS_MACOSX -#elif defined(__FreeBSD__) -#define GLOG_OS_FREEBSD -#elif defined(__NetBSD__) -#define GLOG_OS_NETBSD -#elif defined(__OpenBSD__) -#define GLOG_OS_OPENBSD -#else -// TODO(hamaji): Add other platforms. -#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github. -#endif - -#endif // GLOG_PLATFORM_H diff --git a/third_party/glog/src/glog/raw_logging.h.in b/third_party/glog/src/glog/raw_logging.h.in deleted file mode 100644 index 66fec91..0000000 --- a/third_party/glog/src/glog/raw_logging.h.in +++ /dev/null @@ -1,179 +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 GLOG_RAW_LOGGING_H -#define GLOG_RAW_LOGGING_H - -#include - -@ac_google_start_namespace@ - -#include -#include -#include - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvariadic-macros" -#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: -// E20200821 211317 file.cc:123] RAW: Failed foo with 22: bad_file -// I20200821 211317 file.cc:142] RAW: status is 20 -#define RAW_LOG(severity, ...) \ - do { \ - switch (@ac_google_namespace@::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 !defined(STRIP_LOG) || 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 !defined(STRIP_LOG) || STRIP_LOG == 0 -#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_INFO, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG == 0 - -#if !defined(STRIP_LOG) || STRIP_LOG <= 1 -#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_WARNING, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 1 - -#if !defined(STRIP_LOG) || STRIP_LOG <= 2 -#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_ERROR, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__) -#endif // STRIP_LOG <= 2 - -#if !defined(STRIP_LOG) || STRIP_LOG <= 3 -#define RAW_LOG_FATAL(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_FATAL, \ - __FILE__, __LINE__, __VA_ARGS__) -#else -#define RAW_LOG_FATAL(...) \ - do { \ - @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } 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 - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -// 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. -GLOG_EXPORT void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) - @ac_cv___attribute___printf_4_5@; - -@ac_google_end_namespace@ - -#endif // GLOG_RAW_LOGGING_H diff --git a/third_party/glog/src/glog/stl_logging.h.in b/third_party/glog/src/glog/stl_logging.h.in deleted file mode 100644 index bdfdc8b..0000000 --- a/third_party/glog/src/glog/stl_logging.h.in +++ /dev/null @@ -1,220 +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); -// -// If you want to use this header file with hash maps or slist, you -// need to define macros before including this file: -// -// - GLOG_STL_LOGGING_FOR_UNORDERED - and -// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - -// - GLOG_STL_LOGGING_FOR_EXT_HASH - -// - GLOG_STL_LOGGING_FOR_EXT_SLIST - -// - -#ifndef UTIL_GTL_STL_LOGGING_INL_H_ -#define UTIL_GTL_STL_LOGGING_INL_H_ - -#if !@ac_cv_cxx_using_operator@ -# error We do not support stl_logging for this compiler -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L -# include -# include -#endif - -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# include -# include -#endif - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -# include -# include -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST -# 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); - -@ac_google_start_namespace@ - -template -void PrintSequence(std::ostream& out, Iter begin, Iter end); - -@ac_google_end_namespace@ - -#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ -template \ -inline std::ostream& operator<<(std::ostream& out, \ - const Sequence& seq) { \ - @ac_google_namespace@::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 GLOG_STL_LOGGING_FOR_EXT_SLIST -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) { \ - @ac_google_namespace@::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) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -OUTPUT_FOUR_ARG_CONTAINER(std::map) -OUTPUT_FOUR_ARG_CONTAINER(std::multimap) -#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set) -OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -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) { \ - @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \ - return out; \ -} - -#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map) -OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap) -#endif -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -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; -} - -@ac_google_start_namespace@ - -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 << " ..."; - } -} - -@ac_google_end_namespace@ - -// 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/glog/src/glog/vlog_is_on.h.in b/third_party/glog/src/glog/vlog_is_on.h.in deleted file mode 100644 index 7526fc3..0000000 --- a/third_party/glog/src/glog/vlog_is_on.h.in +++ /dev/null @@ -1,118 +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 - -#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 @ac_google_namespace@::SiteFlag vlocal__ = {NULL, NULL, 0, NULL}; \ - @ac_google_namespace@::int32 verbose_level__ = (verboselevel); \ - (vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \ - __FILE__, verbose_level__) : *vlocal__.level >= 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 GLOG_EXPORT int SetVLOGLevel(const char* module_pattern, int log_level); - -// Various declarations needed for VLOG_IS_ON above: ========================= - -struct SiteFlag { - @ac_google_namespace@::int32* level; - const char* base_name; - size_t base_len; - SiteFlag* next; -}; - -// 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 GLOG_EXPORT bool InitVLOG3__( - @ac_google_namespace@::SiteFlag* site_flag, - @ac_google_namespace@::int32* site_default, const char* fname, - @ac_google_namespace@::int32 verbose_level); - -#endif // BASE_VLOG_IS_ON_H_ diff --git a/third_party/glog/src/googletest.h b/third_party/glog/src/googletest.h deleted file mode 100644 index 5761361..0000000 --- a/third_party/glog/src/googletest.h +++ /dev/null @@ -1,672 +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" - -#if __cplusplus < 201103L && !defined(_MSC_VER) -#define GOOGLE_GLOG_THROW_BAD_ALLOC throw (std::bad_alloc) -#else -#define GOOGLE_GLOG_THROW_BAD_ALLOC -#endif - -using std::map; -using std::string; -using std::vector; - -_START_GOOGLE_NAMESPACE_ - -extern GLOG_EXPORT void (*g_logging_fail_func)(); - -_END_GOOGLE_NAMESPACE_ - -#undef GLOG_EXPORT -#define GLOG_EXPORT - -static inline string GetTempDir() { - vector temp_directories_list; - google::GetExistingTempDirectories(&temp_directories_list); - - if (temp_directories_list.empty()) { - fprintf(stderr, "No temporary directory found\n"); - exit(EXIT_FAILURE); - } - - // Use first directory from list of existing temporary directories. - return temp_directories_list.front(); -} - -#if defined(GLOG_OS_WINDOWS) && defined(_MSC_VER) && !defined(TEST_SRC_DIR) -// 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 - -static const uint32_t PTR_TEST_VALUE = 0x12345678; - -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**); - -void InitGoogleTest(int*, char**) {} - -// The following is some bare-bones testing infrastructure - -#define EXPECT_NEAR(val1, val2, abs_error) \ - do { \ - if (abs(val1 - val2) > abs_error) { \ - fprintf(stderr, "Check failed: %s within %s of %s\n", #val1, #abs_error, \ - #val2); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - -#define EXPECT_TRUE(cond) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "Check failed: %s\n", #cond); \ - exit(EXIT_FAILURE); \ - } \ - } 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(EXIT_FAILURE); \ - } \ - } 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(EXIT_FAILURE); \ - } \ - } while (0) - -#define EXPECT_INF(arg) \ - do { \ - if (!isinf(arg)) { \ - fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \ - exit(EXIT_FAILURE); \ - } \ - } 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(EXIT_FAILURE); \ - } \ - } while (0) - -#define EXPECT_STREQ(val1, val2) \ - do { \ - if (strcmp((val1), (val2)) != 0) { \ - fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \ - exit(EXIT_FAILURE); \ - } \ - } 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", - static_cast(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 GLOG_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(EXIT_FAILURE); \ - } \ - } 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 = (static_cast(clock()) - start) / - CLOCKS_PER_SEC * 1000 * 1000 * 1000; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat=" -#endif - printf("%s\t%8.2lf\t%10d\n", - iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt); -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - } - 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 CaptureTestStdout() { - CaptureTestOutput(STDOUT_FILENO, FLAGS_test_tmpdir + "/captured.out"); -} -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); -} - -static const std::size_t kLoggingPrefixLength = 9; - -// Check if the string is [IWEF](\d{8}|YEARDATE) -static inline bool IsLoggingPrefix(const string& s) { - if (s.size() != kLoggingPrefixLength) { - return false; - } - if (!strchr("IWEF", s[0])) return false; - for (size_t i = 1; i <= 8; ++i) { - if (!isdigit(s[i]) && s[i] != "YEARDATE"[i-1]) return false; - } - return true; -} - -// Convert log output into normalized form. -// -// Example: -// I20200102 030405 logging_unittest.cc:345] RAW: vlog -1 -// => IYEARDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1 -static inline string MungeLine(const string& line) { - string before, logcode_date, time, thread_lineinfo; - std::size_t begin_of_logging_prefix = 0; - for (; begin_of_logging_prefix + kLoggingPrefixLength < line.size(); - ++begin_of_logging_prefix) { - if (IsLoggingPrefix( - line.substr(begin_of_logging_prefix, kLoggingPrefixLength))) { - break; - } - } - if (begin_of_logging_prefix + kLoggingPrefixLength >= line.size()) { - return line; - } else if (begin_of_logging_prefix > 0) { - before = line.substr(0, begin_of_logging_prefix - 1); - } - std::istringstream iss(line.substr(begin_of_logging_prefix)); - iss >> logcode_date; - 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] + "YEARDATE 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); - } -} - -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); - const size_t str_size = 256; - char null_str[str_size]; - char ptr_str[str_size]; - snprintf(null_str, str_size, "%p", static_cast(NULL)); - snprintf(ptr_str, str_size, "%p", reinterpret_cast(PTR_TEST_VALUE)); - - StringReplace(&line, "__NULLP__", null_str); - StringReplace(&line, "__PTRTEST__", ptr_str); - - StringReplace(&line, "__SUCCESS__", StrError(0)); - 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 MungeAndDiffTest(const string& golden_filename, - CapturedStream* cap) { - if (cap == s_captured_streams[STDOUT_FILENO]) { - CHECK(cap) << ": did you forget CaptureTestStdout()?"; - } else { - 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); -#ifdef GLOG_OS_WINDOWS - string diffcmd("fc " + munged_golden + " " + munged_captured); -#else - string diffcmd("diff -u " + munged_golden + " " + munged_captured); -#endif - 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; -} - -static inline bool MungeAndDiffTestStderr(const string& golden_filename) { - return MungeAndDiffTest(golden_filename, s_captured_streams[STDERR_FILENO]); -} - -static inline bool MungeAndDiffTestStdout(const string& golden_filename) { - return MungeAndDiffTest(golden_filename, s_captured_streams[STDOUT_FILENO]); -} - -// 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(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN) - void Start() { - handle_ = CreateThread(NULL, - 0, - &Thread::InvokeThreadW, - 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) { - (static_cast(self))->Run(); - return NULL; - } - -#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN) - static DWORD __stdcall InvokeThreadW(LPVOID self) { - InvokeThread(self); - return 0; - } - HANDLE handle_; - DWORD th_; -#else - pthread_t th_; -#endif -}; - -static inline void SleepForMilliseconds(unsigned t) { -#ifndef GLOG_OS_WINDOWS -# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L - const struct timespec req = {0, t * 1000 * 1000}; - nanosleep(&req, NULL); -# else - usleep(t * 1000); -# endif -#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) GOOGLE_GLOG_THROW_BAD_ALLOC { - if (GOOGLE_NAMESPACE::g_new_hook) { - GOOGLE_NAMESPACE::g_new_hook(); - } - return malloc(size); -} - -void* operator new[](size_t size) GOOGLE_GLOG_THROW_BAD_ALLOC { - return ::operator new(size); -} - -void operator delete(void* p) throw() { - free(p); -} - -void operator delete(void* p, size_t) throw() { - ::operator delete(p); -} - -void operator delete[](void* p) throw() { - ::operator delete(p); -} - -void operator delete[](void* p, size_t) throw() { - ::operator delete(p); -} diff --git a/third_party/glog/src/logging.cc b/third_party/glog/src/logging.cc deleted file mode 100644 index 4028ccc..0000000 --- a/third_party/glog/src/logging.cc +++ /dev/null @@ -1,2691 +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 -#include -#ifdef HAVE_PWD_H -# include -#endif -#ifdef HAVE_SYSLOG_H -# include -#endif -#include -#include // for errno -#include -#ifdef GLOG_OS_WINDOWS -#include "windows/dirent.h" -#else -#include // for automatic removal of old logs -#endif -#include "base/commandlineflags.h" // to get the program name -#include -#include -#include "base/googleinit.h" - -#ifdef HAVE_STACKTRACE -# include "stacktrace.h" -#endif - -#ifdef __ANDROID__ -#include -#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 - -#ifdef _WIN32 -#define fdopen _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(timestamp_in_logfile_name, - BoolFromEnv("GOOGLE_TIMESTAMP_IN_LOGFILE_NAME", true), - "put a timestamp at the end of the log file name"); -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)"); -GLOG_DEFINE_bool(colorlogtostdout, false, - "color messages logged to stdout (if supported by terminal)"); -GLOG_DEFINE_bool(logtostdout, BoolFromEnv("GOOGLE_LOGTOSTDOUT", false), - "log messages go to stdout instead of logfiles"); -#ifdef GLOG_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."); -#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_bool(log_year_in_prefix, true, - "Include the year in the log prefix"); -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(logcleansecs, 60 * 5, // every 5 minutes - "Clean overdue logs every 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, "", - "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_int32(logfile_mode, 0664, "Log file mode/permissions."); - -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_uint32(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."); - -GLOG_DEFINE_bool(log_utc_time, false, - "Use UTC time for logging."); - -// TODO(hamaji): consider windows -#define PATH_SEPARATOR '/' - -#ifndef HAVE_PREAD -#if defined(GLOG_OS_WINDOWS) -#include -#define ssize_t SSIZE_T -#endif -static ssize_t pread(int fd, void* buf, size_t count, off_t offset) { - off_t orig_offset = lseek(fd, 0, SEEK_CUR); - if (orig_offset == (off_t)-1) - return -1; - if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) - return -1; - ssize_t len = read(fd, buf, count); - if (len < 0) - return len; - if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) - return -1; - return len; -} -#endif // !HAVE_PREAD - -#ifndef HAVE_PWRITE -static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) { - off_t orig_offset = lseek(fd, 0, SEEK_CUR); - if (orig_offset == (off_t)-1) - return -1; - if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) - return -1; - ssize_t len = write(fd, buf, count); - if (len < 0) - return len; - if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) - return -1; - return len; -} -#endif // !HAVE_PWRITE - -static void GetHostName(string* hostname) { -#if defined(HAVE_SYS_UTSNAME_H) - struct utsname buf; - if (uname(&buf) < 0) { - // ensure null termination on failure - *buf.nodename = '\0'; - } - *hostname = buf.nodename; -#elif defined(GLOG_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 GLOG_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-256color") || - !strcmp(term, "konsole") || - !strcmp(term, "konsole-16color") || - !strcmp(term, "konsole-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 GLOG_OS_WINDOWS - -// Returns the character attribute for the given color. -static 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. -static 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 // GLOG_OS_WINDOWS - -// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 -static uint32 MaxLogSize() { - return (FLAGS_max_log_size > 0 && FLAGS_max_log_size < 4096 - ? FLAGS_max_log_size - : 1); -} - -// 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; - -struct LogMessage::LogMessageData { - LogMessageData(); - - int preserved_errno_; // preserved errno - // Buffer space; contains complete message text. - char message_text_[LogMessage::kMaxLogMessageLen+1]; - 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 - }; - 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 - - 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() { -} - -#ifdef GLOG_CUSTOM_PREFIX_SUPPORT -namespace { - // Optional user-configured callback to print custom prefixes. - CustomPrefixCallback custom_prefix_callback = NULL; - // User-provided data to pass to the callback: - void* custom_prefix_callback_data = NULL; -} -#endif - -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, - size_t 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 dropped_mem_length_; - uint32 file_length_; - unsigned int rollover_attempt_; - int64 next_flush_time_; // cycle count at which to flush log - WallTime start_time_; - - // Actually create a logfile using the value of base_filename_ and the - // optional argument time_pid_string - // REQUIRES: lock_ is held - bool CreateLogfile(const string& time_pid_string); -}; - -// Encapsulate all log cleaner related states -class LogCleaner { - public: - LogCleaner(); - - // Setting overdue_days to 0 days will delete all logs. - void Enable(unsigned int overdue_days); - void Disable(); - - // update next_cleanup_time_ - void UpdateCleanUpTime(); - - void Run(bool base_filename_selected, - const string& base_filename, - const string& filename_extension); - - bool enabled() const { return enabled_; } - - private: - vector GetOverdueLogNames(string log_directory, unsigned int days, - const string& base_filename, - const string& filename_extension) const; - - bool IsLogFromCurrentProject(const string& filepath, - const string& base_filename, - const string& filename_extension) const; - - bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const; - - bool enabled_; - unsigned int overdue_days_; - int64 next_cleanup_time_; // cycle count at which to clean overdue log -}; - -LogCleaner log_cleaner; - -} // 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 message_len, size_t prefix_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 LogMessageTime& logmsgtime, 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_) { -} - -LogDestination::~LogDestination() { - if (logger_ && logger_ != &fileobject_) { - // Delete user-specified logger set via SetLogger(). - delete logger_; - } -} - -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_destinations_[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_) { - sinks_->erase(std::remove(sinks_->begin(), sinks_->end(), destination), sinks_->end()); - } -} - -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 ColoredWriteToStderrOrStdout(FILE* output, LogSeverity severity, - const char* message, size_t len) { - bool is_stdout = (output == stdout); - const GLogColor color = (LogDestination::terminal_supports_color() && - ((!is_stdout && FLAGS_colorlogtostderr) || - (is_stdout && FLAGS_colorlogtostdout))) - ? 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, output); - return; - } -#ifdef GLOG_OS_WINDOWS - const HANDLE output_handle = - GetStdHandle(is_stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(output_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(output); - SetConsoleTextAttribute(output_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - fwrite(message, len, 1, output); - fflush(output); - // Restores the text color. - SetConsoleTextAttribute(output_handle, old_color_attrs); -#else - fprintf(output, "\033[0;3%sm", GetAnsiColorCode(color)); - fwrite(message, len, 1, output); - fprintf(output, "\033[m"); // Resets the terminal to default. -#endif // GLOG_OS_WINDOWS -} - -static void ColoredWriteToStdout(LogSeverity severity, const char* message, - size_t len) { - FILE* output = stdout; - // We also need to send logs to the stderr when the severity is - // higher or equal to the stderr threshold. - if (severity >= FLAGS_stderrthreshold) { - output = stderr; - } - ColoredWriteToStderrOrStdout(output, severity, message, len); -} - -static void ColoredWriteToStderr(LogSeverity severity, const char* message, - size_t len) { - ColoredWriteToStderrOrStdout(stderr, severity, message, len); -} - -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 message_len, size_t prefix_len) { - if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { - ColoredWriteToStderr(severity, message, message_len); -#ifdef GLOG_OS_WINDOWS - (void) prefix_len; - // On Windows, also output to the debugger - ::OutputDebugStringA(message); -#elif defined(__ANDROID__) - // On Android, also output to logcat - const int android_log_levels[NUM_SEVERITIES] = { - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL, - }; - __android_log_write(android_log_levels[severity], - glog_internal_namespace_::ProgramInvocationShortName(), - message + prefix_len); -#else - (void) prefix_len; -#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_logtostdout) { // global flag: never log to file - ColoredWriteToStdout(severity, message, len); - } else 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 LogMessageTime& logmsgtime, - const char* message, - size_t message_len) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (size_t i = sinks_->size(); i-- > 0; ) { - (*sinks_)[i]->send(severity, full_filename, base_filename, - line, logmsgtime, message, message_len); - } - } -} - -inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { - ReaderMutexLock l(&sink_mutex_); - if (sinks_) { - for (size_t i = sinks_->size(); i-- > 0; ) { - (*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; - } - MutexLock l(&sink_mutex_); - delete sinks_; - sinks_ = NULL; -} - -namespace { - -std::string g_application_fingerprint; - -} // namespace - -void SetApplicationFingerprint(const std::string& fingerprint) { - g_application_fingerprint = fingerprint; -} - -namespace { - -// Directory delimiter; Windows supports both forward slashes and backslashes -#ifdef GLOG_OS_WINDOWS -const char possible_dir_delim[] = {'\\', '/'}; -#else -const char possible_dir_delim[] = {'/'}; -#endif - -string PrettyDuration(int secs) { - std::stringstream result; - int mins = secs / 60; - int hours = mins / 60; - mins = mins % 60; - secs = secs % 60; - result.fill('0'); - result << hours << ':' << setw(2) << mins << ':' << setw(2) << secs; - return result.str(); -} - - -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), - dropped_mem_length_(0), - file_length_(0), - rollover_attempt_(kRolloverAttemptFrequency-1), - next_flush_time_(0), - start_time_(WallTime_Now()) { - 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_; - if (FLAGS_timestamp_in_logfile_name) { - string_filename += time_pid_string; - } - string_filename += filename_extension_; - const char* filename = string_filename.c_str(); - //only write to files, create if non-existant. - int flags = O_WRONLY | O_CREAT; - if (FLAGS_timestamp_in_logfile_name) { - //demand that the file is unique for our timestamp (fail if it exists). - flags = flags | O_EXCL; - } - int fd = open(filename, flags, FLAGS_logfile_mode); - 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); - - // Mark the file as exclusive write access to avoid two clients logging to the - // same file. This applies particularly when !FLAGS_timestamp_in_logfile_name - // (otherwise open would fail because the O_EXCL flag on similar filename). - // locks are released on unlock or close() automatically, only after log is - // released. - // This will work after a fork as it is not inherited (not stored in the fd). - // Lock will not be lost because the file is opened with exclusive lock (write) - // and we will never read from it inside the process. - // TODO windows implementation of this (as flock is not available on mingw). - static struct flock w_lock; - - w_lock.l_type = F_WRLCK; - w_lock.l_start = 0; - w_lock.l_whence = SEEK_SET; - w_lock.l_len = 0; - - int wlock_ret = fcntl(fd, F_SETLK, &w_lock); - if (wlock_ret == -1) { - close(fd); //as we are failing already, do not check errors here - return false; - } -#endif - - //fdopen in append mode so if the file exists it will fseek to the end - file_ = fdopen(fd, "a"); // Make a FILE*. - if (file_ == NULL) { // Man, we're screwed! - close(fd); - if (FLAGS_timestamp_in_logfile_name) { - unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it. - } - return false; - } -#ifdef GLOG_OS_WINDOWS - // https://github.com/golang/go/issues/27638 - make sure we seek to the end to append - // empirically replicated with wine over mingw build - if (!FLAGS_timestamp_in_logfile_name) { - if (fseek(file_, 0, SEEK_END) != 0) { - return false; - } - } -#endif - // 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, static_cast(slash-filename+1)); // get dirname - linkpath += linkname; - unlink(linkpath.c_str()); // delete old one if it exists - -#if defined(GLOG_OS_WINDOWS) - // TODO(hamaji): Create lnk file on Windows? -#elif defined(HAVE_UNISTD_H) - // We must 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, - size_t 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 (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) { - if (file_ != NULL) fclose(file_); - file_ = NULL; - file_length_ = bytes_since_flush_ = dropped_mem_length_ = 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; - if (FLAGS_log_utc_time) { - gmtime_r(×tamp, &tm_time); - } else { - 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 << (FLAGS_log_utc_time ? " UTC\n" : "\n") - << "Running on machine: " - << LogDestination::hostname() << '\n'; - - if(!g_application_fingerprint.empty()) { - file_header_stream << "Application fingerprint: " << g_application_fingerprint << '\n'; - } - const char* const date_time_format = FLAGS_log_year_in_prefix - ? "yyyymmdd hh:mm:ss.uuuuuu" - : "mmdd hh:mm:ss.uuuuuu"; - file_header_stream << "Running duration (h:mm:ss): " - << PrettyDuration(static_cast(WallTime_Now() - start_time_)) << '\n' - << "Log line format: [IWEF]" << date_time_format << " " - << "threadid file:line] msg" << '\n'; - const string& file_header_string = file_header_stream.str(); - - const size_t 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 GLOG_OS_LINUX - // Only consider files >= 3MiB - if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) { - // Don't evict the most recent 1-2MiB so as not to impact a tailer - // of the log file and to avoid page rounding issue on linux < 4.7 - uint32 total_drop_length = - (file_length_ & ~((1U << 20U) - 1U)) - (1U << 20U); - uint32 this_drop_length = total_drop_length - dropped_mem_length_; - if (this_drop_length >= (2U << 20U)) { - // Only advise when >= 2MiB to drop -# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) - // 'posix_fadvise' introduced in API 21: - // * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732 -# else - posix_fadvise(fileno(file_), dropped_mem_length_, this_drop_length, - POSIX_FADV_DONTNEED); -# endif - dropped_mem_length_ = total_drop_length; - } - } -#endif - - // Remove old logs - if (log_cleaner.enabled()) { - log_cleaner.Run(base_filename_selected_, - base_filename_, - filename_extension_); - } - } -} - -LogCleaner::LogCleaner() : enabled_(false), overdue_days_(7), next_cleanup_time_(0) {} - -void LogCleaner::Enable(unsigned int overdue_days) { - enabled_ = true; - overdue_days_ = overdue_days; -} - -void LogCleaner::Disable() { - enabled_ = false; -} - -void LogCleaner::UpdateCleanUpTime() { - const int64 next = (FLAGS_logcleansecs - * 1000000); // in usec - next_cleanup_time_ = CycleClock_Now() + UsecToCycles(next); -} - -void LogCleaner::Run(bool base_filename_selected, - const string& base_filename, - const string& filename_extension) { - assert(enabled_); - assert(!base_filename_selected || !base_filename.empty()); - - // avoid scanning logs too frequently - if (CycleClock_Now() < next_cleanup_time_) { - return; - } - UpdateCleanUpTime(); - - vector dirs; - - if (!base_filename_selected) { - dirs = GetLoggingDirectories(); - } else { - size_t pos = base_filename.find_last_of(possible_dir_delim, string::npos, - sizeof(possible_dir_delim)); - if (pos != string::npos) { - string dir = base_filename.substr(0, pos + 1); - dirs.push_back(dir); - } else { - dirs.push_back("."); - } - } - - for (size_t i = 0; i < dirs.size(); i++) { - vector logs = GetOverdueLogNames(dirs[i], - overdue_days_, - base_filename, - filename_extension); - for (size_t j = 0; j < logs.size(); j++) { - static_cast(unlink(logs[j].c_str())); - } - } -} - -vector LogCleaner::GetOverdueLogNames( - string log_directory, unsigned int days, const string& base_filename, - const string& filename_extension) const { - // The names of overdue logs. - vector overdue_log_names; - - // Try to get all files within log_directory. - DIR *dir; - struct dirent *ent; - - if ((dir = opendir(log_directory.c_str()))) { - while ((ent = readdir(dir))) { - if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { - continue; - } - - string filepath = ent->d_name; - const char* const dir_delim_end = - possible_dir_delim + sizeof(possible_dir_delim); - - if (!log_directory.empty() && - std::find(possible_dir_delim, dir_delim_end, - log_directory[log_directory.size() - 1]) != dir_delim_end) { - filepath = log_directory + filepath; - } - - if (IsLogFromCurrentProject(filepath, base_filename, filename_extension) && - IsLogLastModifiedOver(filepath, days)) { - overdue_log_names.push_back(filepath); - } - } - closedir(dir); - } - - return overdue_log_names; -} - -bool LogCleaner::IsLogFromCurrentProject(const string& filepath, - const string& base_filename, - const string& filename_extension) const { - // We should remove duplicated delimiters from `base_filename`, e.g., - // before: "/tmp//.." - // after: "/tmp/.." - string cleaned_base_filename; - - const char* const dir_delim_end = - possible_dir_delim + sizeof(possible_dir_delim); - - size_t real_filepath_size = filepath.size(); - for (size_t i = 0; i < base_filename.size(); ++i) { - const char& c = base_filename[i]; - - if (cleaned_base_filename.empty()) { - cleaned_base_filename += c; - } else if (std::find(possible_dir_delim, dir_delim_end, c) == - dir_delim_end || - (!cleaned_base_filename.empty() && - c != cleaned_base_filename[cleaned_base_filename.size() - 1])) { - cleaned_base_filename += c; - } - } - - // Return early if the filename doesn't start with `cleaned_base_filename`. - if (filepath.find(cleaned_base_filename) != 0) { - return false; - } - - // Check if in the string `filename_extension` is right next to - // `cleaned_base_filename` in `filepath` if the user - // has set a custom filename extension. - if (!filename_extension.empty()) { - if (cleaned_base_filename.size() >= real_filepath_size) { - return false; - } - // for origin version, `filename_extension` is middle of the `filepath`. - string ext = filepath.substr(cleaned_base_filename.size(), filename_extension.size()); - if (ext == filename_extension) { - cleaned_base_filename += filename_extension; - } - else { - // for new version, `filename_extension` is right of the `filepath`. - if (filename_extension.size() >= real_filepath_size) { - return false; - } - real_filepath_size = filepath.size() - filename_extension.size(); - if (filepath.substr(real_filepath_size) != filename_extension) { - return false; - } - } - } - - // The characters after `cleaned_base_filename` should match the format: - // YYYYMMDD-HHMMSS.pid - for (size_t i = cleaned_base_filename.size(); i < real_filepath_size; i++) { - const char& c = filepath[i]; - - if (i <= cleaned_base_filename.size() + 7) { // 0 ~ 7 : YYYYMMDD - if (c < '0' || c > '9') { return false; } - - } else if (i == cleaned_base_filename.size() + 8) { // 8: - - if (c != '-') { return false; } - - } else if (i <= cleaned_base_filename.size() + 14) { // 9 ~ 14: HHMMSS - if (c < '0' || c > '9') { return false; } - - } else if (i == cleaned_base_filename.size() + 15) { // 15: . - if (c != '.') { return false; } - - } else if (i >= cleaned_base_filename.size() + 16) { // 16+: pid - if (c < '0' || c > '9') { return false; } - } - } - - return true; -} - -bool LogCleaner::IsLogLastModifiedOver(const string& filepath, - unsigned int days) const { - // Try to get the last modified time of this file. - struct stat file_stat; - - if (stat(filepath.c_str(), &file_stat) == 0) { - const time_t seconds_in_a_day = 60 * 60 * 24; - time_t last_modified_time = file_stat.st_mtime; - time_t current_time = time(NULL); - return difftime(current_time, last_modified_time) > days * seconds_in_a_day; - } - - // If failed to get file stat, don't return true! - return false; -} - -} // namespace - -// 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 LogMessage::LogMessageData fatal_msg_data_exclusive; -static LogMessage::LogMessageData fatal_msg_data_shared; - -#ifdef GLOG_THREAD_LOCAL_STORAGE -// Static thread-local log data space to use, because typically at most one -// LogMessageData object exists (in this case glog makes zero heap memory -// allocations). -static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true; - -#if defined(HAVE_ALIGNED_STORAGE) && __cplusplus >= 201103L -static GLOG_THREAD_LOCAL_STORAGE - std::aligned_storage::type thread_msg_data; -#else -static GLOG_THREAD_LOCAL_STORAGE - char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)]; -#endif // HAVE_ALIGNED_STORAGE -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) - -LogMessage::LogMessageData::LogMessageData() - : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { -} - -LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - int64 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) { -#ifdef GLOG_THREAD_LOCAL_STORAGE - // No need for locking, because this is thread local. - if (thread_data_available) { - thread_data_available = false; -#ifdef HAVE_ALIGNED_STORAGE - data_ = new (&thread_msg_data) LogMessageData; -#else - const uintptr_t kAlign = sizeof(void*) - 1; - - char* align_ptr = - reinterpret_cast(reinterpret_cast(thread_msg_data + kAlign) & ~kAlign); - data_ = new (align_ptr) LogMessageData; - assert(reinterpret_cast(align_ptr) % sizeof(void*) == 0); -#endif - } else { - allocated_ = new LogMessageData(); - data_ = allocated_; - } -#else // !defined(GLOG_THREAD_LOCAL_STORAGE) - allocated_ = new LogMessageData(); - data_ = allocated_; -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) - data_->first_fatal_ = false; - } else { - MutexLock l(&fatal_msg_lock); - if (fatal_msg_exclusive) { - fatal_msg_exclusive = false; - data_ = &fatal_msg_data_exclusive; - data_->first_fatal_ = true; - } else { - data_ = &fatal_msg_data_shared; - data_->first_fatal_ = false; - } - } - - 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(); - time_t timestamp_now = static_cast(now); - logmsgtime_ = LogMessageTime(timestamp_now, now); - - 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: - // I20201018 160715 f5d4fbb0 logging.cc:1153] - // (log level, GMT year, month, date, time, thread_id, file basename, line) - // We exclude the thread_id for the default thread. - if (FLAGS_log_prefix && (line != kNoLogPrefix)) { - std::ios saved_fmt(NULL); - saved_fmt.copyfmt(stream()); - stream().fill('0'); - #ifdef GLOG_CUSTOM_PREFIX_SUPPORT - if (custom_prefix_callback == NULL) { - #endif - stream() << LogSeverityNames[severity][0]; - if (FLAGS_log_year_in_prefix) { - stream() << setw(4) << 1900 + logmsgtime_.year(); - } - stream() << setw(2) << 1 + logmsgtime_.month() - << setw(2) << logmsgtime_.day() - << ' ' - << setw(2) << logmsgtime_.hour() << ':' - << setw(2) << logmsgtime_.min() << ':' - << setw(2) << logmsgtime_.sec() << "." - << setw(6) << logmsgtime_.usec() - << ' ' - << setfill(' ') << setw(5) - << static_cast(GetTID()) << setfill('0') - << ' ' - << data_->basename_ << ':' << data_->line_ << "] "; - #ifdef GLOG_CUSTOM_PREFIX_SUPPORT - } else { - custom_prefix_callback( - stream(), - LogMessageInfo(LogSeverityNames[severity], - data_->basename_, data_->line_, GetTID(), - logmsgtime_), - custom_prefix_callback_data - ); - stream() << " "; - } - #endif - stream().copyfmt(saved_fmt); - } - 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 (FLAGS_log_backtrace_at == fileline) { - string stacktrace; - DumpStackTraceToString(&stacktrace); - stream() << " (stacktrace:\n" << stacktrace << ") "; - } -#endif - } -} - -const LogMessageTime& LogMessage::getLogMessageTime() const { - return logmsgtime_; -} - -LogMessage::~LogMessage() { - Flush(); -#ifdef GLOG_THREAD_LOCAL_STORAGE - if (data_ == static_cast(&thread_msg_data)) { - data_->~LogMessageData(); - thread_data_available = true; - } - else { - delete allocated_; - } -#else // !defined(GLOG_THREAD_LOCAL_STORAGE) - delete allocated_; -#endif // defined(GLOG_THREAD_LOCAL_STORAGE) -} - -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'; - } - data_->message_text_[data_->num_chars_to_log_] = '\0'; - - // 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_data_exclusive. -static time_t fatal_time; -static char fatal_message[256]; - -void ReprintFatalMessage() { - if (fatal_message[0]) { - const size_t 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 || FLAGS_logtostdout || !IsGoogleLoggingInitialized()) { - if (FLAGS_logtostdout) { - ColoredWriteToStdout(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - } else { - 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_, logmsgtime_, - 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_, logmsgtime_.timestamp(), - data_->message_text_, - data_->num_chars_to_log_); - - LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, - data_->num_chars_to_log_, - data_->num_prefix_chars_); - LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, - data_->num_chars_to_log_); - LogDestination::LogToSinks(data_->severity_, - data_->fullname_, data_->basename_, - data_->line_, logmsgtime_, - 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 size_t copy = min(data_->num_chars_to_log_, - sizeof(fatal_message)-1); - memcpy(fatal_message, data_->message_text_, copy); - fatal_message[copy] = '\0'; - fatal_time = logmsgtime_.timestamp(); - } - - if (!FLAGS_logtostderr && !FLAGS_logtostdout) { - 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. - } -#if defined(__ANDROID__) - // ANDROID_LOG_FATAL as this message is of FATAL severity. - __android_log_write(ANDROID_LOG_FATAL, - glog_internal_namespace_::ProgramInvocationShortName(), - message); -#endif - 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_data_exclusive.message_text_ + - 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 -} - -GLOG_EXPORT logging_fail_func_t g_logging_fail_func = - reinterpret_cast(&abort); - -void InstallFailureFunction(logging_fail_func_t fail_func) { - g_logging_fail_func = 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_, logmsgtime_, - 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_; - size_t 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_; - size_t 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, int64 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. - stream() << ": " << StrError(preserved_errno()) << " [" - << 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::send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const LogMessageTime& time, const char* message, - size_t message_len) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#elif defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4996) -#endif // __GNUC__ - send(severity, full_filename, base_filename, line, &time.tm(), message, - message_len); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#elif defined(_MSC_VER) -#pragma warning(pop) -#endif // __GNUC__ -} - -void LogSink::send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const std::tm* t, - const char* message, size_t message_len) { - (void)severity; - (void)full_filename; - (void)base_filename; - (void)line; - (void)t; - (void)message; - (void)message_len; -} - -void LogSink::WaitTillSent() { - // noop default -} - -string LogSink::ToString(LogSeverity severity, const char* file, int line, - const LogMessageTime& logmsgtime, const char* message, - size_t message_len) { - ostringstream stream(string(message, message_len)); - stream.fill('0'); - - stream << LogSeverityNames[severity][0] - << setw(4) << 1900 + logmsgtime.year() - << setw(2) << 1 + logmsgtime.month() - << setw(2) << logmsgtime.day() - << ' ' - << setw(2) << logmsgtime.hour() << ':' - << setw(2) << logmsgtime.min() << ':' - << setw(2) << logmsgtime.sec() << '.' - << setw(6) << logmsgtime.usec() - << ' ' - << 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(); -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); -void SetExitOnDFatal(bool value) { - MutexLock l(&log_mutex); - exit_on_dfatal = value; -} - -} // namespace internal -} // namespace base - -// Shell-escaping as we need to shell out ot /bin/mail. -static const char kDontNeedShellEscapeChars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+-_.=/:,@"; - -static string ShellEscape(const string& src) { - string result; - if (!src.empty() && // empty string needs quotes - src.find_first_not_of(kDontNeedShellEscapeChars) == string::npos) { - // only contains chars that don't need quotes; it's fine - result.assign(src); - } else if (src.find_first_of('\'') == string::npos) { - // no single quotes; just wrap it in single quotes - result.assign("'"); - result.append(src); - result.append("'"); - } else { - // needs double quote escaping - result.assign("\""); - for (size_t i = 0; i < src.size(); ++i) { - switch (src[i]) { - case '\\': - case '$': - case '"': - case '`': - result.append("\\"); - } - result.append(src, i, 1); - } - result.append("\""); - } - return result; -} - - -// 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) { -#ifndef __EMSCRIPTEN__ - 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 logmailer = FLAGS_logmailer; - if (logmailer.empty()) { - logmailer = "/bin/mail"; - } - string cmd = - logmailer + " -s" + - ShellEscape(subject) + " " + ShellEscape(dest); - if (use_logging) { - VLOG(4) << "Mailing command: " << cmd; - } - - 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 ) { - LOG(ERROR) << "Problems sending mail to " << dest << ": " - << StrError(errno); - } else { - fprintf(stderr, "Problems sending mail to %s: %s\n", - dest, StrError(errno).c_str()); - } - } - 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); - } - } - } -#endif - 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 GLOG_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); - } else { - GetTempDirectories(logging_directories_list); -#ifdef GLOG_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, uint64 limit, uint64 keep) { -#ifdef HAVE_UNISTD_H - struct stat statbuf; - const int kCopyBlockSize = 8 << 10; - char copybuf[kCopyBlockSize]; - off_t read_offset, write_offset; - // Don't follow symlinks unless they're our own fd symlinks in /proc - int flags = O_RDWR; - // TODO(hamaji): Support other environments. -#ifdef GLOG_OS_LINUX - const char *procfd_prefix = "/proc/self/fd/"; - if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; -#endif - - 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 <= static_cast(limit)) goto out_close_fd; - if (statbuf.st_size <= static_cast(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 - static_cast(keep); - write_offset = 0; - ssize_t bytesin, bytesout; - while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { - bytesout = pwrite(fd, copybuf, static_cast(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 - uint64 limit = MaxLogSize() << 20U; - uint64 keep = 1U << 20U; - 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(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_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; - } - } -} - -string StrError(int err) { - char buf[100]; - int rc = posix_strerror_r(err, buf, sizeof(buf)); - if ((rc < 0) || (buf[0] == '\000')) { - snprintf(buf, sizeof(buf), "Error number %d", err); - } - return buf; -} - -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 " << static_cast(v); - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const signed char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "signed char value " << static_cast(v); - } -} - -template <> -void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { - if (v >= 32 && v <= 126) { - (*os) << "'" << v << "'"; - } else { - (*os) << "unsigned char value " << static_cast(v); - } -} - -#if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L -template <> -void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) { - (*os) << "nullptr"; -} -#endif // defined(HAVE_CXX11_NULLPTR_T) - -void InitGoogleLogging(const char* argv0) { - glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); -} - -#ifdef GLOG_CUSTOM_PREFIX_SUPPORT -void InitGoogleLogging(const char* argv0, - CustomPrefixCallback prefix_callback, - void* prefix_callback_data) { - custom_prefix_callback = prefix_callback; - custom_prefix_callback_data = prefix_callback_data; - InitGoogleLogging(argv0); -} -#endif - -void ShutdownGoogleLogging() { - glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); - LogDestination::DeleteLogDestinations(); - delete logging_directories_list; - logging_directories_list = NULL; -} - -void EnableLogCleaner(unsigned int overdue_days) { - log_cleaner.Enable(overdue_days); -} - -void DisableLogCleaner() { - log_cleaner.Disable(); -} - -LogMessageTime::LogMessageTime() - : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {} - -LogMessageTime::LogMessageTime(std::tm t) { - std::time_t timestamp = std::mktime(&t); - init(t, timestamp, 0); -} - -LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) { - std::tm t; - if (FLAGS_log_utc_time) - gmtime_r(×tamp, &t); - else - localtime_r(×tamp, &t); - init(t, timestamp, now); -} - -void LogMessageTime::init(const std::tm& t, std::time_t timestamp, - WallTime now) { - time_struct_ = t; - timestamp_ = timestamp; - usecs_ = static_cast((now - timestamp) * 1000000); - - CalcGmtOffset(); -} - -void LogMessageTime::CalcGmtOffset() { - std::tm gmt_struct; - int isDst = 0; - if ( FLAGS_log_utc_time ) { - localtime_r(×tamp_, &gmt_struct); - isDst = gmt_struct.tm_isdst; - gmt_struct = time_struct_; - } else { - isDst = time_struct_.tm_isdst; - gmtime_r(×tamp_, &gmt_struct); - } - - time_t gmt_sec = mktime(&gmt_struct); - const long hour_secs = 3600; - // If the Daylight Saving Time(isDst) is active subtract an hour from the current timestamp. - gmtoffset_ = static_cast(timestamp_ - gmt_sec + (isDst ? hour_secs : 0) ) ; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/logging_custom_prefix_unittest.cc b/third_party/glog/src/logging_custom_prefix_unittest.cc deleted file mode 100644 index 615dce7..0000000 --- a/third_party/glog/src/logging_custom_prefix_unittest.cc +++ /dev/null @@ -1,1384 +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 "utilities.h" - -#include -#ifdef HAVE_GLOB_H -# include -#endif -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_SYS_WAIT_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "base/commandlineflags.h" -#include -#include -#include "googletest.h" - -DECLARE_string(log_backtrace_at); // logging.cc - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#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 TestBasenameAppendWhenNoTimestamp(); -static void TestTwoProcessesWrite(); -static void TestSymlink(); -static void TestExtension(); -static void TestWrapper(); -static void TestErrno(); -static void TestTruncate(); -static void TestCustomLoggerDeletionOnShutdown(); - -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) - -// Dynamically generate a prefix using the default format and write it to the stream. -void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) { - // Assert that `data` contains the expected contents before producing the - // prefix (otherwise causing the tests to fail): - if (data == NULL || *static_cast(data) != "good data") { - return; - } - - s << l.severity[0] - << setw(4) << 1900 + l.time.year() - << setw(2) << 1 + l.time.month() - << setw(2) << l.time.day() - << ' ' - << setw(2) << l.time.hour() << ':' - << setw(2) << l.time.min() << ':' - << setw(2) << l.time.sec() << "." - << setw(6) << l.time.usec() - << ' ' - << setfill(' ') << setw(5) - << l.thread_id << setfill('0') - << ' ' - << l.filename << ':' << l.line_number << "]"; -} - -int main(int argc, char **argv) { - FLAGS_colorlogtostderr = false; - FLAGS_timestamp_in_logfile_name = true; - - // 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(); - - EXPECT_FALSE(IsGoogleLoggingInitialized()); - - // Setting a custom prefix generator (it will use the default format so that - // the golden outputs can be reused): - string prefix_attacher_data = "good data"; - InitGoogleLogging(argv[0], &PrefixAttacher, static_cast(&prefix_attacher_data)); - - EXPECT_TRUE(IsGoogleLoggingInitialized()); - - RunSpecifiedBenchmarks(); - - FLAGS_logtostderr = true; - - InitGoogleTest(&argc, argv); -#ifdef HAVE_LIB_GMOCK - InitGoogleMock(&argc, argv); -#endif - -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#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_custom_prefix_unittest.err")); - - FLAGS_logtostderr = false; - - TestBasename(); - TestBasenameAppendWhenNoTimestamp(); - TestTwoProcessesWrite(); - TestSymlink(); - TestExtension(); - TestWrapper(); - TestErrno(); - TestTruncate(); - TestCustomLoggerDeletionOnShutdown(); - - 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; - LOG(INFO) << "foo " << std::setw(10) << 1.0; - - { - google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR); - outer.stream() << "outer"; - - LOG(ERROR) << "inner"; - } - - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix"; - - if (check_counts) { - CHECK_EQ(base_num_infos + 15, LogMessage::num_messages(GLOG_INFO)); - CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING)); - CHECK_EQ(base_num_errors + 17, LogMessage::num_messages(GLOG_ERROR)); - } -} - -static void NoAllocNewHook() { - LOG(FATAL) << "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(PTR_TEST_VALUE); - 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); - -#if defined(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"); - -#if defined(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 LogMessageTime &logmsgtime, - const char* message, size_t message_len) { - errors.push_back( - ToString(severity, base_filename, line, logmsgtime, 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(GLOG_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() { -#if defined(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); - - int64* orig_ptr = new int64; - int64* ptr = DCHECK_NOTNULL(orig_ptr); - CHECK_EQ(ptr, orig_ptr); - delete orig_ptr; -} - -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(GLOG_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 (handle == INVALID_HANDLE_VALUE) { - // Finding no files is OK. - return; - } - do { - files->push_back(dirname + data.cFileName); - } while (FindNextFileA(handle, &data)); - BOOL result = FindClose(handle); - LOG_SYSRESULT(result != 0); -#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); - } -} - -//check string is in file (or is *NOT*, depending on optional checkInFileOrNot) -static void CheckFile(const string& name, const string& expected_string, const bool checkInFileOrNot = true) { - 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) { - char* first = strstr(buf, expected_string.c_str()); - //if first == NULL, not found. - //Terser than if (checkInFileOrNot && first != NULL || !check... - if (checkInFileOrNot != (first == NULL)) { - fclose(file); - return; - } - } - fclose(file); - LOG(FATAL) << "Did " << (checkInFileOrNot? "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 TestBasenameAppendWhenNoTimestamp() { - fprintf(stderr, "==== Test setting log file basename without timestamp and appending properly\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp"; - DeleteFiles(dest + "*"); - - ofstream out(dest.c_str()); - out << "test preexisting content" << endl; - out.close(); - - CheckFile(dest, "test preexisting content"); - - FLAGS_timestamp_in_logfile_name=false; - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base, appending to preexisting file"; - FlushLogFiles(GLOG_INFO); - FLAGS_timestamp_in_logfile_name=true; - - //if the logging overwrites the file instead of appending it will fail. - CheckFile(dest, "test preexisting content"); - CheckFile(dest, "message to new base, appending to preexisting file"); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -static void TestTwoProcessesWrite() { -// test only implemented for platforms with fork & wait; the actual implementation relies on flock -#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL) - fprintf(stderr, "==== Test setting log file basename and two processes writing - second should fail\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing"; - DeleteFiles(dest + "*"); - - //make both processes write into the same file (easier test) - FLAGS_timestamp_in_logfile_name=false; - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base, parent"; - FlushLogFiles(GLOG_INFO); - - pid_t pid = fork(); - CHECK_ERR(pid); - if (pid == 0) { - LOG(INFO) << "message to new base, child - should only appear on STDERR not on the file"; - ShutdownGoogleLogging(); //for children proc - exit(EXIT_SUCCESS); - } else if (pid > 0) { - wait(NULL); - } - FLAGS_timestamp_in_logfile_name=true; - - CheckFile(dest, "message to new base, parent"); - CheckFile(dest, "message to new base, child - should only appear on STDERR not on the file", false); - - // Release - LogToStderr(); - DeleteFiles(dest + "*"); -#endif -} - -static void TestSymlink() { -#ifndef GLOG_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, - size_t 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, uint64 limit, uint64 keep, - size_t dsize, size_t ksize, size_t expect) { - int fd; - CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)); - - const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!"; - const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr); - - // Fill the file with the requested data; first discard data, then kept data - size_t written = 0; - while (written < dsize) { - size_t bytes = min(dsize - written, discard_size); - CHECK_ERR(write(fd, discardstr, bytes)); - written += bytes; - } - written = 0; - while (written < ksize) { - size_t bytes = min(ksize - written, keep_size); - 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(static_cast(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 = static_cast(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; - size_t checked = 0; - while (checked < expect) { - size_t bytes = min(expect - checked, keep_size); - 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 + "/truncatefilecustom"; - - // 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(), 2U << 20U, 4U << 10U, 3U << 20U, 4U << 10U, - 4U << 10U); - - // 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(GLOG_OS_MACOSX) && !defined(GLOG_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(GLOG_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 -} - -struct RecordDeletionLogger : public base::Logger { - RecordDeletionLogger(bool* set_on_destruction, - base::Logger* wrapped_logger) : - set_on_destruction_(set_on_destruction), - wrapped_logger_(wrapped_logger) - { - *set_on_destruction_ = false; - } - virtual ~RecordDeletionLogger() { - *set_on_destruction_ = true; - } - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - size_t length) { - wrapped_logger_->Write(force_flush, timestamp, message, length); - } - virtual void Flush() { wrapped_logger_->Flush(); } - virtual uint32 LogSize() { return wrapped_logger_->LogSize(); } - private: - bool* set_on_destruction_; - base::Logger* wrapped_logger_; -}; - -static void TestCustomLoggerDeletionOnShutdown() { - bool custom_logger_deleted = false; - base::SetLogger(GLOG_INFO, - new RecordDeletionLogger(&custom_logger_deleted, - base::GetLogger(GLOG_INFO))); - EXPECT_TRUE(IsGoogleLoggingInitialized()); - ShutdownGoogleLogging(); - EXPECT_TRUE(custom_logger_deleted); - EXPECT_FALSE(IsGoogleLoggingInitialized()); -} - -_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: - size_t 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 LogMessageTime &logmsgtime, - 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, - logmsgtime, 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(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_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); - delete[] buf; - CHECK_EQ(msg, StrError(errcode)); - free(msg); -} - -// Simple routines to look at the sizes of generated code for LOG(FATAL) and -// CHECK(..) via objdump -/* -static void MyFatal() { - LOG(FATAL) << "Failed"; -} -static void MyCheck(bool a, bool b) { - CHECK_EQ(a, b); -} -*/ -#ifdef HAVE_LIB_GMOCK - -TEST(DVLog, Basic) { - ScopedMockLog log; - -#if defined(NDEBUG) - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); -#else - EXPECT_CALL(log, Log(GLOG_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(GLOG_WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version")); - - int severity = GLOG_WARNING; - LogAtLevel(severity, "function version"); - - severity = GLOG_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 = -#if defined(NDEBUG) - GLOG_ERROR; -#else - GLOG_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); -} - -TEST(LogMsgTime, gmtoff) { - /* - * Unit test for GMT offset API - * TODO: To properly test this API, we need a platform independent way to set time-zone. - * */ - google::LogMessage log_obj(__FILE__, __LINE__); - - long int nGmtOff = log_obj.getLogMessageTime().gmtoff(); - // GMT offset ranges from UTC-12:00 to UTC+14:00 - const long utc_min_offset = -43200; - const long utc_max_offset = 50400; - EXPECT_TRUE( (nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset) ); -} diff --git a/third_party/glog/src/logging_custom_prefix_unittest.err b/third_party/glog/src/logging_custom_prefix_unittest.err deleted file mode 100644 index ccd5ba9..0000000 --- a/third_party/glog/src/logging_custom_prefix_unittest.err +++ /dev/null @@ -1,308 +0,0 @@ -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -WARNING: Logging before InitGoogleLogging() is written to STDERR -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo bar 10 3.4 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0] -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 1 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 1 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 5, iteration 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 1 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if less than 3 every 2, iteration 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 2 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2] -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 3 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if less than 3 every 2, iteration 3 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 4 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 4 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4] -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 5 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 5 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 5, iteration 6 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 6 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6] -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 7 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 7 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 8 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8] -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 4, iteration 9 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 9 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log every 3, iteration 10 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Log if every 1, iteration 10 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if this -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] array -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] const array -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo 1000 1000 3e8 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] foo 1 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] inner -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] outer -no prefix -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo bar 10 3.400000 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: array -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: const array -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: ptr __PTRTEST__ -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: ptr __NULLP__ -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: foo 1000 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 on -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1 on -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 2 on -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_STRING: reported error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: reported error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_SINK: -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected info -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected warning -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported info -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported warning -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] LOG_TO_STRING: reported error -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left -EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left -WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Have 0 left -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_custom_prefix_unittest.cc:LINE] Message 3 diff --git a/third_party/glog/src/logging_striplog_test.sh b/third_party/glog/src/logging_striplog_test.sh deleted file mode 100755 index 73492bd..0000000 --- a/third_party/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/glog/src/logging_striptest10.cc b/third_party/glog/src/logging_striptest10.cc deleted file mode 100644 index f6e1078..0000000 --- a/third_party/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/glog/src/logging_striptest2.cc b/third_party/glog/src/logging_striptest2.cc deleted file mode 100644 index a64685c..0000000 --- a/third_party/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/glog/src/logging_striptest_main.cc b/third_party/glog/src/logging_striptest_main.cc deleted file mode 100644 index 27e1254..0000000 --- a/third_party/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 -#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/glog/src/logging_unittest.cc b/third_party/glog/src/logging_unittest.cc deleted file mode 100644 index 728b5fe..0000000 --- a/third_party/glog/src/logging_unittest.cc +++ /dev/null @@ -1,1477 +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.h" -#include "utilities.h" - -#include -#ifdef HAVE_GLOB_H -# include -#endif -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_SYS_WAIT_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "base/commandlineflags.h" -#include -#include -#include "googletest.h" - -DECLARE_string(log_backtrace_at); // logging.cc - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#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 TestVLogModule(); -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 TestBasenameAppendWhenNoTimestamp(); -static void TestTwoProcessesWrite(); -static void TestSymlink(); -static void TestExtension(); -static void TestWrapper(); -static void TestErrno(); -static void TestTruncate(); -static void TestCustomLoggerDeletionOnShutdown(); -static void TestLogPeriodically(); - -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; - FLAGS_timestamp_in_logfile_name = true; - - // 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(); - - EXPECT_FALSE(IsGoogleLoggingInitialized()); - - InitGoogleLogging(argv[0]); - - EXPECT_TRUE(IsGoogleLoggingInitialized()); - - RunSpecifiedBenchmarks(); - - FLAGS_logtostderr = true; - - InitGoogleTest(&argc, argv); -#ifdef HAVE_LIB_GMOCK - InitGoogleMock(&argc, argv); -#endif - -#ifdef HAVE_LIB_GFLAGS - ParseCommandLineFlags(&argc, &argv, true); -#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(); - TestVLogModule(); - 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; - - FLAGS_logtostdout = true; - FLAGS_stderrthreshold = NUM_SEVERITIES; - CaptureTestStdout(); - TestRawLogging(); - TestLoggingLevels(); - TestLogString(); - TestLogSink(); - TestLogToString(); - TestLogSinkWaitTillSent(); - TestCHECK(); - TestDCHECK(); - TestSTREQ(); - EXPECT_TRUE( - MungeAndDiffTestStdout(FLAGS_test_srcdir + "/src/logging_unittest.out")); - FLAGS_logtostdout = false; - - TestBasename(); - TestBasenameAppendWhenNoTimestamp(); - TestTwoProcessesWrite(); - TestSymlink(); - TestExtension(); - TestWrapper(); - TestErrno(); - TestTruncate(); - TestCustomLoggerDeletionOnShutdown(); - TestLogPeriodically(); - - 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; - LOG(INFO) << "foo " << std::setw(10) << 1.0; - - { - google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR); - outer.stream() << "outer"; - - LOG(ERROR) << "inner"; - } - - LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix"; - - if (check_counts) { - CHECK_EQ(base_num_infos + 15, LogMessage::num_messages(GLOG_INFO)); - CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING)); - CHECK_EQ(base_num_errors + 17, LogMessage::num_messages(GLOG_ERROR)); - } -} - -static void NoAllocNewHook() { - LOG(FATAL) << "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(PTR_TEST_VALUE); - 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); - -#if defined(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"); - -#if defined(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); -} - -int TestVlogHelper() { - if (VLOG_IS_ON(1)) { - return 1; - } - return 0; -} - -void TestVLogModule() { - int c = TestVlogHelper(); - EXPECT_EQ(0, c); - -#if defined(__GNUC__) - EXPECT_EQ(0, SetVLOGLevel("logging_unittest", 1)); - c = TestVlogHelper(); - EXPECT_EQ(1, c); -#endif -} - -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 LogMessageTime &logmsgtime, - const char* message, size_t message_len) { - errors.push_back( - ToString(severity, base_filename, line, logmsgtime, 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(GLOG_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() { -#if defined(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); - - int64* orig_ptr = new int64; - int64* ptr = DCHECK_NOTNULL(orig_ptr); - CHECK_EQ(ptr, orig_ptr); - delete orig_ptr; -} - -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(GLOG_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 (handle == INVALID_HANDLE_VALUE) { - // Finding no files is OK. - return; - } - do { - files->push_back(dirname + data.cFileName); - } while (FindNextFileA(handle, &data)); - BOOL result = FindClose(handle); - LOG_SYSRESULT(result != 0); -#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); - } -} - -//check string is in file (or is *NOT*, depending on optional checkInFileOrNot) -static void CheckFile(const string& name, const string& expected_string, const bool checkInFileOrNot = true) { - 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) { - char* first = strstr(buf, expected_string.c_str()); - //if first == NULL, not found. - //Terser than if (checkInFileOrNot && first != NULL || !check... - if (checkInFileOrNot != (first == NULL)) { - fclose(file); - return; - } - } - fclose(file); - LOG(FATAL) << "Did " << (checkInFileOrNot? "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 TestBasenameAppendWhenNoTimestamp() { - fprintf(stderr, "==== Test setting log file basename without timestamp and appending properly\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp"; - DeleteFiles(dest + "*"); - - ofstream out(dest.c_str()); - out << "test preexisting content" << endl; - out.close(); - - CheckFile(dest, "test preexisting content"); - - FLAGS_timestamp_in_logfile_name=false; - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base, appending to preexisting file"; - FlushLogFiles(GLOG_INFO); - FLAGS_timestamp_in_logfile_name=true; - - //if the logging overwrites the file instead of appending it will fail. - CheckFile(dest, "test preexisting content"); - CheckFile(dest, "message to new base, appending to preexisting file"); - - // Release file handle for the destination file to unlock the file in Windows. - LogToStderr(); - DeleteFiles(dest + "*"); -} - -static void TestTwoProcessesWrite() { -// test only implemented for platforms with fork & wait; the actual implementation relies on flock -#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL) - fprintf(stderr, "==== Test setting log file basename and two processes writing - second should fail\n"); - const string dest = FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing"; - DeleteFiles(dest + "*"); - - //make both processes write into the same file (easier test) - FLAGS_timestamp_in_logfile_name=false; - SetLogDestination(GLOG_INFO, dest.c_str()); - LOG(INFO) << "message to new base, parent"; - FlushLogFiles(GLOG_INFO); - - pid_t pid = fork(); - CHECK_ERR(pid); - if (pid == 0) { - LOG(INFO) << "message to new base, child - should only appear on STDERR not on the file"; - ShutdownGoogleLogging(); //for children proc - exit(EXIT_SUCCESS); - } else if (pid > 0) { - wait(NULL); - } - FLAGS_timestamp_in_logfile_name=true; - - CheckFile(dest, "message to new base, parent"); - CheckFile(dest, "message to new base, child - should only appear on STDERR not on the file", false); - - // Release - LogToStderr(); - DeleteFiles(dest + "*"); -#endif -} - -static void TestSymlink() { -#ifndef GLOG_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, - size_t 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, uint64 limit, uint64 keep, - size_t dsize, size_t ksize, size_t expect) { - int fd; - CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)); - - const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!"; - const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr); - - // Fill the file with the requested data; first discard data, then kept data - size_t written = 0; - while (written < dsize) { - size_t bytes = min(dsize - written, discard_size); - CHECK_ERR(write(fd, discardstr, bytes)); - written += bytes; - } - written = 0; - while (written < ksize) { - size_t bytes = min(ksize - written, keep_size); - 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(static_cast(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 = static_cast(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; - size_t checked = 0; - while (checked < expect) { - size_t bytes = min(expect - checked, keep_size); - 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(), 2U << 20U, 4U << 10U, 3U << 20U, 4U << 10U, - 4U << 10U); - - // 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(GLOG_OS_MACOSX) && !defined(GLOG_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(GLOG_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 -} - -struct RecordDeletionLogger : public base::Logger { - RecordDeletionLogger(bool* set_on_destruction, - base::Logger* wrapped_logger) : - set_on_destruction_(set_on_destruction), - wrapped_logger_(wrapped_logger) - { - *set_on_destruction_ = false; - } - virtual ~RecordDeletionLogger() { - *set_on_destruction_ = true; - } - virtual void Write(bool force_flush, - time_t timestamp, - const char* message, - size_t length) { - wrapped_logger_->Write(force_flush, timestamp, message, length); - } - virtual void Flush() { wrapped_logger_->Flush(); } - virtual uint32 LogSize() { return wrapped_logger_->LogSize(); } - private: - bool* set_on_destruction_; - base::Logger* wrapped_logger_; -}; - -static void TestCustomLoggerDeletionOnShutdown() { - bool custom_logger_deleted = false; - base::SetLogger(GLOG_INFO, - new RecordDeletionLogger(&custom_logger_deleted, - base::GetLogger(GLOG_INFO))); - EXPECT_TRUE(IsGoogleLoggingInitialized()); - ShutdownGoogleLogging(); - EXPECT_TRUE(custom_logger_deleted); - EXPECT_FALSE(IsGoogleLoggingInitialized()); -} - -namespace LogTimes { -// Log a "message" every 10ms, 10 times. These numbers are nice compromise -// between total running time of 100ms and the period of 10ms. The period is -// large enough such that any CPU and OS scheduling variation shouldn't affect -// the results from the ideal case by more than 5% (500us or 0.5ms) -GLOG_CONSTEXPR int64_t LOG_PERIOD_NS = 10000000; // 10ms -GLOG_CONSTEXPR int64_t LOG_PERIOD_TOL_NS = 500000; // 500us - -// Set an upper limit for the number of times the stream operator can be -// called. Make sure not to exceed this number of times the stream operator is -// called, since it is also the array size and will be indexed by the stream -// operator. -GLOG_CONSTEXPR size_t MAX_CALLS = 10; -} // namespace LogTimes - -#if defined(HAVE_CXX11_CHRONO) && __cplusplus >= 201103L -struct LogTimeRecorder { - LogTimeRecorder() : m_streamTimes(0) {} - size_t m_streamTimes; - std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS]; -}; -// The stream operator is called by LOG_EVERY_T every time a logging event -// occurs. Make sure to save the times for each call as they will be used later -// to verify the time delta between each call. -std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) { - t.m_callTimes[t.m_streamTimes++] = std::chrono::steady_clock::now(); - return stream; -} -// get elapsed time in nanoseconds -int64 elapsedTime_ns(const std::chrono::steady_clock::time_point& begin, - const std::chrono::steady_clock::time_point& end) { - return std::chrono::duration_cast((end - begin)) - .count(); -} -#elif defined(GLOG_OS_WINDOWS) -struct LogTimeRecorder { - LogTimeRecorder() : m_streamTimes(0) {} - size_t m_streamTimes; - LARGE_INTEGER m_callTimes[LogTimes::MAX_CALLS]; -}; -std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) { - QueryPerformanceCounter(&t.m_callTimes[t.m_streamTimes++]); - return stream; -} -// get elapsed time in nanoseconds -int64 elapsedTime_ns(const LARGE_INTEGER& begin, const LARGE_INTEGER& end) { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - return (end.QuadPart - begin.QuadPart) * LONGLONG(1000000000) / freq.QuadPart; -} -#else -struct LogTimeRecorder { - LogTimeRecorder() : m_streamTimes(0) {} - size_t m_streamTimes; - timespec m_callTimes[LogTimes::MAX_CALLS]; -}; -std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) { - clock_gettime(CLOCK_MONOTONIC, &t.m_callTimes[t.m_streamTimes++]); - return stream; -} -// get elapsed time in nanoseconds -int64 elapsedTime_ns(const timespec& begin, const timespec& end) { - return (end.tv_sec - begin.tv_sec) * 1000000000 + - (end.tv_nsec - begin.tv_nsec); -} -#endif - -static void TestLogPeriodically() { - fprintf(stderr, "==== Test log periodically\n"); - - LogTimeRecorder timeLogger; - - GLOG_CONSTEXPR double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9; - - while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) { - LOG_EVERY_T(INFO, LOG_PERIOD_SEC) - << timeLogger << "Timed Message #" << timeLogger.m_streamTimes; - } - - // Calculate time between each call in nanoseconds for higher resolution to - // minimize error. - int64 nsBetweenCalls[LogTimes::MAX_CALLS - 1]; - for (size_t i = 1; i < LogTimes::MAX_CALLS; ++i) { - nsBetweenCalls[i - 1] = elapsedTime_ns( - timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]); - } - - for (size_t idx = 0; idx < LogTimes::MAX_CALLS - 1; ++idx) { - int64 time_ns = nsBetweenCalls[idx]; - EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS); - } -} - -_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: - size_t 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 LogMessageTime &logmsgtime, - 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, - logmsgtime, 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() { - // Clear global_messages here to make sure that this test case can be - // reentered - global_messages.clear(); - { 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(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_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); - delete[] buf; - CHECK_EQ(msg, StrError(errcode)); - free(msg); -} - -// Simple routines to look at the sizes of generated code for LOG(FATAL) and -// CHECK(..) via objdump -/* -static void MyFatal() { - LOG(FATAL) << "Failed"; -} -static void MyCheck(bool a, bool b) { - CHECK_EQ(a, b); -} -*/ -#ifdef HAVE_LIB_GMOCK - -TEST(DVLog, Basic) { - ScopedMockLog log; - -#if defined(NDEBUG) - // We are expecting that nothing is logged. - EXPECT_CALL(log, Log(_, _, _)).Times(0); -#else - EXPECT_CALL(log, Log(GLOG_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(GLOG_WARNING, StrNe(__FILE__), "function version")); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "macro version")); - - int severity = GLOG_WARNING; - LogAtLevel(severity, "function version"); - - severity = GLOG_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 = -#if defined(NDEBUG) - GLOG_ERROR; -#else - GLOG_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/glog/src/logging_unittest.err b/third_party/glog/src/logging_unittest.err deleted file mode 100644 index 21517cb..0000000 --- a/third_party/glog/src/logging_unittest.err +++ /dev/null @@ -1,308 +0,0 @@ -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WARNING: Logging before InitGoogleLogging() is written to STDERR -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2] -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8] -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] const array -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 1000 3e8 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] inner -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] outer -no prefix -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __PTRTEST__ -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__ -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long! -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0 -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0 -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK: -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 diff --git a/third_party/glog/src/logging_unittest.out b/third_party/glog/src/logging_unittest.out deleted file mode 100644 index 18795e1..0000000 --- a/third_party/glog/src/logging_unittest.out +++ /dev/null @@ -1,150 +0,0 @@ -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING: LOG_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK: -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING: LOG_TO_STRING: collected error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2 -IYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WYEARDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3 diff --git a/third_party/glog/src/mock-log.h b/third_party/glog/src/mock-log.h deleted file mode 100644 index bdfb3c5..0000000 --- a/third_party/glog/src/mock-log.h +++ /dev/null @@ -1,156 +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 - -_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. - ~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 LogMessageTime & /*logmsgtime*/, - 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/glog/src/mock-log_unittest.cc b/third_party/glog/src/mock-log_unittest.cc deleted file mode 100644 index b9bef4e..0000000 --- a/third_party/glog/src/mock-log_unittest.cc +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2022, 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::GLOG_ERROR; -using GOOGLE_NAMESPACE::GLOG_INFO; -using GOOGLE_NAMESPACE::GLOG_WARNING; -using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog; -using std::string; -using testing::_; -using testing::EndsWith; -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(GLOG_WARNING, EndsWith("mock-log_unittest.cc"), "Fishy.")); - EXPECT_CALL(log, Log(GLOG_INFO, _, "Working...")) - .Times(2); - EXPECT_CALL(log, Log(GLOG_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(GLOG_INFO, __FILE__, "Logging a branch...")) - .WillOnce(InvokeWithoutArgs(LogTree)); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the whole tree...")) - .WillOnce(InvokeWithoutArgs(LogForest)); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest.")); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest..")); - EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "Logging the entire forest...")); - LogBranch(); -} - -} // namespace - -int main(int argc, char **argv) { - GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]); - testing::InitGoogleTest(&argc, argv); - testing::InitGoogleMock(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt b/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt deleted file mode 100644 index 5fcfe7f..0000000 --- a/third_party/glog/src/package_config_unittest/working_config/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required (VERSION 3.16) -project (glog_package_config LANGUAGES CXX) - -find_package (glog REQUIRED NO_MODULE) - -add_executable (glog_package_config glog_package_config.cc) - -target_link_libraries (glog_package_config PRIVATE glog::glog) diff --git a/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc b/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc deleted file mode 100644 index b7b5cf6..0000000 --- a/third_party/glog/src/package_config_unittest/working_config/glog_package_config.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int /*argc*/, char** argv) -{ - google::InitGoogleLogging(argv[0]); -} diff --git a/third_party/glog/src/raw_logging.cc b/third_party/glog/src/raw_logging.cc deleted file mode 100644 index 4315983..0000000 --- a/third_party/glog/src/raw_logging.cc +++ /dev/null @@ -1,178 +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 // To pick up flag settings etc. -#include -#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)) && (!(defined(GLOG_OS_MACOSX))) -# 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_ - -#if defined(__GNUC__) -#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck) \ - __attribute__((format(archetype, stringIndex, firstToCheck))) -#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex) \ - __attribute__((format_arg(stringIndex))) -#else -#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck) -#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex) -#endif - -// 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. -GLOG_ATTRIBUTE_FORMAT(printf, 3, 4) -static bool DoRawLog(char** buf, size_t* size, const char* format, ...) { - va_list ap; - va_start(ap, format); - int n = vsnprintf(*buf, *size, format, ap); - va_end(ap); - if (n < 0 || static_cast(n) > *size) return false; - *size -= static_cast(n); - *buf += n; - return true; -} - -// Helper for RawLog__ below. -inline static bool VADoRawLog(char** buf, size_t* size, - const char* format, va_list ap) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif - int n = vsnprintf(*buf, *size, format, ap); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - if (n < 0 || static_cast(n) > *size) return false; - *size -= static_cast(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' - -GLOG_ATTRIBUTE_FORMAT(printf, 4, 5) -void RawLog__(LogSeverity severity, const char* file, int line, - const char* format, ...) { - if (!(FLAGS_logtostdout || FLAGS_logtostderr || - severity >= FLAGS_stderrthreshold || FLAGS_alsologtostderr || - !IsGoogleLoggingInitialized())) { - return; // this stderr log message is suppressed - } - // can't call localtime_r here: it can allocate - char buffer[kLogBufSize]; - char* buf = buffer; - size_t size = sizeof(buffer); - - // NOTE: this format should match the specification in base/logging.h - DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %5u %s:%d] RAW: ", - LogSeverityNames[severity][0], - 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 size_t 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/glog/src/signalhandler.cc b/third_party/glog/src/signalhandler.cc deleted file mode 100644 index ebe95b1..0000000 --- a/third_party/glog/src/signalhandler.cc +++ /dev/null @@ -1,409 +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 - -#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" }, -#if !defined(GLOG_OS_WINDOWS) - { SIGBUS, "SIGBUS" }, -#endif - { SIGTERM, "SIGTERM" }, -}; - -static bool kFailureSignalHandlerInstalled = false; - -#if !defined(GLOG_OS_WINDOWS) -// 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; - } -#else - (void)ucontext_in_void; -#endif - return NULL; -} -#endif - -// 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, size_t size) - : buffer_(buffer), - cursor_(buffer), - end_(buffer + size) { - } - - // Returns the number of bytes written in the buffer. - std::size_t num_bytes_written() const { return static_cast(cursor_ - buffer_); } - - // Appends string from "str" and updates the internal cursor. - void AppendString(const char* str) { - ptrdiff_t 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, unsigned radix) { - unsigned i = 0; - while (cursor_ + i < end_) { - const uint64 tmp = number % radix; - number /= radix; - cursor_[i] = static_cast(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, size_t 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, size_t 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(static_cast(time_in_sec), 10); - formatter.AppendString(" (unix time)"); - formatter.AppendString(" try \"date -d @"); - formatter.AppendUint64(static_cast(time_in_sec), 10); - formatter.AppendString("\" if you are using GNU date ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -// TODO(hamaji): Use signal instead of sigaction? -#ifdef HAVE_SIGACTION - -// 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(static_cast(signal_number), 10); - } - formatter.AppendString(" (@0x"); - formatter.AppendUint64(reinterpret_cast(siginfo->si_addr), 16); - formatter.AppendString(")"); - formatter.AppendString(" received by PID "); - formatter.AppendUint64(static_cast(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. - pthread_t id = pthread_self(); - formatter.AppendUint64( - reinterpret_cast(reinterpret_cast(id)), 16); - formatter.AppendString(") "); - // Only linux has the PID of the signal sender in si_pid. -#ifdef GLOG_OS_LINUX - formatter.AppendString("from PID "); - formatter.AppendUint64(static_cast(siginfo->si_pid), 10); - formatter.AppendString("; "); -#endif - formatter.AppendString("stack trace: ***\n"); - g_failure_writer(buf, formatter.num_bytes_written()); -} - -#endif // HAVE_SIGACTION - -// 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) { -#ifdef HAVE_SIGACTION - 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); -#elif defined(GLOG_OS_WINDOWS) - signal(signal_number, SIG_DFL); - raise(signal_number); -#endif -} - -// 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. -#if defined(GLOG_OS_WINDOWS) -void FailureSignalHandler(int signal_number) -#else -void FailureSignalHandler(int signal_number, - siginfo_t *signal_info, - void *ucontext) -#endif -{ - // 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(); - -#if !defined(GLOG_OS_WINDOWS) - // Get the program counter from ucontext. - void *pc = GetPC(ucontext); - DumpStackFrameInfo("PC: ", pc); -#endif - -#ifdef HAVE_STACKTRACE - // Get the stack traces. - void *stack[32]; - // +1 to exclude this function. - const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1); -# ifdef HAVE_SIGACTION - DumpSignalInfo(signal_number, signal_info); -# endif - // 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 - -namespace glog_internal_namespace_ { - -bool IsFailureSignalHandlerInstalled() { -#ifdef HAVE_SIGACTION - // TODO(andschwa): Return kFailureSignalHandlerInstalled? - struct sigaction sig_action; - memset(&sig_action, 0, sizeof(sig_action)); - sigemptyset(&sig_action.sa_mask); - sigaction(SIGABRT, NULL, &sig_action); - if (sig_action.sa_sigaction == &FailureSignalHandler) { - return true; - } -#elif defined(GLOG_OS_WINDOWS) - return kFailureSignalHandlerInstalled; -#endif // HAVE_SIGACTION - return false; -} - -} // namespace glog_internal_namespace_ - -void InstallFailureSignalHandler() { -#ifdef HAVE_SIGACTION - // 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)); - } - kFailureSignalHandlerInstalled = true; -#elif defined(GLOG_OS_WINDOWS) - for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { - CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler), - SIG_ERR); - } - kFailureSignalHandlerInstalled = true; -#endif // HAVE_SIGACTION -} - -void InstallFailureWriter(void (*writer)(const char* data, size_t size)) { -#if defined(HAVE_SIGACTION) || defined(GLOG_OS_WINDOWS) - g_failure_writer = writer; -#endif // HAVE_SIGACTION -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/signalhandler_unittest.cc b/third_party/glog/src/signalhandler_unittest.cc deleted file mode 100644 index c4c99cc..0000000 --- a/third_party/glog/src/signalhandler_unittest.cc +++ /dev/null @@ -1,113 +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" - -#if defined(HAVE_PTHREAD) -# include -#endif -#include -#include -#include -#include -#include - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -using namespace GOOGLE_NAMESPACE; - -static 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. - fprintf( - stderr, "0x%px is dying\n", - static_cast(reinterpret_cast(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; -} - -static void WriteToStdout(const char* data, size_t 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") { -#if defined(HAVE_PTHREAD) - pthread_t thread; - pthread_create(&thread, NULL, &DieInThread, NULL); - pthread_join(thread, NULL); -#else - fprintf(stderr, "no pthread\n"); - return 1; -#endif - } else if (command == "dump_to_stdout") { - InstallFailureWriter(WriteToStdout); - abort(); - } else if (command == "installed") { - fprintf(stderr, "signal handler installed: %s\n", - IsFailureSignalHandlerInstalled() ? "true" : "false"); - } else { - // Tell the shell script - puts("OK"); - } -#endif - return 0; -} diff --git a/third_party/glog/src/signalhandler_unittest.sh b/third_party/glog/src/signalhandler_unittest.sh deleted file mode 100755 index 265cd45..0000000 --- a/third_party/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/glog/src/stacktrace.h b/third_party/glog/src/stacktrace.h deleted file mode 100644 index 55b98b2..0000000 --- a/third_party/glog/src/stacktrace.h +++ /dev/null @@ -1,61 +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" -#include - -_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. -GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_STACKTRACE_H_ diff --git a/third_party/glog/src/stacktrace_generic-inl.h b/third_party/glog/src/stacktrace_generic-inl.h deleted file mode 100644 index 96397d0..0000000 --- a/third_party/glog/src/stacktrace_generic-inl.h +++ /dev/null @@ -1,62 +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/glog/src/stacktrace_libunwind-inl.h b/third_party/glog/src/stacktrace_libunwind-inl.h deleted file mode 100644 index 0b20d23..0000000 --- a/third_party/glog/src/stacktrace_libunwind-inl.h +++ /dev/null @@ -1,93 +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 -#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. -// We can use the GCC __thread syntax here since libunwind is not supported on -// Windows. -static __thread bool g_tl_entered; // Initialized to 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 (g_tl_entered) { - return 0; - } - g_tl_entered = true; - - 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, reinterpret_cast(&ip)); - if (ret < 0) { - break; - } - if (skip_count > 0) { - skip_count--; - } else { - result[n++] = ip; - } - ret = unw_step(&cursor); - if (ret <= 0) { - break; - } - } - - g_tl_entered = false; - return n; -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_powerpc-inl.h b/third_party/glog/src/stacktrace_powerpc-inl.h deleted file mode 100644 index 911970c..0000000 --- a/third_party/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 = static_cast(*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(__linux__)) && defined(__PPC64__)) - // This check is in case the compiler doesn't define _CALL_AIX/etc. - result[n++] = *(sp+2); -#elif defined(__linux) || defined(__OpenBSD__) - // 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/glog/src/stacktrace_unittest.cc b/third_party/glog/src/stacktrace_unittest.cc deleted file mode 100644 index 2d07c5f..0000000 --- a/third_party/glog/src/stacktrace_unittest.cc +++ /dev/null @@ -1,239 +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 -#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__ - -//-----------------------------------------------------------------------// - -static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range) -{ - CHECK_GE(ret_addr, range.start); - CHECK_LE(ret_addr, range.end); -} - -//-----------------------------------------------------------------------// - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wgnu-label-as-value" -#endif - -void ATTRIBUTE_NOINLINE CheckStackTrace(int); -static 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]); - } - - union { - void (*p1)(int); - void* p2; - } p = {&CheckStackTrace}; - - printf("CheckStackTrace() addr: %p\n", p.p2); - 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. */ -static 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); -} -static 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); -} -static 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); -} -static 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); -} - -#ifndef __GNUC__ -// On non-GNU environment, we use the address of `CheckStackTrace` to -// guess the address range of this function. This guess is wrong for -// non-static function on Windows. This is probably because -// `&CheckStackTrace` returns the address of a trampoline like PLT, -// not the actual address of `CheckStackTrace`. -// See https://github.com/google/glog/issues/421 for the detail. -static -#endif -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); -} - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -//-----------------------------------------------------------------------// - -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/glog/src/stacktrace_unwind-inl.h b/third_party/glog/src/stacktrace_unwind-inl.h deleted file mode 100644 index fbb5f98..0000000 --- a/third_party/glog/src/stacktrace_unwind-inl.h +++ /dev/null @@ -1,106 +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 - -#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 = static_cast(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/glog/src/stacktrace_windows-inl.h b/third_party/glog/src/stacktrace_windows-inl.h deleted file mode 100644 index e6af561..0000000 --- a/third_party/glog/src/stacktrace_windows-inl.h +++ /dev/null @@ -1,50 +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. -// -// Author: Andrew Schwartzmeyer -// -// Windows implementation - just use CaptureStackBackTrace - -#include "config.h" -#include "port.h" -#include "stacktrace.h" -#include - -_START_GOOGLE_NAMESPACE_ - -int GetStackTrace(void** result, int max_depth, int skip_count) { - if (max_depth > 64) { - max_depth = 64; - } - skip_count++; // we want to skip the current frame as well - // This API is thread-safe (moreover it walks only the current thread). - return CaptureStackBackTrace(static_cast(skip_count), static_cast(max_depth), result, NULL); -} - -_END_GOOGLE_NAMESPACE_ diff --git a/third_party/glog/src/stacktrace_x86-inl.h b/third_party/glog/src/stacktrace_x86-inl.h deleted file mode 100644 index b12adc1..0000000 --- a/third_party/glog/src/stacktrace_x86-inl.h +++ /dev/null @@ -1,147 +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(GLOG_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 = static_cast(*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(GLOG_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 __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 -#define USE_BUILTIN_FRAME_ADDRESS -#endif -#endif - -#ifdef USE_BUILTIN_FRAME_ADDRESS - sp = reinterpret_cast(__builtin_frame_address(0)); -#elif defined(__i386__) - // Stack frame format: - // sp[0] pointer to previous frame - // sp[1] caller address - // sp[2] first argument - // ... - sp = (void **)&result - 2; -#elif defined(__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/glog/src/stl_logging_unittest.cc b/third_party/glog/src/stl_logging_unittest.cc deleted file mode 100644 index 5ab2414..0000000 --- a/third_party/glog/src/stl_logging_unittest.cc +++ /dev/null @@ -1,207 +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 -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -// C++0x isn't enabled by default in GCC and libc++ does not have -// non-standard ext/* and tr1/unordered_*. -# if defined(_LIBCPP_VERSION) -# ifndef GLOG_STL_LOGGING_FOR_UNORDERED -# define GLOG_STL_LOGGING_FOR_UNORDERED -# endif -# else -# ifndef GLOG_STL_LOGGING_FOR_EXT_HASH -# define GLOG_STL_LOGGING_FOR_EXT_HASH -# endif -# ifndef GLOG_STL_LOGGING_FOR_EXT_SLIST -# define GLOG_STL_LOGGING_FOR_EXT_SLIST -# endif -# ifndef GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# define GLOG_STL_LOGGING_FOR_TR1_UNORDERED -# endif -# endif -#endif - -#include -#include -#include "googletest.h" - -using namespace std; -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH -using namespace __gnu_cxx; -#endif - -struct user_hash { - size_t operator()(int x) const { return static_cast(x); } -}; - -static 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 GLOG_STL_LOGGING_FOR_EXT_HASH - { - // 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().size(), 8); - EXPECT_TRUE(ss.str().find("10") != string::npos); - EXPECT_TRUE(ss.str().find("20") != string::npos); - EXPECT_TRUE(ss.str().find("30") != string::npos); - hash_set copied_hs(hs); - CHECK_EQ(hs, copied_hs); // This must compile. - } -#endif - -#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH - { - // 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().size(), 35); - EXPECT_TRUE(ss.str().find("(10, ten)") != string::npos); - EXPECT_TRUE(ss.str().find("(20, twenty)") != string::npos); - EXPECT_TRUE(ss.str().find("(30, thirty)") != string::npos); - 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 += ' '; - const size_t buf_size = 256; - char buf[buf_size]; - snprintf(buf, buf_size, "%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 GLOG_STL_LOGGING_FOR_EXT_HASH - { - // 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().size(), 8); - EXPECT_TRUE(ss.str().find("10") != string::npos); - EXPECT_TRUE(ss.str().find("20") != string::npos); - EXPECT_TRUE(ss.str().find("30") != string::npos); - 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/glog/src/symbolize.cc b/third_party/glog/src/symbolize.cc deleted file mode 100644 index d979b82..0000000 --- a/third_party/glog/src/symbolize.cc +++ /dev/null @@ -1,955 +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. -// -// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE -// macro to add platform specific defines (e.g. GLOG_OS_OPENBSD). - -#ifdef GLOG_BUILD_CONFIG_INCLUDE -#include GLOG_BUILD_CONFIG_INCLUDE -#endif // GLOG_BUILD_CONFIG_INCLUDE - -#include "utilities.h" - -#if defined(HAVE_SYMBOLIZE) - -#include - -#include -#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; -} - -static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback = - NULL; -void InstallSymbolizeOpenObjectFileCallback( - SymbolizeOpenObjectFileCallback callback) { - g_symbolize_open_object_file_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 <= static_cast(out_size)) { // +1 for '\0'. - SAFE_ASSERT(len < sizeof(demangled)); - memmove(out, demangled, len + 1); - } - } -} - -_END_GOOGLE_NAMESPACE_ - -#if defined(__ELF__) - -#if defined(HAVE_DLFCN_H) -#include -#endif -#if defined(GLOG_OS_OPENBSD) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "symbolize.h" -#include "config.h" -#include - -// 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 "offset" in the file pointed by 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 ReadFromOffset(const int fd, void *buf, const size_t count, - const size_t offset) { - SAFE_ASSERT(fd >= 0); - SAFE_ASSERT(count <= static_cast(std::numeric_limits::max())); - char *buf0 = reinterpret_cast(buf); - size_t num_bytes = 0; - while (num_bytes < count) { - ssize_t len; - NO_INTR(len = pread(fd, buf0 + num_bytes, count - num_bytes, - static_cast(offset + num_bytes))); - if (len < 0) { // There was an error other than EINTR. - return -1; - } - if (len == 0) { // Reached EOF. - break; - } - num_bytes += static_cast(len); - } - SAFE_ASSERT(num_bytes <= count); - return static_cast(num_bytes); -} - -// 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 size_t offset) { - ssize_t len = ReadFromOffset(fd, buf, count, offset); - return static_cast(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 size_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 (size_t i = 0; i < sh_num;) { - const size_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); - const size_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])); - if (len == -1) { - return false; - } - SAFE_ASSERT(static_cast(len) % sizeof(buf[0]) == 0); - const size_t num_headers_in_buf = static_cast(len) / sizeof(buf[0]); - SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); - for (size_t 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; - size_t shstrtab_offset = - (elf_header.e_shoff + static_cast(elf_header.e_shentsize) * - static_cast(elf_header.e_shstrndx)); - if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { - return false; - } - - for (size_t i = 0; i < elf_header.e_shnum; ++i) { - size_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; - } - size_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 (static_cast(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, size_t out_size, - uint64_t symbol_offset, const ElfW(Shdr) *strtab, - const ElfW(Shdr) *symtab) { - if (symtab == NULL) { - return false; - } - const size_t num_symbols = symtab->sh_size / symtab->sh_entsize; - for (unsigned i = 0; i < num_symbols;) { - size_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 defined(__WORDSIZE) && __WORDSIZE == 64 - const size_t NUM_SYMBOLS = 32U; -#else - const size_t NUM_SYMBOLS = 64U; -#endif - - // Read at most NUM_SYMBOLS symbols at once to save read() calls. - ElfW(Sym) buf[NUM_SYMBOLS]; - size_t num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i); - const ssize_t len = - ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset); - SAFE_ASSERT(static_cast(len) % sizeof(buf[0]) == 0); - const size_t num_symbols_in_buf = static_cast(len) / sizeof(buf[0]); - SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read); - for (unsigned 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) { - memset(out, 0, out_size); - 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, - size_t out_size, - uint64_t base_address) { - // Read the ELF header. - ElfW(Ehdr) elf_header; - if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { - return false; - } - - ElfW(Shdr) symtab, strtab; - - // Consult a regular symbol table first. - if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, - SHT_SYMTAB, &symtab)) { - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, base_address, &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)) { - if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + - symtab.sh_link * sizeof(symtab))) { - return false; - } - if (FindSymbol(pc, fd, out, out_size, base_address, &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) { - close(fd_); - } - } - int get() { return fd_; } - - private: - 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, size_t buf_len, size_t offset) - : fd_(fd), - buf_(buf), - buf_len_(buf_len), - offset_(offset), - 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 = ReadFromOffset(fd_, buf_, buf_len_, offset_); - if (num_bytes <= 0) { // EOF or error. - return false; - } - offset_ += static_cast(num_bytes); - 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 size_t incomplete_line_length = static_cast(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 size_t capacity_left = buf_len_ - incomplete_line_length; - const ssize_t num_bytes = - ReadFromOffset(fd_, append_pos, capacity_left, offset_); - if (num_bytes <= 0) { // EOF or error. - return false; - } - offset_ += static_cast(num_bytes); - 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: - LineReader(const LineReader &); - void operator=(const LineReader&); - - char *FindLineFeed() { - return reinterpret_cast(memchr(bol_, '\n', static_cast(eod_ - bol_))); - } - - bool BufferIsEmpty() { - return buf_ == eod_; - } - - bool HasCompleteLine() { - return !BufferIsEmpty() && FindLineFeed() != NULL; - } - - const int fd_; - char * const buf_; - const size_t buf_len_; - size_t offset_; - 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 << 4U) | (ch < 'A' ? static_cast(ch - '0') : (ch & 0xF) + 9U); - } else { // Encountered the first non-hex character. - break; - } - } - SAFE_ASSERT(p <= end); - return const_cast(p); -} - -// Searches for the object file (from /proc/self/maps) that contains -// the specified pc. If found, sets |start_address| to the start address -// of where this object file is mapped in memory, sets the module base -// address into |base_address|, copies the object file name into -// |out_file_name|, and attempts to open the object file. If the object -// file is opened successfully, returns the file descriptor. Otherwise, -// returns -1. |out_file_name_size| is the size of the file name buffer -// (including the null-terminator). -static ATTRIBUTE_NOINLINE int -OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, - uint64_t &start_address, - uint64_t &base_address, - char *out_file_name, - size_t out_file_name_size) { - int object_fd; - - 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; - } - - int mem_fd; - NO_INTR(mem_fd = open("/proc/self/mem", O_RDONLY)); - FileDescriptor wrapped_mem_fd(mem_fd); - if (wrapped_mem_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 - unsigned num_maps = 0; - LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0); - while (true) { - num_maps++; - 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 ' '. - - // 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. - } - - // Determine the base address by reading ELF headers in process memory. - ElfW(Ehdr) ehdr; - // Skip non-readable maps. - if (flags_start[0] == 'r' && - ReadFromOffsetExact(mem_fd, &ehdr, sizeof(ElfW(Ehdr)), start_address) && - memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) { - switch (ehdr.e_type) { - case ET_EXEC: - base_address = 0; - break; - case ET_DYN: - // Find the segment containing file offset 0. This will correspond - // to the ELF header that we just read. Normally this will have - // virtual address 0, but this is not guaranteed. We must subtract - // the virtual address from the address where the ELF header was - // mapped to get the base address. - // - // If we fail to find a segment for file offset 0, use the address - // of the ELF header as the base address. - base_address = start_address; - for (unsigned i = 0; i != ehdr.e_phnum; ++i) { - ElfW(Phdr) phdr; - if (ReadFromOffsetExact( - mem_fd, &phdr, sizeof(phdr), - start_address + ehdr.e_phoff + i * sizeof(phdr)) && - phdr.p_type == PT_LOAD && phdr.p_offset == 0) { - base_address = start_address - phdr.p_vaddr; - break; - } - } - break; - default: - // ET_REL or ET_CORE. These aren't directly executable, so they don't - // affect the base address. - break; - } - } - - // Check start and end addresses. - if (!(start_address <= pc && pc < end_address)) { - continue; // We skip this map. PC isn't in this map. - } - - // Check flags. We are only interested in "r*x" maps. - if (flags_start[0] != 'r' || flags_start[2] != 'x') { - continue; // We skip this map. - } - ++cursor; // Skip ' '. - - // Read file offset. - uint64_t file_offset; - cursor = GetHex(cursor, eol, &file_offset); - if (cursor == eol || *cursor != ' ') { - return -1; // Malformed line. - } - ++cursor; // Skip ' '. - - // Skip to file name. "cursor" now points to dev. We need to - // skip at least two spaces for dev and inode. - int num_spaces = 0; - while (cursor < eol) { - if (*cursor == ' ') { - ++num_spaces; - } else if (num_spaces >= 2) { - // The first non-space character after skipping two 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) { - // Failed to open object file. Copy the object file name to - // |out_file_name|. - strncpy(out_file_name, cursor, out_file_name_size); - // Making sure |out_file_name| is always null-terminated. - out_file_name[out_file_name_size - 1] = '\0'; - return -1; - } - return object_fd; - } -} - -// POSIX doesn't define any async-signal safe function for converting -// an integer to ASCII. We'll have to define our own version. -// itoa_r() converts an (unsigned) integer to ASCII. It returns "buf", if the -// conversion was successful or NULL otherwise. It never writes more than "sz" -// bytes. Output will be truncated as needed, and a NUL character is always -// appended. -// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. -static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) { - // Make sure we can write at least one NUL byte. - size_t n = 1; - if (n > sz) { - return NULL; - } - - if (base < 2 || base > 16) { - buf[0] = '\000'; - return NULL; - } - - char *start = buf; - - // Loop until we have converted the entire number. Output at least one - // character (i.e. '0'). - char *ptr = start; - do { - // Make sure there is still enough space left in our output buffer. - if (++n > sz) { - buf[0] = '\000'; - return NULL; - } - - // Output the next digit. - *ptr++ = "0123456789abcdef"[i % base]; - i /= base; - - if (padding > 0) { - padding--; - } - } while (i > 0 || padding > 0); - - // Terminate the output with a NUL character. - *ptr = '\000'; - - // Conversion to ASCII actually resulted in the digits being in reverse - // order. We can't easily generate them in forward order, as we can't tell - // the number of characters needed until we are done converting. - // So, now, we reverse the string (except for the possible "-" sign). - while (--ptr > start) { - char ch = *ptr; - *ptr = *start; - *start++ = ch; - } - return buf; -} - -// Safely appends string |source| to string |dest|. Never writes past the -// buffer size |dest_size| and guarantees that |dest| is null-terminated. -static void SafeAppendString(const char* source, char* dest, size_t dest_size) { - size_t dest_string_length = strlen(dest); - SAFE_ASSERT(dest_string_length < dest_size); - dest += dest_string_length; - dest_size -= dest_string_length; - strncpy(dest, source, dest_size); - // Making sure |dest| is always null-terminated. - dest[dest_size - 1] = '\0'; -} - -// Converts a 64-bit value into a hex string, and safely appends it to |dest|. -// Never writes past the buffer size |dest_size| and guarantees that |dest| is -// null-terminated. -static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) { - // 64-bit numbers in hex can have up to 16 digits. - char buf[17] = {'\0'}; - SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size); -} - -// 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, - size_t out_size) { - uint64_t pc0 = reinterpret_cast(pc); - uint64_t start_address = 0; - uint64_t base_address = 0; - int object_fd = -1; - - if (out_size < 1) { - return false; - } - out[0] = '\0'; - SafeAppendString("(", out, out_size); - - if (g_symbolize_open_object_file_callback) { - object_fd = g_symbolize_open_object_file_callback(pc0, start_address, - base_address, out + 1, - out_size - 1); - } else { - object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address, - base_address, - out + 1, - out_size - 1); - } - - FileDescriptor wrapped_object_fd(object_fd); - -#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES) - { -#else - // Check whether a file name was returned. - if (object_fd < 0) { -#endif - if (out[1]) { - // The object file containing PC was determined successfully however the - // object file was not opened successfully. This is still considered - // success because the object file name and offset are known and tools - // like asan_symbolize.py can be used for the symbolization. - out[out_size - 1] = '\0'; // Making sure |out| is always null-terminated. - SafeAppendString("+0x", out, out_size); - SafeAppendHexNumber(pc0 - base_address, out, out_size); - SafeAppendString(")", out, out_size); - return true; - } - // Failed to determine the object file containing PC. Bail out. - return false; - } - 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_t 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 += static_cast(num_bytes_written); - out_size -= static_cast(num_bytes_written); - } - } - if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, - out, out_size, base_address)) { - if (out[1] && !g_symbolize_callback) { - // The object file containing PC was opened successfully however the - // symbol was not found. The object may have been stripped. This is still - // considered success because the object file name and offset are known - // and tools like asan_symbolize.py can be used for the symbolization. - out[out_size - 1] = '\0'; // Making sure |out| is always null-terminated. - SafeAppendString("+0x", out, out_size); - SafeAppendHexNumber(pc0 - base_address, out, out_size); - SafeAppendString(")", out, out_size); - return true; - } - return false; - } - - // Symbolization succeeded. Now we try to demangle the symbol. - DemangleInplace(out, out_size); - return true; -} - -_END_GOOGLE_NAMESPACE_ - -#elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR) - -#include -#include - -_START_GOOGLE_NAMESPACE_ - -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - size_t out_size) { - Dl_info info; - if (dladdr(pc, &info)) { - if (info.dli_sname) { - if (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_ - -#elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN) - -#include -#include - -#ifdef _MSC_VER -#pragma comment(lib, "dbghelp") -#endif - -_START_GOOGLE_NAMESPACE_ - -class SymInitializer { -public: - HANDLE process; - bool ready; - SymInitializer() : process(NULL), ready(false) { - // Initialize the symbol handler. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx - process = GetCurrentProcess(); - // Defer symbol loading. - // We do not request undecorated symbols with SYMOPT_UNDNAME - // because the mangling library calls UnDecorateSymbolName. - SymSetOptions(SYMOPT_DEFERRED_LOADS); - if (SymInitialize(process, NULL, true)) { - ready = true; - } - } - ~SymInitializer() { - SymCleanup(process); - // We do not need to close `HANDLE process` because it's a "pseudo handle." - } -private: - SymInitializer(const SymInitializer&); - SymInitializer& operator=(const SymInitializer&); -}; - -static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, - int out_size) { - const static SymInitializer symInitializer; - if (!symInitializer.ready) { - return false; - } - // Resolve symbol information from address. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx - char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; - SYMBOL_INFO *symbol = reinterpret_cast(buf); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; - // We use the ANSI version to ensure the string type is always `char *`. - // This could break if a symbol has Unicode in it. - BOOL ret = SymFromAddr(symInitializer.process, - reinterpret_cast(pc), 0, symbol); - if (ret == 1 && static_cast(symbol->NameLen) < out_size) { - // `NameLen` does not include the null terminating character. - strncpy(out, symbol->Name, static_cast(symbol->NameLen) + 1); - out[static_cast(symbol->NameLen)] = '\0'; - // 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, size_t out_size) { - 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*/, size_t /*out_size*/) { - assert(0); - return false; -} - -_END_GOOGLE_NAMESPACE_ - -#endif diff --git a/third_party/glog/src/symbolize.h b/third_party/glog/src/symbolize.h deleted file mode 100644 index dcbb194..0000000 --- a/third_party/glog/src/symbolize.h +++ /dev/null @@ -1,159 +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 - -#ifdef HAVE_SYMBOLIZE - -#if defined(__ELF__) // defined by gcc -#if defined(__OpenBSD__) -#include -#else -#include -#endif - -#if !defined(ANDROID) -#include // For ElfW() macro. -#endif - -// For systems where SIZEOF_VOID_P is not defined, determine it -// based on __LP64__ (defined by gcc on 64-bit systems) -#if !defined(SIZEOF_VOID_P) -# if defined(__LP64__) -# define SIZEOF_VOID_P 8 -# else -# define SIZEOF_VOID_P 4 -# endif -#endif - -// 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_ - -// Restrictions on the callbacks that follow: -// - The callbacks must not use heaps but only use stacks. -// - The callbacks must be async-signal-safe. - -// 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_t relocation); -GLOG_EXPORT -void InstallSymbolizeCallback(SymbolizeCallback callback); - -// Installs a callback function, which will be called instead of -// OpenObjectFileContainingPcAndGetStartAddress. The callback is expected -// to searches for the object file (from /proc/self/maps) that contains -// the specified pc. If found, sets |start_address| to the start address -// of where this object file is mapped in memory, sets the module base -// address into |base_address|, copies the object file name into -// |out_file_name|, and attempts to open the object file. If the object -// file is opened successfully, returns the file descriptor. Otherwise, -// returns -1. |out_file_name_size| is the size of the file name buffer -// (including the null-terminator). -typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc, - uint64_t& start_address, - uint64_t& base_address, - char* out_file_name, - size_t out_file_name_size); -void InstallSymbolizeOpenObjectFileCallback( - SymbolizeOpenObjectFileCallback 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. -GLOG_EXPORT bool Symbolize(void* pc, char* out, size_t out_size); - -_END_GOOGLE_NAMESPACE_ - -#endif // BASE_SYMBOLIZE_H_ diff --git a/third_party/glog/src/symbolize_unittest.cc b/third_party/glog/src/symbolize_unittest.cc deleted file mode 100644 index a50e44a..0000000 --- a/third_party/glog/src/symbolize_unittest.cc +++ /dev/null @@ -1,447 +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 -#include - -#include "config.h" -#include -#include "googletest.h" -#include "symbolize.h" -#include "utilities.h" - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -using namespace std; -using namespace GOOGLE_NAMESPACE; - -#if defined(HAVE_STACKTRACE) - -#define always_inline - -#if defined(__ELF__) || defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN) -// 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; - } -} -#endif - -# if defined(__ELF__) - -// 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 defined(__i386__) && __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 - -// Make them C linkage to avoid mangled names. -extern "C" { -void nonstatic_func(); -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))); - - // The name of an internal linkage symbol is not specified; allow either a - // mangled or an unmangled name here. - const char *static_func_symbol = - TrySymbolize(reinterpret_cast(&static_func)); - -#if !defined(_MSC_VER) || !defined(NDEBUG) - CHECK(NULL != static_func_symbol); - EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 || - strcmp("static_func()", static_func_symbol) == 0); -#endif - - 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); -#if !defined(_MSC_VER) || !defined(NDEBUG) - EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func))); -#endif -} -#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; -} - -#ifdef __ppc64__ -// Symbolize stack consumption should be within 4kB. -const int kStackConsumptionUpperLimit = 4096; -#else -// Symbolize stack consumption should be within 2kB. -const int kStackConsumptionUpperLimit = 2048; -#endif - -TEST(Symbolize, SymbolizeStackConsumption) { - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption(reinterpret_cast(&nonstatic_func), - &stack_consumed); - EXPECT_STREQ("nonstatic_func", symbol); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); - - // The name of an internal linkage symbol is not specified; allow either a - // mangled or an unmangled name here. - symbol = SymbolizeStackConsumption(reinterpret_cast(&static_func), - &stack_consumed); - CHECK(NULL != symbol); - EXPECT_TRUE(strcmp("static_func", symbol) == 0 || - strcmp("static_func()", symbol) == 0); - EXPECT_GT(stack_consumed, 0); - EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit); -} - -#ifdef TEST_WITH_MODERN_GCC -TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) { - Foo::func(100); - int stack_consumed; - const char* symbol; - - symbol = SymbolizeStackConsumption(reinterpret_cast(&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() { - 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(); -void* ATTRIBUTE_NOINLINE non_inline_func() { - void *pc = NULL; -#ifdef TEST_X86_32_AND_64 - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); -#endif - return pc; -} - -static 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); - -#if !defined(_MSC_VER) || !defined(NDEBUG) - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "non_inline_func"); -#endif - cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl; -#endif -} - -static 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); - -#if !defined(_MSC_VER) || !defined(NDEBUG) - CHECK(symbol != NULL); - CHECK_STREQ(symbol, __FUNCTION__); -#endif - cout << "Test case TestWithPCInsideInlineFunction passed." << endl; -#endif -} -} - -// Test with a return address. -static void ATTRIBUTE_NOINLINE TestWithReturnAddress() { -#if defined(HAVE_ATTRIBUTE_NOINLINE) - void *return_address = __builtin_return_address(0); - const char *symbol = TrySymbolize(return_address); - -#if !defined(_MSC_VER) || !defined(NDEBUG) - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "main"); -#endif - cout << "Test case TestWithReturnAddress passed." << endl; -#endif -} - -# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN) - -#ifdef _MSC_VER -#include -#pragma intrinsic(_ReturnAddress) -#endif - -struct Foo { - static void func(int x); -}; - -__declspec(noinline) void Foo::func(int x) { - volatile int a = x; - ++a; -} - -TEST(Symbolize, SymbolizeWithDemangling) { - Foo::func(100); - const char* ret = TrySymbolize((void *)(&Foo::func)); - -#if defined(HAVE_DBGHELP) && !defined(NDEBUG) - EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret); -#endif -} - -__declspec(noinline) void TestWithReturnAddress() { - void *return_address = -#ifdef __GNUC__ // Cygwin and MinGW support - __builtin_return_address(0) -#else - _ReturnAddress() -#endif - ; - const char *symbol = TrySymbolize(return_address); -#if !defined(_MSC_VER) || !defined(NDEBUG) - CHECK(symbol != NULL); - CHECK_STREQ(symbol, "main"); -#endif - cout << "Test case TestWithReturnAddress passed." << endl; -} -# endif // __ELF__ -#endif // HAVE_STACKTRACE - -int main(int argc, char **argv) { - FLAGS_logtostderr = true; - InitGoogleLogging(argv[0]); - InitGoogleTest(&argc, argv); -#if defined(HAVE_SYMBOLIZE) && defined(HAVE_STACKTRACE) -# if defined(__ELF__) - // We don't want to get affected by the callback interface, that may be - // used to install some callback function at InitGoogle() time. - InstallSymbolizeCallback(NULL); - - TestWithPCInsideInlineFunction(); - TestWithPCInsideNonInlineFunction(); - TestWithReturnAddress(); - return RUN_ALL_TESTS(); -# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN) - TestWithReturnAddress(); - return RUN_ALL_TESTS(); -# else // GLOG_OS_WINDOWS - printf("PASS (no symbolize_unittest support)\n"); - return 0; -# endif // __ELF__ -#else - printf("PASS (no symbolize support)\n"); - return 0; -#endif // HAVE_SYMBOLIZE -} diff --git a/third_party/glog/src/utilities.cc b/third_party/glog/src/utilities.cc deleted file mode 100644 index a332f1a..0000000 --- a/third_party/glog/src/utilities.cc +++ /dev/null @@ -1,402 +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 "config.h" -#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 -#ifdef HAVE_UNISTD_H -# include // For geteuid. -#endif -#ifdef HAVE_PWD_H -# include -#endif -#ifdef __ANDROID__ -#include -#endif - -#include "base/googleinit.h" - -using std::string; - -_START_GOOGLE_NAMESPACE_ - -static const char* g_program_invocation_short_name = NULL; - -bool IsGoogleLoggingInitialized() { - return g_program_invocation_short_name != NULL; -} - -_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. - } -#if defined(__ANDROID__) - // ANDROID_LOG_FATAL as fatal error occurred and now is dumping call stack. - __android_log_write(ANDROID_LOG_FATAL, - glog_internal_namespace_::ProgramInvocationShortName(), - data); -#endif -} - -static 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 - } -} - -#if defined(__GNUC__) -__attribute__((noreturn)) -#elif defined(_MSC_VER) -__declspec(noreturn) -#endif -static void DumpStackTraceAndExit() { - DumpStackTrace(1, DebugWriteToStderr, NULL); - - // TODO(hamaji): Use signal instead of sigaction? - if (IsFailureSignalHandlerInstalled()) { - // Set the default signal handler for SIGABRT, to avoid invoking our - // own signal handler installed by InstallFailureSignalHandler(). -#ifdef HAVE_SIGACTION - 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); -#elif defined(GLOG_OS_WINDOWS) - signal(SIGABRT, SIG_DFL); -#endif // HAVE_SIGACTION - } - - 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"; - } -} - -#ifdef GLOG_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*/) { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlong-long" -#endif -#define EPOCHFILETIME (116444736000000000ULL) - FILETIME ft; - ULARGE_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; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - 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 GLOG_OS_LINUX || defined GLOG_OS_MACOSX -#ifndef __NR_gettid -#ifdef GLOG_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) { -#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP)) - uint64_t tid64; - const int error = pthread_threadid_np(NULL, &tid64); - pid_t tid = error ? -1 : static_cast(tid64); -#else - pid_t tid = static_cast(syscall(__NR_gettid)); -#endif - 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 // GLOG_OS_LINUX || GLOG_OS_MACOSX - - // If gettid() could not be used, we use one of the following. -#if defined GLOG_OS_LINUX - return getpid(); // Linux: getpid returns thread ID when gettid is absent -#elif defined GLOG_OS_WINDOWS && !defined GLOG_OS_CYGWIN - return static_cast(GetCurrentThreadId()); -#elif defined(HAVE_PTHREAD) - // If none of the techniques above worked, we use pthread_self(). - return (pid_t)(uintptr_t)pthread_self(); -#else - return -1; -#endif -} - -const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef GLOG_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(GLOG_OS_WINDOWS) - const char* user = getenv("USERNAME"); -#else - const char* user = getenv("USER"); -#endif - if (user != NULL) { - g_my_user_name = user; - } else { -#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H) - struct passwd pwd; - struct passwd* result = NULL; - char buffer[1024] = {'\0'}; - uid_t uid = geteuid(); - int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result); - if (pwuid_res == 0 && result) { - g_my_user_name = pwd.pw_name; - } else { - snprintf(buffer, sizeof(buffer), "uid%d", uid); - g_my_user_name = buffer; - } -#endif - if (g_my_user_name.empty()) { - 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 GLOG_OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); -#endif - g_program_invocation_short_name = slash ? slash + 1 : argv0; - -#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 -# if 0 -// For include scanners which can't handle macro expansions. -# include "stacktrace_libunwind-inl.h" -# include "stacktrace_x86-inl.h" -# include "stacktrace_x86_64-inl.h" -# include "stacktrace_powerpc-inl.h" -# include "stacktrace_generic-inl.h" -# endif -#endif diff --git a/third_party/glog/src/utilities.h b/third_party/glog/src/utilities.h deleted file mode 100644 index 1f55eff..0000000 --- a/third_party/glog/src/utilities.h +++ /dev/null @@ -1,217 +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__ - -// 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 - -#include - -#if defined(GLOG_OS_WINDOWS) -# include "port.h" -#endif - -#include "config.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(). -// -// 4) The Windows API CaptureStackTrace. -// -// 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(HAVE__UNWIND_BACKTRACE) -# define STACKTRACE_H "stacktrace_unwind-inl.h" -#elif !defined(NO_FRAME_POINTER) -# if defined(__i386__) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_x86-inl.h" -# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 -# define STACKTRACE_H "stacktrace_powerpc-inl.h" -# elif defined(GLOG_OS_WINDOWS) -# define STACKTRACE_H "stacktrace_windows-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 - -#ifndef GLOG_NO_SYMBOLIZE_DETECTION -#ifndef HAVE_SYMBOLIZE -// defined by gcc -#if defined(__ELF__) && defined(GLOG_OS_LINUX) -# define HAVE_SYMBOLIZE -#elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR) -// Use dladdr to symbolize. -# define HAVE_SYMBOLIZE -#elif defined(GLOG_OS_WINDOWS) -// Use DbgHelp to symbolize -# define HAVE_SYMBOLIZE -#endif -#endif // !defined(HAVE_SYMBOLIZE) -#endif // !defined(GLOG_NO_SYMBOLIZE_DETECTION) - -#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 -#elif defined(GLOG_OS_WINDOWS) -# define ATTRIBUTE_NOINLINE __declspec(noinline) -# define HAVE_ATTRIBUTE_NOINLINE -#else -# define ATTRIBUTE_NOINLINE -#endif - -const char* ProgramInvocationShortName(); - -int64 CycleClock_Now(); - -int64 UsecToCycles(int64 usec); -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/glog/src/utilities_unittest.cc b/third_party/glog/src/utilities_unittest.cc deleted file mode 100644 index 93b1acd..0000000 --- a/third_party/glog/src/utilities_unittest.cc +++ /dev/null @@ -1,58 +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 - -#ifdef HAVE_LIB_GFLAGS -#include -using namespace GFLAGS_NAMESPACE; -#endif - -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/glog/src/vlog_is_on.cc b/third_party/glog/src/vlog_is_on.cc deleted file mode 100644 index e478a36..0000000 --- a/third_party/glog/src/vlog_is_on.cc +++ /dev/null @@ -1,293 +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 -#include -#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_ { - -// Used by logging_unittests.cc so can't make it static here. -GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len, - const char* str, size_t str_len); - -// 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. -GLOG_EXPORT 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_; - -// 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; -static SiteFlag* cached_site_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, static_cast(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; - size_t 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; - - SiteFlag** item_ptr = &cached_site_list; - SiteFlag* item = cached_site_list; - - // We traverse the list fully because the pattern can match several items - // from the list. - while (item) { - if (SafeFNMatch_(module_pattern, pattern_len, item->base_name, - item->base_len)) { - // Redirect the cached value to its module override. - item->level = &info->vlog_level; - *item_ptr = item->next; // Remove the item from the list. - } else { - item_ptr = &item->next; - } - item = *item_ptr; - } - } - } - 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__(SiteFlag* site_flag, int32* level_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 = level_default; - - // Get basename for file - const char* base = strrchr(fname, '/'); - -#ifdef _WIN32 - if (!base) { - base = strrchr(fname, '\\'); - } -#endif - - 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->level = site_flag_value; - // If VLOG flag has been cached to the default site pointer, - // we want to add to the cached list in order to invalidate in case - // SetVModule is called afterwards with new modules. - // The performance penalty here is neglible, because InitVLOG3__ is called - // once per site. - if (site_flag_value == level_default && !site_flag->base_name) { - site_flag->base_name = base; - site_flag->base_len = base_length; - site_flag->next = cached_site_list; - cached_site_list = site_flag; - } - } - - // 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/glog/src/windows/dirent.h b/third_party/glog/src/windows/dirent.h deleted file mode 100644 index 12cf00a..0000000 --- a/third_party/glog/src/windows/dirent.h +++ /dev/null @@ -1,1159 +0,0 @@ -/* - * Dirent interface for Microsoft Visual Studio - * - * Copyright (C) 1998-2019 Toni Ronkko - * This file is part of dirent. Dirent may be freely distributed - * under the MIT license. For all details and documentation, see - * https://github.com/tronkko/dirent - */ -#ifndef DIRENT_H -#define DIRENT_H - -/* Hide warnings about unreferenced local functions */ -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wunused-function" -#elif defined(_MSC_VER) -# pragma warning(disable:4505) -#elif defined(__GNUC__) -# pragma GCC diagnostic ignored "-Wunused-function" -#endif - -/* - * Include windows.h without Windows Sockets 1.1 to prevent conflicts with - * Windows Sockets 2.0. - */ -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Indicates that d_type field is available in dirent structure */ -#define _DIRENT_HAVE_D_TYPE - -/* Indicates that d_namlen field is available in dirent structure */ -#define _DIRENT_HAVE_D_NAMLEN - -/* Entries missing from MSVC 6.0 */ -#if !defined(FILE_ATTRIBUTE_DEVICE) -# define FILE_ATTRIBUTE_DEVICE 0x40 -#endif - -/* File type and permission flags for stat(), general mask */ -#if !defined(S_IFMT) -# define S_IFMT _S_IFMT -#endif - -/* Directory bit */ -#if !defined(S_IFDIR) -# define S_IFDIR _S_IFDIR -#endif - -/* Character device bit */ -#if !defined(S_IFCHR) -# define S_IFCHR _S_IFCHR -#endif - -/* Pipe bit */ -#if !defined(S_IFFIFO) -# define S_IFFIFO _S_IFFIFO -#endif - -/* Regular file bit */ -#if !defined(S_IFREG) -# define S_IFREG _S_IFREG -#endif - -/* Read permission */ -#if !defined(S_IREAD) -# define S_IREAD _S_IREAD -#endif - -/* Write permission */ -#if !defined(S_IWRITE) -# define S_IWRITE _S_IWRITE -#endif - -/* Execute permission */ -#if !defined(S_IEXEC) -# define S_IEXEC _S_IEXEC -#endif - -/* Pipe */ -#if !defined(S_IFIFO) -# define S_IFIFO _S_IFIFO -#endif - -/* Block device */ -#if !defined(S_IFBLK) -# define S_IFBLK 0 -#endif - -/* Link */ -#if !defined(S_IFLNK) -# define S_IFLNK 0 -#endif - -/* Socket */ -#if !defined(S_IFSOCK) -# define S_IFSOCK 0 -#endif - -/* Read user permission */ -#if !defined(S_IRUSR) -# define S_IRUSR S_IREAD -#endif - -/* Write user permission */ -#if !defined(S_IWUSR) -# define S_IWUSR S_IWRITE -#endif - -/* Execute user permission */ -#if !defined(S_IXUSR) -# define S_IXUSR 0 -#endif - -/* Read group permission */ -#if !defined(S_IRGRP) -# define S_IRGRP 0 -#endif - -/* Write group permission */ -#if !defined(S_IWGRP) -# define S_IWGRP 0 -#endif - -/* Execute group permission */ -#if !defined(S_IXGRP) -# define S_IXGRP 0 -#endif - -/* Read others permission */ -#if !defined(S_IROTH) -# define S_IROTH 0 -#endif - -/* Write others permission */ -#if !defined(S_IWOTH) -# define S_IWOTH 0 -#endif - -/* Execute others permission */ -#if !defined(S_IXOTH) -# define S_IXOTH 0 -#endif - -/* Maximum length of file name */ -#if !defined(PATH_MAX) -# define PATH_MAX MAX_PATH -#endif -#if !defined(FILENAME_MAX) -# define FILENAME_MAX MAX_PATH -#endif -#if !defined(NAME_MAX) -# define NAME_MAX FILENAME_MAX -#endif - -/* File type flags for d_type */ -#define DT_UNKNOWN 0 -#define DT_REG S_IFREG -#define DT_DIR S_IFDIR -#define DT_FIFO S_IFIFO -#define DT_SOCK S_IFSOCK -#define DT_CHR S_IFCHR -#define DT_BLK S_IFBLK -#define DT_LNK S_IFLNK - -/* Macros for converting between st_mode and d_type */ -#define IFTODT(mode) ((mode) & S_IFMT) -#define DTTOIF(type) (type) - -/* - * File type macros. Note that block devices, sockets and links cannot be - * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are - * only defined for compatibility. These macros should always return false - * on Windows. - */ -#if !defined(S_ISFIFO) -# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -#endif -#if !defined(S_ISDIR) -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) -# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISLNK) -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#endif -#if !defined(S_ISSOCK) -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -#endif -#if !defined(S_ISCHR) -# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISBLK) -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -#endif - -/* Return the exact length of the file name without zero terminator */ -#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) - -/* Return the maximum size of a file name */ -#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1) - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Wide-character version */ -struct _wdirent { - /* Always zero */ - long d_ino; - - /* File position within stream */ - long d_off; - - /* Structure size */ - unsigned short d_reclen; - - /* Length of name without \0 */ - size_t d_namlen; - - /* File type */ - int d_type; - - /* File name */ - wchar_t d_name[PATH_MAX+1]; -}; -typedef struct _wdirent _wdirent; - -struct _WDIR { - /* Current directory entry */ - struct _wdirent ent; - - /* Private file data */ - WIN32_FIND_DATAW data; - - /* True if data is valid */ - int cached; - - /* Win32 search handle */ - HANDLE handle; - - /* Initial directory name */ - wchar_t *patt; -}; -typedef struct _WDIR _WDIR; - -/* Multi-byte character version */ -struct dirent { - /* Always zero */ - long d_ino; - - /* File position within stream */ - long d_off; - - /* Structure size */ - unsigned short d_reclen; - - /* Length of name without \0 */ - size_t d_namlen; - - /* File type */ - int d_type; - - /* File name */ - char d_name[PATH_MAX+1]; -}; -typedef struct dirent dirent; - -struct DIR { - struct dirent ent; - struct _WDIR *wdirp; -}; -typedef struct DIR DIR; - - -/* Dirent functions */ -static DIR *opendir (const char *dirname); -static _WDIR *_wopendir (const wchar_t *dirname); - -static struct dirent *readdir (DIR *dirp); -static struct _wdirent *_wreaddir (_WDIR *dirp); - -static int readdir_r( - DIR *dirp, struct dirent *entry, struct dirent **result); -static int _wreaddir_r( - _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result); - -static int closedir (DIR *dirp); -static int _wclosedir (_WDIR *dirp); - -static void rewinddir (DIR* dirp); -static void _wrewinddir (_WDIR* dirp); - -static int scandir (const char *dirname, struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)); - -static int alphasort (const struct dirent **a, const struct dirent **b); - -static int versionsort (const struct dirent **a, const struct dirent **b); - - -/* For compatibility with Symbian */ -#define wdirent _wdirent -#define WDIR _WDIR -#define wopendir _wopendir -#define wreaddir _wreaddir -#define wclosedir _wclosedir -#define wrewinddir _wrewinddir - - -/* Internal utility functions */ -static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); -static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); - -static int dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count); - -static int dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, - const wchar_t *wcstr, - size_t count); - -static void dirent_set_errno (int error); - - -/* - * Open directory stream DIRNAME for read and return a pointer to the - * internal working area that is used to retrieve individual directory - * entries. - */ -static _WDIR* -_wopendir( - const wchar_t *dirname) -{ - _WDIR *dirp; - DWORD n; - wchar_t *p; - - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } - - /* Allocate new _WDIR structure */ - dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); - if (!dirp) { - return NULL; - } - - /* Reset _WDIR structure */ - dirp->handle = INVALID_HANDLE_VALUE; - dirp->patt = NULL; - dirp->cached = 0; - - /* - * Compute the length of full path plus zero terminator - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, 0, NULL, NULL); -#else - /* WinRT */ - n = wcslen (dirname); -#endif - - /* Allocate room for absolute directory name and search pattern */ - dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); - if (dirp->patt == NULL) { - goto exit_closedir; - } - - /* - * Convert relative directory name to an absolute one. This - * allows rewinddir() to function correctly even when current - * working directory is changed between opendir() and rewinddir(). - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, n, dirp->patt, NULL); - if (n <= 0) { - goto exit_closedir; - } -#else - /* WinRT */ - wcsncpy_s (dirp->patt, n+1, dirname, n); -#endif - - /* Append search pattern \* to the directory name */ - p = dirp->patt + n; - switch (p[-1]) { - case '\\': - case '/': - case ':': - /* Directory ends in path separator, e.g. c:\temp\ */ - /*NOP*/; - break; - - default: - /* Directory name doesn't end in path separator */ - *p++ = '\\'; - } - *p++ = '*'; - *p = '\0'; - - /* Open directory stream and retrieve the first entry */ - if (!dirent_first (dirp)) { - goto exit_closedir; - } - - /* Success */ - return dirp; - - /* Failure */ -exit_closedir: - _wclosedir (dirp); - return NULL; -} - -/* - * Read next directory entry. - * - * Returns pointer to static directory entry which may be overwritten by - * subsequent calls to _wreaddir(). - */ -static struct _wdirent* -_wreaddir( - _WDIR *dirp) -{ - struct _wdirent *entry; - - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) _wreaddir_r (dirp, &dirp->ent, &entry); - - /* Return pointer to statically allocated directory entry */ - return entry; -} - -/* - * Read next directory entry. - * - * Returns zero on success. If end of directory stream is reached, then sets - * result to NULL and returns zero. - */ -static int -_wreaddir_r( - _WDIR *dirp, - struct _wdirent *entry, - struct _wdirent **result) -{ - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp); - if (datap) { - size_t n; - DWORD attr; - - /* - * Copy file name as wide-character string. If the file name is too - * long to fit in to the destination buffer, then truncate file name - * to PATH_MAX characters and zero-terminate the buffer. - */ - n = 0; - while (n < PATH_MAX && datap->cFileName[n] != 0) { - entry->d_name[n] = datap->cFileName[n]; - n++; - } - entry->d_name[n] = 0; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n; - - /* File type */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct _wdirent); - - /* Set result address */ - *result = entry; - - } else { - - /* Return NULL to indicate end of directory */ - *result = NULL; - - } - - return /*OK*/0; -} - -/* - * Close directory stream opened by opendir() function. This invalidates the - * DIR structure as well as any directory entry read previously by - * _wreaddir(). - */ -static int -_wclosedir( - _WDIR *dirp) -{ - int ok; - if (dirp) { - - /* Release search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } - - /* Release search pattern */ - free (dirp->patt); - - /* Release directory structure */ - free (dirp); - ok = /*success*/0; - - } else { - - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; - - } - return ok; -} - -/* - * Rewind directory stream such that _wreaddir() returns the very first - * file name again. - */ -static void -_wrewinddir( - _WDIR* dirp) -{ - if (dirp) { - /* Release existing search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } - - /* Open new search handle */ - dirent_first (dirp); - } -} - -/* Get first directory entry (internal) */ -static WIN32_FIND_DATAW* -dirent_first( - _WDIR *dirp) -{ - WIN32_FIND_DATAW *datap; - DWORD error; - - /* Open directory and retrieve the first entry */ - dirp->handle = FindFirstFileExW( - dirp->patt, FindExInfoStandard, &dirp->data, - FindExSearchNameMatch, NULL, 0); - if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* a directory entry is now waiting in memory */ - datap = &dirp->data; - dirp->cached = 1; - - } else { - - /* Failed to open directory: no directory entry in memory */ - dirp->cached = 0; - datap = NULL; - - /* Set error code */ - error = GetLastError (); - switch (error) { - case ERROR_ACCESS_DENIED: - /* No read access to directory */ - dirent_set_errno (EACCES); - break; - - case ERROR_DIRECTORY: - /* Directory name is invalid */ - dirent_set_errno (ENOTDIR); - break; - - case ERROR_PATH_NOT_FOUND: - default: - /* Cannot find the file */ - dirent_set_errno (ENOENT); - } - - } - return datap; -} - -/* - * Get next directory entry (internal). - * - * Returns - */ -static WIN32_FIND_DATAW* -dirent_next( - _WDIR *dirp) -{ - WIN32_FIND_DATAW *p; - - /* Get next directory entry */ - if (dirp->cached != 0) { - - /* A valid directory entry already in memory */ - p = &dirp->data; - dirp->cached = 0; - - } else if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* Get the next directory entry from stream */ - if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { - /* Got a file */ - p = &dirp->data; - } else { - /* The very last entry has been processed or an error occurred */ - FindClose (dirp->handle); - dirp->handle = INVALID_HANDLE_VALUE; - p = NULL; - } - - } else { - - /* End of directory stream reached */ - p = NULL; - - } - - return p; -} - -/* - * Open directory stream using plain old C-string. - */ -static DIR* -opendir( - const char *dirname) -{ - struct DIR *dirp; - - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } - - /* Allocate memory for DIR structure */ - dirp = (DIR*) malloc (sizeof (struct DIR)); - if (!dirp) { - return NULL; - } - { - int error; - wchar_t wname[PATH_MAX + 1]; - size_t n; - - /* Convert directory name to wide-character string */ - error = dirent_mbstowcs_s( - &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); - if (error) { - /* - * Cannot convert file name to wide-character string. This - * occurs if the string contains invalid multi-byte sequences or - * the output buffer is too small to contain the resulting - * string. - */ - goto exit_free; - } - - - /* Open directory stream using wide-character name */ - dirp->wdirp = _wopendir (wname); - if (!dirp->wdirp) { - goto exit_free; - } - - } - - /* Success */ - return dirp; - - /* Failure */ -exit_free: - free (dirp); - return NULL; -} - -/* - * Read next directory entry. - */ -static struct dirent* -readdir( - DIR *dirp) -{ - struct dirent *entry; - - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) readdir_r (dirp, &dirp->ent, &entry); - - /* Return pointer to statically allocated directory entry */ - return entry; -} - -/* - * Read next directory entry into called-allocated buffer. - * - * Returns zero on success. If the end of directory stream is reached, then - * sets result to NULL and returns zero. - */ -static int -readdir_r( - DIR *dirp, - struct dirent *entry, - struct dirent **result) -{ - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp->wdirp); - if (datap) { - size_t n; - int error; - - /* Attempt to convert file name to multi-byte string */ - error = dirent_wcstombs_s( - &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); - - /* - * If the file name cannot be represented by a multi-byte string, - * then attempt to use old 8+3 file name. This allows traditional - * Unix-code to access some file names despite of unicode - * characters, although file names may seem unfamiliar to the user. - * - * Be ware that the code below cannot come up with a short file - * name unless the file system provides one. At least - * VirtualBox shared folders fail to do this. - */ - if (error && datap->cAlternateFileName[0] != '\0') { - error = dirent_wcstombs_s( - &n, entry->d_name, PATH_MAX + 1, - datap->cAlternateFileName, PATH_MAX + 1); - } - - if (!error) { - DWORD attr; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n - 1; - - /* File attributes */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct dirent); - - } else { - - /* - * Cannot convert file name to multi-byte string so construct - * an erroneous directory entry and return that. Note that - * we cannot return NULL as that would stop the processing - * of directory entries completely. - */ - entry->d_name[0] = '?'; - entry->d_name[1] = '\0'; - entry->d_namlen = 1; - entry->d_type = DT_UNKNOWN; - entry->d_ino = 0; - entry->d_off = -1; - entry->d_reclen = 0; - - } - - /* Return pointer to directory entry */ - *result = entry; - - } else { - - /* No more directory entries */ - *result = NULL; - - } - - return /*OK*/0; -} - -/* - * Close directory stream. - */ -static int -closedir( - DIR *dirp) -{ - int ok; - if (dirp) { - - /* Close wide-character directory stream */ - ok = _wclosedir (dirp->wdirp); - dirp->wdirp = NULL; - - /* Release multi-byte character version */ - free (dirp); - - } else { - - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; - - } - return ok; -} - -/* - * Rewind directory stream to beginning. - */ -static void -rewinddir( - DIR* dirp) -{ - /* Rewind wide-character string directory stream */ - _wrewinddir (dirp->wdirp); -} - -/* - * Scan directory for entries. - */ -static int -scandir( - const char *dirname, - struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)) -{ - struct dirent **files = NULL; - size_t size = 0; - size_t allocated = 0; - const size_t init_size = 1; - DIR *dir = NULL; - struct dirent *entry; - struct dirent *tmp = NULL; - size_t i; - int result = 0; - - /* Open directory stream */ - dir = opendir (dirname); - if (dir) { - - /* Read directory entries to memory */ - while (1) { - - /* Enlarge pointer table to make room for another pointer */ - if (size >= allocated) { - void *p; - size_t num_entries; - - /* Compute number of entries in the enlarged pointer table */ - if (size < init_size) { - /* Allocate initial pointer table */ - num_entries = init_size; - } else { - /* Double the size */ - num_entries = size * 2; - } - - /* Allocate first pointer table or enlarge existing table */ - p = realloc (files, sizeof (void*) * num_entries); - if (p != NULL) { - /* Got the memory */ - files = (dirent**) p; - allocated = num_entries; - } else { - /* Out of memory */ - result = -1; - break; - } - - } - - /* Allocate room for temporary directory entry */ - if (tmp == NULL) { - tmp = (struct dirent*) malloc (sizeof (struct dirent)); - if (tmp == NULL) { - /* Cannot allocate temporary directory entry */ - result = -1; - break; - } - } - - /* Read directory entry to temporary area */ - if (readdir_r (dir, tmp, &entry) == /*OK*/0) { - - /* Did we get an entry? */ - if (entry != NULL) { - int pass; - - /* Determine whether to include the entry in result */ - if (filter) { - /* Let the filter function decide */ - pass = filter (tmp); - } else { - /* No filter function, include everything */ - pass = 1; - } - - if (pass) { - /* Store the temporary entry to pointer table */ - files[size++] = tmp; - tmp = NULL; - - /* Keep up with the number of files */ - result++; - } - - } else { - - /* - * End of directory stream reached => sort entries and - * exit. - */ - qsort (files, size, sizeof (void*), - (int (*) (const void*, const void*)) compare); - break; - - } - - } else { - /* Error reading directory entry */ - result = /*Error*/ -1; - break; - } - - } - - } else { - /* Cannot open directory */ - result = /*Error*/ -1; - } - - /* Release temporary directory entry */ - free (tmp); - - /* Release allocated memory on error */ - if (result < 0) { - for (i = 0; i < size; i++) { - free (files[i]); - } - free (files); - files = NULL; - } - - /* Close directory stream */ - if (dir) { - closedir (dir); - } - - /* Pass pointer table to caller */ - if (namelist) { - *namelist = files; - } - return result; -} - -/* Alphabetical sorting */ -static int -alphasort( - const struct dirent **a, const struct dirent **b) -{ - return strcoll ((*a)->d_name, (*b)->d_name); -} - -/* Sort versions */ -static int -versionsort( - const struct dirent **a, const struct dirent **b) -{ - /* FIXME: implement strverscmp and use that */ - return alphasort (a, b); -} - -/* Convert multi-byte string to wide character string */ -static int -dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count) -{ - int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); - -#else - - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; - - /* Convert to wide-character string (or count characters) */ - n = mbstowcs (wcstr, mbstr, sizeInWords); - if (!wcstr || n < count) { - - /* Zero-terminate output buffer */ - if (wcstr && sizeInWords) { - if (n >= sizeInWords) { - n = sizeInWords - 1; - } - wcstr[n] = 0; - } - - /* Length of resulting multi-byte string WITH zero terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } - - /* Success */ - error = 0; - - } else { - - /* Could not convert string */ - error = 1; - - } - -#endif - return error; -} - -/* Convert wide-character string to multi-byte string */ -static int -dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, /* max size of mbstr */ - const wchar_t *wcstr, - size_t count) -{ - int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); - -#else - - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; - - /* Convert to multi-byte string (or count the number of bytes needed) */ - n = wcstombs (mbstr, wcstr, sizeInBytes); - if (!mbstr || n < count) { - - /* Zero-terminate output buffer */ - if (mbstr && sizeInBytes) { - if (n >= sizeInBytes) { - n = sizeInBytes - 1; - } - mbstr[n] = '\0'; - } - - /* Length of resulting multi-bytes string WITH zero-terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } - - /* Success */ - error = 0; - - } else { - - /* Cannot convert string */ - error = 1; - - } - -#endif - return error; -} - -/* Set errno variable */ -static void -dirent_set_errno( - int error) -{ -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 and later */ - _set_errno (error); - -#else - - /* Non-Microsoft compiler or older Microsoft compiler */ - errno = error; - -#endif -} - - -#ifdef __cplusplus -} -#endif -#endif /*DIRENT_H*/ diff --git a/third_party/glog/src/windows/port.cc b/third_party/glog/src/windows/port.cc deleted file mode 100755 index f0022e7..0000000 --- a/third_party/glog/src/windows/port.cc +++ /dev/null @@ -1,71 +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 "port.h" - -// 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_LOCALTIME_R -struct tm* localtime_r(const time_t* timep, struct tm* result) { - localtime_s(result, timep); - return result; -} -#endif // not HAVE_LOCALTIME_R -#ifndef HAVE_GMTIME_R -struct tm* gmtime_r(const time_t* timep, struct tm* result) { - gmtime_s(result, timep); - return result; -} -#endif // not HAVE_GMTIME_R -#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/glog/src/windows/port.h b/third_party/glog/src/windows/port.h deleted file mode 100755 index a71979f..0000000 --- a/third_party/glog/src/windows/port.h +++ /dev/null @@ -1,181 +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 /* template_dictionary.cc uses va_copy */ -#include /* read in vsnprintf decl. before redifining it */ -#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. - */ - -#include - -#ifdef _MSC_VER - -/* 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() - * 4312: Converting uint32_t to a pointer when testing %p - * 4267: also subtracting two size_t to int - * 4722: Destructor never returns due to abort() - */ -#pragma warning(disable:4244 4251 4355 4715 4800 4996 4267 4312 4722) - -/* file I/O */ -#define PATH_MAX 1024 -#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 -#define R_OK 04 /* read-only (for access()) */ -#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) - -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_EXCL _O_EXCL - -#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 GLOG_EXPORT snprintf(char* str, size_t size, const char* format, - ...); -#endif -extern int GLOG_EXPORT 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 -typedef int pid_t; -#define getpid _getpid - -#endif // _MSC_VER - -// ----------------------------------- THREADS -#if defined(HAVE_PTHREAD) -# include -#else // no PTHREAD -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)) -#endif // HAVE_PTHREAD - -#ifndef HAVE_LOCALTIME_R -extern GLOG_EXPORT struct tm* localtime_r(const time_t* timep, - struct tm* result); -#endif // not HAVE_LOCALTIME_R - -#ifndef HAVE_GMTIME_R -extern GLOG_EXPORT struct tm* gmtime_r(const time_t* timep, struct tm* result); -#endif // not HAVE_GMTIME_R - -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/tile/base/config.h.in b/tile/base/config.h.in index d16f6cc..6fb7ea6 100644 --- a/tile/base/config.h.in +++ b/tile/base/config.h.in @@ -20,7 +20,7 @@ #define TILE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@" #define TILE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@" #define TILE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@" -#define TILE_VERSION "@PROJECT_VERSOIN@" +#define TILE_VERSION "@TILE_VERSION@" // clang-format on diff --git a/tile/base/exposed_var.h b/tile/base/exposed_var.h index 85d347c..70d9267 100644 --- a/tile/base/exposed_var.h +++ b/tile/base/exposed_var.h @@ -171,6 +171,7 @@ private: std::unordered_map m = {{"1s", 1}}; for (auto &&item : m) { } + return result; } void LinkToParent(Slice rel_path, ExposedVarGroup *parent) { diff --git a/tile/base/internal/logging.cc b/tile/base/internal/logging.cc index 746bbf4..0dd9dc3 100644 --- a/tile/base/internal/logging.cc +++ b/tile/base/internal/logging.cc @@ -1,57 +1,27 @@ #include "tile/base/internal/logging.h" - -#include "glog/logging.h" - +#include +#include #include #include - -namespace tile { -bool VLogIsOn(int n) { return true; } -class LogMessage::Impl { -public: - Impl(const char *file, int line, int severity) : lm_(file, line, severity) {} - std::ostream &stream() { return lm_.stream(); } - -private: - google::LogMessage lm_; -}; - -class LogMessageFatal::Impl { -public: - Impl(const char *file, int line) : lm_(file, line) {} - std::ostream &stream() { return lm_.stream(); } - -private: - google::LogMessageFatal lm_; -}; - -LogMessage::LogMessage(const char *file, int line, int severity) - : impl_(new Impl(file, line, severity)) {} -LogMessage::~LogMessage() = default; -std::ostream &LogMessage::stream() { return impl_->stream(); } - -LogMessageFatal::LogMessageFatal(const char *file, int line) - : impl_(new Impl(file, line)) {} -LogMessageFatal::~LogMessageFatal() = default; -std::ostream &LogMessageFatal::stream() { return impl_->stream(); } - -} // namespace tile +#include namespace tile { namespace internal { namespace logging { + namespace { std::vector *GetProviers() { static std::vector providers; return &providers; } } // namespace + namespace details { std::string DescribeFormatArguments(const std::vector &args) { return fmt::format("{}", fmt::join(args.begin(), args.end(), ", ")); } - } // namespace details + void InstallPrefixProvider(PrefixAppender *writer) { GetProviers()->push_back(writer); } @@ -67,30 +37,223 @@ void WritePrefixTo(std::string *to) { } // namespace logging } // namespace internal } // namespace tile + namespace tile { +static std::mutex g_sink_mutex; +static std::set g_sinks; +static std::atomic g_sink_count{0}; + +static uint64_t g_num_messages[TILE_MAX_LOG_SEVERITY + 1]; +std::mutex g_log_mutex; + +class OStreamWrapper : public std::streambuf { +public: + OStreamWrapper(std::ostream &ostream) : ostream_(ostream) {} + + int_type overflow(int_type c) override { return c; } + +private: + std::ostream &ostream_; +}; + +bool VLogIsOn(int n) { return true; } + +class LogMessage::Impl { +public: + Impl(const char *file, int line) + : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { + Init(file, line, TILE_INFO, &LogMessage::Impl::SendToLog); + } + Impl(const char *file, int line, LogSeverity severity) + : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { + Init(file, line, severity, &LogMessage::Impl::SendToLog); + } + Impl(const char *file, int line, LogSeverity severity, LogSink *sink, + bool also_send_to_log) + : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { + Init(file, line, severity, + also_send_to_log ? &LogMessage::Impl::SendToSinkAndLog + : &LogMessage::Impl::SendToSink); + sink_ = sink; + } + ~Impl() { Flush(); } + std::ostream &stream() { return stream_; } + void Flush() { + if (has_been_flushed_) { + return; + } + + num_chars_to_log_ = stream_.pcount(); + const bool append_newline = message_text_[num_chars_to_log_ - 1] != '\n'; + char original_final_char = '\0'; + + if (append_newline) { + original_final_char = message_text_[num_chars_to_log_]; + message_text_[num_chars_to_log_++] = '\n'; + } + message_text_[num_chars_to_log_] = '\0'; + + { + std::lock_guard _{g_log_mutex}; + (this->*(send_method_))(); + ++g_num_messages[severity_]; + WaitForSinks(); + if (sink_) { + sink_->Flush(); + } + } + + if (append_newline) { + message_text_[num_chars_to_log_ - 1] = original_final_char; + } + + if (preserved_errno_ != 0) { + errno = preserved_errno_; + } + has_been_flushed_ = true; + + if (severity_ == TILE_FATAL) { + assert(false); + } + } + + LogSeverity severity() const noexcept { return severity_; } + int line() const noexcept { return line_; } + const char *fullname() const noexcept { return file_; } + const char *basename() const noexcept { return file_; } + const LogMessageTime &time() const noexcept { return time_; } + int preserved_errno() const { return preserved_errno_; } + +private: + void Init(const char *file, int line, LogSeverity severity, + void (LogMessage::Impl::*send_method)()) { + has_been_flushed_ = false; + file_ = file; + line_ = line; + severity_ = severity; + send_method_ = send_method; + sink_ = nullptr; + const auto now = std::chrono::system_clock::now(); + time_ = LogMessageTime(now); + thread_id_ = std::this_thread::get_id(); + preserved_errno_ = errno; + } + + void SendToSink() { + if (sink_) { + sink_->Send(severity_, fullname(), basename(), line(), time(), + message_text_ + num_prefix_chars_, + num_chars_to_log_ - num_prefix_chars_); + } + } + void SendToLog() { + if (g_sink_count.load(std::memory_order_relaxed) == 0) { + ColoredWriteToStdout(severity_, message_text_ + num_prefix_chars_, + num_chars_to_log_ - num_chars_to_log_); + } + LogToSinks(severity_, fullname(), basename(), line(), time(), + message_text_ + num_prefix_chars_, + num_chars_to_log_ - num_prefix_chars_); + } + void SendToSinkAndLog() { + SendToSink(); + SendToLog(); + } + +private: + char message_text_[LogMessage::kMaxLogMessageLen + 1]; + LogMessage::LogStream stream_; + + bool has_been_flushed_; + + const char *file_; + int line_; + LogSeverity severity_; + void (LogMessage::Impl::*send_method_)(); + + LogSink *sink_; + LogMessageTime time_; + std::thread::id thread_id_; + int preserved_errno_; + + size_t num_prefix_chars_; + size_t num_chars_to_log_; +}; + +LogMessage::LogMessage(const char *file, int line) + : impl_(new Impl(file, line)) {} +LogMessage::LogMessage(const char *file, int line, LogSeverity severity) + : impl_(new Impl(file, line, severity)) {} +LogMessage::LogMessage(const char *file, int line, LogSeverity severity, + LogSink *sink, bool also_send_to_log) + : impl_(new Impl(file, line, severity, sink, also_send_to_log)) {} + +LogMessage::~LogMessage() {} + +std::ostream &LogMessage::stream() { return impl_->stream(); } +void LogMessage::Flush() { impl_->Flush(); } + +LogSeverity LogMessage::severity() const noexcept { return impl_->severity(); } +int LogMessage::line() const noexcept { return impl_->line(); } +const char *LogMessage::fullname() const noexcept { return impl_->fullname(); } +const char *LogMessage::basename() const noexcept { return impl_->basename(); } +const LogMessageTime &LogMessage::time() const noexcept { + return impl_->time(); +} +int LogMessage::preserved_errno() const { return impl_->preserved_errno(); } + +LogMessageFatal::LogMessageFatal(const char *file, int line) + : LogMessage(file, line, TILE_FATAL) {} + +LogMessageFatal::~LogMessageFatal() {} + +std::ostream &LogMessageFatal::stream() { return LogMessage::stream(); } LogMessageTime::LogMessageTime() : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {} -LogMessageTime::LogMessageTime(std::tm t) { +LogMessageTime::LogMessageTime(std::tm t) : use_localtime_(true) { std::time_t timestamp = std::mktime(&t); init(t, timestamp, 0); } -LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) { +LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) + : use_localtime_(false) { std::tm t; - if (FLAGS_log_utc_time) - gmtime_r(×tamp, &t); - else + if (use_localtime_) { localtime_r(×tamp, &t); + } else { + gmtime_r(×tamp, &t); + } + init(t, timestamp, now); } +LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp) + : use_localtime_(false) { + std::time_t timestamp = std::chrono::system_clock::to_time_t(tp); + std::tm t; + if (use_localtime_) { + localtime_r(×tamp, &t); + } else { + gmtime_r(×tamp, &t); + } + + init(t, timestamp, 0); + usecs_ = std::chrono::duration_cast( + tp.time_since_epoch()) + .count() % + 1000000; +} void LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now) { time_struct_ = t; timestamp_ = timestamp; - usecs_ = static_cast((now - timestamp) * 1000000); + if (now < timestamp) { + usecs_ = 0; + } else { + usecs_ = static_cast((now - timestamp) * 1000000) % 1000000; + } CalcGmtOffset(); } @@ -98,7 +261,7 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp, void LogMessageTime::CalcGmtOffset() { std::tm gmt_struct; int isDst = 0; - if (FLAGS_log_utc_time) { + if (true) { localtime_r(×tamp_, &gmt_struct); isDst = gmt_struct.tm_isdst; gmt_struct = time_struct_; @@ -116,72 +279,112 @@ void LogMessageTime::CalcGmtOffset() { } LogSink::~LogSink() {} -void LogSink::send(LogSeverity severity, const char *full_filename, +bool LogSink::ShouldLog(LogSeverity severity) { return true; } +void LogSink::Send(LogSeverity severity, const char *full_filename, const char *base_filename, int line, const LogMessageTime &logmsgtime, const char *message, size_t message_len) { // do nothing } -void LogSink::WaitTillSent() {} -std::string LogSink::ToString(LogSeverity severity, const char *file, int line, +void LogSink::Flush() {} + +std::string LogSink::ToString(LogSeverity severity, const char *file, + const char *base_filename, int line, const LogMessageTime &logmsgtime, const char *message, size_t message_len) { - return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), - message, message_len); + std::stringstream ss; + char date_time[64]; + sprintf(date_time, "%4d-%02d-%02dT%02d:%02d:%02d.%06d", + logmsgtime.year() + 1900, logmsgtime.month(), logmsgtime.day(), + logmsgtime.hour(), logmsgtime.min(), logmsgtime.sec(), + logmsgtime.usec()); + + ss << date_time; + + if (logmsgtime.gmtoff() != 0) { + auto hour = logmsgtime.gmtoff() / 3600; + auto min = std::abs(logmsgtime.gmtoff() % 3600) / 60; + sprintf(date_time, "%+03ld:%02ld", hour, min); + ss << date_time; + } else if (!logmsgtime.use_localtime()) { + ss << "Z"; + } + ss << " " << GetLogSeverityName(severity)[0] << " "; + ss << base_filename << ":" << line << " "; + + // return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), + // message, message_len); + + ss.write(message, message_len); + return ss.str(); } -class LogSinkWrapper : public google::LogSink { -public: - LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {} - ~LogSinkWrapper() override {} - void send(LogSeverity severity, const char *full_filename, - const char *base_filename, int line, - const google::LogMessageTime &logmsgtime, const char *message, - size_t message_len) override { - dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(), - message, message_len); - } - - void WaitTillSent() override { dest_->WaitTillSent(); } - -private: - tile::LogSink *dest_; -}; - -struct LogSinkPair { - struct LogSinWrapper *wrapper; - LogSink *sink; -}; - -static std::map sink_registry; -static std::mutex sink_registry_mutex; - -void AddLogSink(LogSink *dest) { - std::lock_guard lock(sink_registry_mutex); - if (sink_registry.find(dest) != sink_registry.end()) { - return; - } - - auto wrapper = new LogSinkWrapper(dest); - sink_registry[dest] = wrapper; - google::AddLogSink(wrapper); +static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity, + const char *message, size_t len) { + fwrite(message, len, 1, output); + fflush(output); } -void RemoveLogSink(LogSink *dest) { - std::lock_guard lock(sink_registry_mutex); - auto iter = sink_registry.find(dest); - if (iter != sink_registry.end()) { - google::RemoveLogSink(iter->second); - sink_registry.erase(iter); - delete iter->second; +void ColoredWriteToStdout(LogSeverity severity, const char *message, + size_t len) { + FILE *output = stdout; + if (severity >= TILE_FATAL) { + output = stderr; + } + ColoredWriteToStderrOrStdout(output, severity, message, len); +} +void ColoredWriteToStderr(LogSeverity severity, const char *message, + size_t len) { + ColoredWriteToStderrOrStdout(stderr, severity, message, len); +} + +void AddLogSink(LogSink::Ptr dest) { + std::lock_guard _(g_sink_mutex); + g_sinks.insert(dest); + g_sink_count.fetch_add(1); +} + +void RemoveLogSink(LogSink::Ptr dest) { + std::lock_guard _(g_sink_mutex); + g_sinks.erase(dest); + g_sink_count.fetch_sub(1); +} + +void SetStderrLogging(LogSeverity min_severity) {} +void LogToStderr() {} +void LogToSinks(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, const LogMessageTime &time, + const char *message, size_t message_len) { + std::lock_guard _(g_sink_mutex); + for (auto &&sink : g_sinks) { + if (sink->ShouldLog(severity)) { + sink->Send(severity, full_filename, base_filename, line, time, message, + message_len); + } } } -void SetStderrLogging(LogSeverity min_severity) { - google::SetStderrLogging(min_severity); +void WaitForSinks() { + std::lock_guard _(g_sink_mutex); + for (auto &&sink : g_sinks) { + sink->Flush(); + } } -void LogToStderr() { google::LogToStderr(); } + const char *GetLogSeverityName(LogSeverity severity) { - return google::GetLogSeverityName(severity); + const static std::map severity_names = { + {TILE_INFO, "INFO"}, + {TILE_WARNING, "WARNING"}, + {TILE_ERROR, "ERROR"}, + {TILE_FATAL, "FATAL"}, + }; + + auto iter = severity_names.find(severity); + if (iter != severity_names.end()) { + return iter->second; + } else { + return "UNKNOWN"; + } } + } // namespace tile diff --git a/tile/base/internal/logging.h b/tile/base/internal/logging.h index 6c527d1..3b4cc44 100644 --- a/tile/base/internal/logging.h +++ b/tile/base/internal/logging.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -17,31 +18,98 @@ #include namespace tile { -typedef int LogSeverity; -const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3; +// typedef int LogSeverity; +// const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3; +enum LogSeverity { + TILE_INFO = 0, + TILE_WARNING = 1, + TILE_ERROR = 2, + TILE_FATAL = 3, + TILE_MAX_LOG_SEVERITY = TILE_FATAL +}; bool VLogIsOn(int n); +class LogStreamBuf : public std::streambuf { +public: + LogStreamBuf(char *buf, int len) { setp(buf, buf + len - 2); } + + int_type overflow(int_type ch) { return ch; } + size_t pcount() const { return static_cast(pptr() - pbase()); } + char *pbase() const { return std::streambuf::pbase(); } +}; + +class LogSink; +class LogMessageTime; class LogMessage { public: - LogMessage(const char *file, int line, int severity); + class LogStream : public std::ostream { + public: + LogStream(char *buf, int len, int64_t ctr) + : std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this) { + rdbuf(&streambuf_); + } + + LogStream(LogStream &other) noexcept + : std::ostream(nullptr), streambuf_(std::move(other.streambuf_)), + ctr_(internal::Exchange(other.ctr_, 0)), self_(this) { + rdbuf(&streambuf_); + } + + LogStream &operator=(LogStream &&other) noexcept { + streambuf_ = std::move(other.streambuf_); + ctr_ = internal::Exchange(other.ctr_, 0); + self_ = this; + rdbuf(&streambuf_); + return *this; + } + + int64_t ctr() const { return ctr_; } + void set_ctr(int64_t ctr) { ctr_ = ctr; } + + LogStream *self() { return self_; } + + size_t pcount() const { return streambuf_.pcount(); } + char *pbase() const { return streambuf_.pbase(); } + char *str() const { return pbase(); } + + LogStream(const LogStream &) = delete; + LogStream &operator=(const LogStream &) = delete; + + private: + LogStreamBuf streambuf_; + int64_t ctr_; + LogStream *self_; + }; + +public: + static const size_t kMaxLogMessageLen = 30000; + LogMessage(const char *file, int line); + LogMessage(const char *file, int line, LogSeverity severity); + LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink, + bool also_send_to_log = true); + ~LogMessage(); std::ostream &stream(); + void Flush(); + + LogSeverity severity() const noexcept; + int line() const noexcept; + const char *fullname() const noexcept; + const char *basename() const noexcept; + const LogMessageTime &time() const noexcept; + int preserved_errno() const; private: class Impl; std::unique_ptr impl_; }; -class LogMessageFatal { +class LogMessageFatal : public LogMessage { public: LogMessageFatal(const char *file, int line); ~LogMessageFatal(); std::ostream &stream(); - -private: - class Impl; - std::unique_ptr impl_; }; class LogMessageVoidify { @@ -599,6 +667,7 @@ struct LogMessageTime { LogMessageTime(); LogMessageTime(std::tm t); LogMessageTime(std::time_t timestamp, WallTime now); + LogMessageTime(std::chrono::system_clock::time_point tp); const time_t ×tamp() const { return timestamp_; } const int &sec() const { return time_struct_.tm_sec; } @@ -613,6 +682,7 @@ struct LogMessageTime { const int &dst() const { return time_struct_.tm_isdst; } const long int &gmtoff() const { return gmtoffset_; } const std::tm &tm() const { return time_struct_; } + const bool use_localtime() const { return use_localtime_; } private: void init(const std::tm &t, std::time_t timestamp, WallTime now); @@ -620,32 +690,40 @@ private: time_t timestamp_; // Time of creation of LogMessage in seconds int32_t usecs_; // Time of creation of LogMessage - microseconds part long int gmtoffset_; + bool use_localtime_; void CalcGmtOffset(); }; class LogSink { public: + using Ptr = std::shared_ptr; + virtual ~LogSink(); - virtual void send(LogSeverity severity, const char *full_filename, + virtual bool ShouldLog(LogSeverity severity); + virtual void Send(LogSeverity severity, const char *full_filename, const char *base_filename, int line, const LogMessageTime &logmsgtime, const char *message, size_t message_len); - virtual void WaitTillSent(); - std::string ToString(LogSeverity severity, const char *file, int line, + virtual void Flush(); + std::string ToString(LogSeverity severity, const char *file, + const char *base_file, int line, const LogMessageTime &logmsgtime, const char *message, size_t message_len); }; -class FileLogSink : public LogSink { -public: - FileLogSink(const std::string &file_path_template); -}; - -void AddLogSink(LogSink *dest); -void RemoveLogSink(LogSink *dest); +void ColoredWriteToStdout(LogSeverity severity, const char *message, + size_t len); +void ColoredWriteToStderr(LogSeverity severity, const char *message, + size_t len); +void AddLogSink(LogSink::Ptr dest); +void RemoveLogSink(LogSink::Ptr dest); void SetStderrLogging(LogSeverity min_severity); void LogToStderr(); +void LogToSinks(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, const LogMessageTime &time, + const char *message, size_t message_len); +void WaitForSinks(); const char *GetLogSeverityName(LogSeverity severity); } // namespace tile diff --git a/tile/base/internal/logging_glog.cc b/tile/base/internal/logging_glog.cc new file mode 100644 index 0000000..746bbf4 --- /dev/null +++ b/tile/base/internal/logging_glog.cc @@ -0,0 +1,187 @@ +#include "tile/base/internal/logging.h" + +#include "glog/logging.h" + +#include +#include + +namespace tile { +bool VLogIsOn(int n) { return true; } +class LogMessage::Impl { +public: + Impl(const char *file, int line, int severity) : lm_(file, line, severity) {} + std::ostream &stream() { return lm_.stream(); } + +private: + google::LogMessage lm_; +}; + +class LogMessageFatal::Impl { +public: + Impl(const char *file, int line) : lm_(file, line) {} + std::ostream &stream() { return lm_.stream(); } + +private: + google::LogMessageFatal lm_; +}; + +LogMessage::LogMessage(const char *file, int line, int severity) + : impl_(new Impl(file, line, severity)) {} +LogMessage::~LogMessage() = default; +std::ostream &LogMessage::stream() { return impl_->stream(); } + +LogMessageFatal::LogMessageFatal(const char *file, int line) + : impl_(new Impl(file, line)) {} +LogMessageFatal::~LogMessageFatal() = default; +std::ostream &LogMessageFatal::stream() { return impl_->stream(); } + +} // namespace tile + +namespace tile { +namespace internal { +namespace logging { +namespace { +std::vector *GetProviers() { + static std::vector providers; + return &providers; +} +} // namespace +namespace details { +std::string DescribeFormatArguments(const std::vector &args) { + return fmt::format("{}", fmt::join(args.begin(), args.end(), ", ")); +} + +} // namespace details +void InstallPrefixProvider(PrefixAppender *writer) { + GetProviers()->push_back(writer); +} +void WritePrefixTo(std::string *to) { + for (auto &&appender : *GetProviers()) { + auto was = to->size(); + appender(to); + if (to->size() != was) { + to->push_back(' '); + } + } +} +} // namespace logging +} // namespace internal +} // namespace tile +namespace tile { + +LogMessageTime::LogMessageTime() + : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {} + +LogMessageTime::LogMessageTime(std::tm t) { + std::time_t timestamp = std::mktime(&t); + init(t, timestamp, 0); +} + +LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) { + std::tm t; + if (FLAGS_log_utc_time) + gmtime_r(×tamp, &t); + else + localtime_r(×tamp, &t); + init(t, timestamp, now); +} + +void LogMessageTime::init(const std::tm &t, std::time_t timestamp, + WallTime now) { + time_struct_ = t; + timestamp_ = timestamp; + usecs_ = static_cast((now - timestamp) * 1000000); + + CalcGmtOffset(); +} + +void LogMessageTime::CalcGmtOffset() { + std::tm gmt_struct; + int isDst = 0; + if (FLAGS_log_utc_time) { + localtime_r(×tamp_, &gmt_struct); + isDst = gmt_struct.tm_isdst; + gmt_struct = time_struct_; + } else { + isDst = time_struct_.tm_isdst; + gmtime_r(×tamp_, &gmt_struct); + } + + time_t gmt_sec = mktime(&gmt_struct); + const long hour_secs = 3600; + // If the Daylight Saving Time(isDst) is active subtract an hour from the + // current timestamp. + gmtoffset_ = + static_cast(timestamp_ - gmt_sec + (isDst ? hour_secs : 0)); +} + +LogSink::~LogSink() {} +void LogSink::send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) { + + // do nothing +} +void LogSink::WaitTillSent() {} +std::string LogSink::ToString(LogSeverity severity, const char *file, int line, + const LogMessageTime &logmsgtime, + const char *message, size_t message_len) { + return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), + message, message_len); +} + +class LogSinkWrapper : public google::LogSink { +public: + LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {} + ~LogSinkWrapper() override {} + void send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const google::LogMessageTime &logmsgtime, const char *message, + size_t message_len) override { + dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(), + message, message_len); + } + + void WaitTillSent() override { dest_->WaitTillSent(); } + +private: + tile::LogSink *dest_; +}; + +struct LogSinkPair { + struct LogSinWrapper *wrapper; + LogSink *sink; +}; + +static std::map sink_registry; +static std::mutex sink_registry_mutex; + +void AddLogSink(LogSink *dest) { + std::lock_guard lock(sink_registry_mutex); + if (sink_registry.find(dest) != sink_registry.end()) { + return; + } + + auto wrapper = new LogSinkWrapper(dest); + sink_registry[dest] = wrapper; + google::AddLogSink(wrapper); +} + +void RemoveLogSink(LogSink *dest) { + std::lock_guard lock(sink_registry_mutex); + auto iter = sink_registry.find(dest); + if (iter != sink_registry.end()) { + google::RemoveLogSink(iter->second); + sink_registry.erase(iter); + delete iter->second; + } +} +void SetStderrLogging(LogSeverity min_severity) { + google::SetStderrLogging(min_severity); +} +void LogToStderr() { google::LogToStderr(); } +const char *GetLogSeverityName(LogSeverity severity) { + return google::GetLogSeverityName(severity); +} +} // namespace tile diff --git a/tile/base/internal/logging_test.cc b/tile/base/internal/logging_test.cc index 6f0d585..013c8e2 100644 --- a/tile/base/internal/logging_test.cc +++ b/tile/base/internal/logging_test.cc @@ -9,11 +9,11 @@ #include struct AwesomeLogSink : public tile::LogSink { - virtual void send(tile::LogSeverity severity, const char *full_filename, + virtual void Send(tile::LogSeverity severity, const char *full_filename, const char *base_filename, int line, const tile::LogMessageTime &logmsgtime, const char *message, size_t message_len) override { - msgs.emplace_back(message, message_len); + msgs.emplace_back(std::string(message, message_len)); } std::vector msgs; }; @@ -39,9 +39,9 @@ TEST(Logging, CHECK) { } TEST(Logging, Prefix) { - AwesomeLogSink sink; - tile::AddLogSink(&sink); - tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); }); + auto sink = std::make_shared(); + tile::AddLogSink(sink); + tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); }); TILE_LOG_INFO("something"); @@ -54,7 +54,7 @@ TEST(Logging, Prefix) { my_prefix2 = "[prefix2]"; TILE_LOG_INFO("something"); - ASSERT_THAT(sink.msgs, + ASSERT_THAT(sink->msgs, ::testing::ElementsAre("something", "[prefix] something", "[prefix1] something", "[prefix1] [prefix2] something")); @@ -67,15 +67,15 @@ TEST(Logging, DontPanicOnFormatFailure) { TEST(Logging, EverySecond) { ResetLogPrefix(); - AwesomeLogSink sink; - tile::AddLogSink(&sink); - tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); }); + auto sink = std::make_shared(); + tile::AddLogSink(sink); + tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); }); for (int i = 0; i < 30; i++) { TILE_LOG_INFO_EVERY_SECOND("something"); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - ASSERT_THAT(sink.msgs, + ASSERT_THAT(sink->msgs, ::testing::ElementsAre("something", "something", "something")); } diff --git a/tile/base/logging.h b/tile/base/logging.h index 9d3cdba..12cc085 100644 --- a/tile/base/logging.h +++ b/tile/base/logging.h @@ -4,6 +4,8 @@ #pragma once #include "tile/base/internal/logging.h" +#include "tile/base/logging/basic_file_sink.h" +#include "tile/base/logging/splitter_sink.h" // #define TILE_VLOG(n, ...) diff --git a/tile/base/logging/basic_file_sink.cc b/tile/base/logging/basic_file_sink.cc new file mode 100644 index 0000000..ca0fe05 --- /dev/null +++ b/tile/base/logging/basic_file_sink.cc @@ -0,0 +1,24 @@ +#include "tile/base/logging/basic_file_sink.h" + +namespace tile { +BasicFileSink::Ptr BasicFileSink::Create(const std::string &filepath) { + auto sink = std::shared_ptr(new BasicFileSink()); + sink->set_filepath(filepath); + return sink; +} +BasicFileSink::BasicFileSink() {} +BasicFileSink::~BasicFileSink() {} +void BasicFileSink::Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) { + TILE_CHECK(!filepath_.empty(), "filepath is empty"); + ofs_ << std::string(message, message_len) << std::endl; +} +std::string BasicFileSink::filepath() const { return filepath_; } +void BasicFileSink::set_filepath(const std::string &filepath) { + filepath_ = filepath; + ofs_.open(filepath, std::ios::out | std::ios::app); +} +void BasicFileSink::Flush() { ofs_.flush(); } +} // namespace tile diff --git a/tile/base/logging/basic_file_sink.h b/tile/base/logging/basic_file_sink.h new file mode 100644 index 0000000..66a8d28 --- /dev/null +++ b/tile/base/logging/basic_file_sink.h @@ -0,0 +1,36 @@ +#ifndef TILE_BASE_LOGGING_BASIC_FILE_SINK_H +#define TILE_BASE_LOGGING_BASIC_FILE_SINK_H + +#pragma once +#include "tile/base/internal/logging.h" + +#include +#include + +namespace tile { +class BasicFileSink : public LogSink { +public: + using Ptr = std::shared_ptr; + static Ptr Create(const std::string &filepath); + + ~BasicFileSink() override; + void Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) override; + void Flush() override; + + std::string filepath() const; + void set_filepath(const std::string &filepath); + +protected: + BasicFileSink(); + +private: + std::string filepath_; + std::ofstream ofs_; +}; + +} // namespace tile + +#endif // TILE_BASE_LOGGING_BASIC_FILE_SINK_H diff --git a/tile/base/logging/console_sink.cc b/tile/base/logging/console_sink.cc new file mode 100644 index 0000000..d274d38 --- /dev/null +++ b/tile/base/logging/console_sink.cc @@ -0,0 +1,32 @@ +#include "tile/base/logging/console_sink.h" + +#include +namespace tile { + +ConsoleSink::Ptr ConsoleSink::Create() { + return std::shared_ptr(new ConsoleSink()); +} + +ConsoleSink::~ConsoleSink() {} + +void ConsoleSink::Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) { + auto msg = ToString(severity, full_filename, base_filename, line, logmsgtime, + message, message_len); + while (!msg.empty() && msg.back() == '\n') { + msg.pop_back(); + } + if (severity >= TILE_FATAL) { + fprintf(stderr, "%s\n", msg.c_str()); + } else { + fprintf(stdout, "%s\n", msg.c_str()); + } +} + +void ConsoleSink::Flush() {} + +ConsoleSink::ConsoleSink() {} + +} // namespace tile diff --git a/tile/base/logging/console_sink.h b/tile/base/logging/console_sink.h new file mode 100644 index 0000000..332930a --- /dev/null +++ b/tile/base/logging/console_sink.h @@ -0,0 +1,25 @@ +#ifndef TILE_BASE_LOGGING_CONSOLE_SINK_H +#define TILE_BASE_LOGGING_CONSOLE_SINK_H + +#pragma once + +#include "tile/base/internal/logging.h" +namespace tile { +class ConsoleSink : public LogSink { +public: + using Ptr = std::shared_ptr; + static Ptr Create(); + + ~ConsoleSink() override; + void Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) override; + void Flush() override; + +protected: + ConsoleSink(); +}; +} // namespace tile + +#endif // TILE_BASE_LOGGING_CONSOLE_SINK_H diff --git a/tile/base/logging/splitter_sink.cc b/tile/base/logging/splitter_sink.cc new file mode 100644 index 0000000..e658d94 --- /dev/null +++ b/tile/base/logging/splitter_sink.cc @@ -0,0 +1,63 @@ +#include "tile/base/logging/splitter_sink.h" +#include + +namespace tile { +std::shared_ptr SplitterSink::Create() { + return std::shared_ptr(new SplitterSink()); +} + +std::shared_ptr SplitterSink::Create( + std::initializer_list> init_list) { + auto sink = Create(); + for (auto &s : init_list) { + sink->AddSink(s); + } + return sink; +} + +SplitterSink::SplitterSink() {} +SplitterSink::~SplitterSink() {} +void SplitterSink::Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) { + assert(!doing_ && "SplitterSink::send() should not be called recursively"); + std::lock_guard _(sinks_mutex_); + doing_ = true; + for (auto &sink : sinks_) { + sink->Send(severity, full_filename, base_filename, line, logmsgtime, + message, message_len); + } + doing_ = false; +} + +void SplitterSink::Flush() { + assert(!doing_ && "SplitterSink::send() should not be called recursively"); + std::lock_guard _(sinks_mutex_); + doing_ = true; + for (auto &sink : sinks_) { + sink->Flush(); + } + doing_ = false; +} + +void SplitterSink::AddSink(std::shared_ptr sink) { + std::lock_guard _(sinks_mutex_); + sinks_.insert(sink); +} + +void SplitterSink::RemoveSink(std::shared_ptr sink) { + std::lock_guard _(sinks_mutex_); + sinks_.erase(sink); +} + +void SplitterSink::ClearSinks() { + std::lock_guard _(sinks_mutex_); + sinks_.clear(); +} +std::set SplitterSink::sinks() { + std::lock_guard _(sinks_mutex_); + return sinks_; +} + +} // namespace tile diff --git a/tile/base/logging/splitter_sink.h b/tile/base/logging/splitter_sink.h new file mode 100644 index 0000000..082c29a --- /dev/null +++ b/tile/base/logging/splitter_sink.h @@ -0,0 +1,40 @@ +#ifndef TILE_BASE_LOGGING_SPLITTER_SINK_H +#define TILE_BASE_LOGGING_SPLITTER_SINK_H + +#pragma once +#include "tile/base/internal/logging.h" + +#include +#include + +namespace tile { +class SplitterSink : public LogSink { +public: + using Ptr = std::shared_ptr; + static Ptr Create(); + static Ptr Create(std::initializer_list> init_list); + + ~SplitterSink() override; + + void Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) override; + void Flush() override; + + void AddSink(std::shared_ptr sink); + void RemoveSink(std::shared_ptr sink); + void ClearSinks(); + std::set sinks(); + +protected: + SplitterSink(); + +private: + std::set> sinks_; + std::mutex sinks_mutex_; + bool doing_ = false; +}; +} // namespace tile + +#endif // TILE_BASE_LOGGING_SPLITTER_SINK_H diff --git a/tile/base/logging/splitter_sink_test.cc b/tile/base/logging/splitter_sink_test.cc new file mode 100644 index 0000000..87af503 --- /dev/null +++ b/tile/base/logging/splitter_sink_test.cc @@ -0,0 +1,56 @@ +#include "tile/base/logging/splitter_sink.h" +#include "gtest/gtest.h" + +namespace tile { +class SimpleSink : public LogSink { +public: + using Ptr = std::shared_ptr; + static Ptr Create() { return std::shared_ptr(new SimpleSink()); } + void Send(LogSeverity severity, const char *full_filename, + const char *base_filename, int line, + const LogMessageTime &logmsgtime, const char *message, + size_t message_len) override { + message_ = std::string(message, message_len); + } + void Flush() override {} + std::string message_; +}; + +TEST(SplitterSink, One) { + auto sink = SimpleSink::Create(); + auto splitter = SplitterSink::Create({sink}); + splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), + "message", 7); + ASSERT_EQ(sink->message_, "message"); +} + +TEST(SplitterSink, Two) { + auto sink1 = SimpleSink::Create(); + auto sink2 = SimpleSink::Create(); + auto splitter = SplitterSink::Create({sink1, sink2}); + splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), + "message", 7); + ASSERT_EQ(sink1->message_, "message"); + ASSERT_EQ(sink2->message_, "message"); +} + +TEST(SplitterSink, Multi) { + auto splitter = SplitterSink::Create(); + for (int i = 0; i < 100; i++) { + splitter->AddSink(SimpleSink::Create()); + } + + for (int i = 0; i < 100; i++) { + std::stringstream ss; + ss << "message" << i; + auto msg = ss.str(); + splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, + LogMessageTime(), msg.data(), msg.size()); + + for (auto &sink : splitter->sinks()) { + ASSERT_EQ(std::static_pointer_cast(sink)->message_, msg); + } + } +} + +} // namespace tile diff --git a/tile/init.cc b/tile/init.cc index bcde904..18b5858 100644 --- a/tile/init.cc +++ b/tile/init.cc @@ -6,6 +6,7 @@ #include "tile/base/internal/time_keeper.h" #include "tile/base/internal/utility.h" #include "tile/base/logging.h" +#include "tile/base/logging/console_sink.h" #include "tile/base/option.h" #include "tile/base/thread/latch.h" #include "tile/init/on_init.h" @@ -13,8 +14,8 @@ #include "tile/net/internal/http_engine.h" #include "gflags/gflags.h" -#include "glog/logging.h" -#include "glog/raw_logging.h" +// #include "glog/logging.h" +// #include "glog/raw_logging.h" #include #include @@ -33,7 +34,8 @@ std::atomic g_quit_siganl{false}; void QuitSignalHandler(int sig) { auto old = g_quit_siganl.exchange(true, std::memory_order_relaxed); if (old && FLAGS_tile_abort_on_double_quit_signal) { - RAW_LOG(FATAL, "Double quit signal received. Crashing the program"); + // TODO: Add TILE_RAW_LOG + // RAW_LOG(FATAL, "Double quit signal received. Crashing the program"); } } @@ -49,9 +51,9 @@ void InstallQuitSignalHandler() { int Start(int argc, char **argv, std::function cb, bool single_thread, bool enable_crash_catch) { - // glog if (enable_crash_catch) { - google::InstallFailureSignalHandler(); + // TODO: Add InstallFailureSignalHandler + // google::InstallFailureSignalHandler(); } // Init gflags @@ -59,8 +61,10 @@ int Start(int argc, char **argv, std::function cb, gflags::ParseCommandLineFlags(&argc, &argv, true); detail::ApplyFlagOverrider(); - // Init Glog - google::InitGoogleLogging(argv[0]); + AddLogSink(ConsoleSink::Create()); + + // TODO: Add Init log level + // google::InitGoogleLogging(argv[0]); TILE_LOG_INFO("Tile started. version: {}", TILE_VERSION); diff --git a/tile/testing/bm_main.cc b/tile/testing/bm_main.cc index 9330183..a322e97 100644 --- a/tile/testing/bm_main.cc +++ b/tile/testing/bm_main.cc @@ -3,7 +3,6 @@ #include "benchmark/benchmark.h" #include "gflags/gflags.h" -#include "glog/logging.h" #include "tile/base/logging.h" #include "tile/init.h" @@ -11,29 +10,27 @@ namespace tile { namespace testing { namespace { -int -StartBenchmark(int argc, char **argv) -{ - ::benchmark::Initialize(&argc, argv); - if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; } - ::benchmark::RunSpecifiedBenchmarks(); - ::benchmark::Shutdown(); - return 0; +int StartBenchmark(int argc, char **argv) { + ::benchmark::Initialize(&argc, argv); + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { + return 1; + } + ::benchmark::RunSpecifiedBenchmarks(); + ::benchmark::Shutdown(); + return 0; } -}// namespace +} // namespace -int -InitAndRunAllBenchmarks(int *argc, char **argv) -{ +int InitAndRunAllBenchmarks(int *argc, char **argv) { - // if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) { - // FLAGS_logtostderr = true; - // } + // if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) { + // FLAGS_logtostderr = true; + // } - return Start(*argc, argv, StartBenchmark, true); + return Start(*argc, argv, StartBenchmark, true); } -}// namespace testing -}// namespace tile +} // namespace testing +} // namespace tile TILE_BENCHMARK_MAIN diff --git a/tile/testing/main.cc b/tile/testing/main.cc index 69ffa25..387b6a6 100644 --- a/tile/testing/main.cc +++ b/tile/testing/main.cc @@ -1,7 +1,7 @@ #include "tile/testing/main.h" #include "gflags/gflags.h" -#include "glog/logging.h" +// #include "glog/logging.h" #include "tile/init.h" #include "gtest/gtest.h"