Merge remote-tracking branch 'origin/master' into feat/update_config
This commit is contained in:
commit
635db57230
@ -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"
|
||||
@ -217,7 +221,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)
|
||||
@ -230,8 +234,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
|
||||
@ -241,7 +245,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)
|
||||
@ -302,9 +306,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 ".cpp" "" TEST_NAME "${TEST_NAME}")
|
||||
string(REPLACE ".cc" "" TEST_NAME "${TEST_NAME}")
|
||||
string(REPLACE ".c" "" 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}")
|
||||
|
@ -1,8 +1,3 @@
|
||||
## TILE
|
||||
一个`C++11`工具库,集成常见的编码工具
|
||||
|
||||
|
||||
## 编译状态
|
||||
[![status-badge](https://ci.uocat.com/api/badges/2/status.svg)](https://ci.uocat.com/repos/2)
|
||||
|
||||
|
||||
|
58
third_party/glog/.bazelci/presubmit.yml
vendored
58
third_party/glog/.bazelci/presubmit.yml
vendored
@ -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:
|
||||
- "//..."
|
168
third_party/glog/.clang-format
vendored
168
third_party/glog/.clang-format
vendored
@ -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: '^<ext/.*\.h>'
|
||||
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
|
||||
...
|
||||
|
59
third_party/glog/.clang-tidy
vendored
59
third_party/glog/.clang-tidy
vendored
@ -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'
|
||||
...
|
||||
|
1
third_party/glog/.gitattributes
vendored
1
third_party/glog/.gitattributes
vendored
@ -1 +0,0 @@
|
||||
*.h linguist-language=C++
|
51
third_party/glog/.github/workflows/android.yml
vendored
51
third_party/glog/.github/workflows/android.yml
vendored
@ -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}}
|
150
third_party/glog/.github/workflows/linux.yml
vendored
150
third_party/glog/.github/workflows/linux.yml
vendored
@ -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
|
83
third_party/glog/.github/workflows/macos.yml
vendored
83
third_party/glog/.github/workflows/macos.yml
vendored
@ -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
|
234
third_party/glog/.github/workflows/windows.yml
vendored
234
third_party/glog/.github/workflows/windows.yml
vendored
@ -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$<$<CONFIG:Debug>: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
|
3
third_party/glog/.gitignore
vendored
3
third_party/glog/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
*.orig
|
||||
/build*/
|
||||
bazel-*
|
29
third_party/glog/AUTHORS
vendored
29
third_party/glog/AUTHORS
vendored
@ -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 <email address>
|
||||
# The email address is not required for organizations.
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Abhishek Dasgupta <abhi2743@gmail.com>
|
||||
Abhishek Parmar <abhishek@orng.net>
|
||||
Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
|
||||
Andy Ying <andy@trailofbits.com>
|
||||
Brian Silverman <bsilver16384@gmail.com>
|
||||
Dmitriy Arbitman <d.arbitman@gmail.com>
|
||||
Google Inc.
|
||||
Guillaume Dumont <dumont.guillaume@gmail.com>
|
||||
Marco Wang <m.aesophor@gmail.com>
|
||||
Michael Tanner <michael@tannertaxpro.com>
|
||||
MiniLight <MiniLightAR@Gmail.com>
|
||||
romange <romange@users.noreply.github.com>
|
||||
Roman Perepelitsa <roman.perepelitsa@gmail.com>
|
||||
Sergiu Deitsch <sergiu.deitsch@gmail.com>
|
||||
tbennun <tbennun@gmail.com>
|
||||
Teddy Reed <teddy@prosauce.org>
|
||||
Vijaymahantesh Sattigeri <vijaymahantesh016@gmail.com>
|
||||
Zhongming Qu <qzmfranklin@gmail.com>
|
||||
Zhuoran Shen <cmsflash99@gmail.com>
|
22
third_party/glog/BUILD.bazel
vendored
22
third_party/glog/BUILD.bazel
vendored
@ -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",
|
||||
],
|
||||
)
|
1139
third_party/glog/CMakeLists.txt
vendored
1139
third_party/glog/CMakeLists.txt
vendored
File diff suppressed because it is too large
Load Diff
52
third_party/glog/CONTRIBUTORS
vendored
52
third_party/glog/CONTRIBUTORS
vendored
@ -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 <email address>
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Abhishek Dasgupta <abhi2743@gmail.com>
|
||||
Abhishek Parmar <abhishek@orng.net>
|
||||
Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
|
||||
Andy Ying <andy@trailofbits.com>
|
||||
Bret McKee <bretmckee@google.com>
|
||||
Brian Silverman <bsilver16384@gmail.com>
|
||||
Dmitriy Arbitman <d.arbitman@gmail.com>
|
||||
Fumitoshi Ukai <ukai@google.com>
|
||||
Guillaume Dumont <dumont.guillaume@gmail.com>
|
||||
Håkan L. S. Younes <hyounes@google.com>
|
||||
Ivan Penkov <ivanpe@google.com>
|
||||
Jacob Trimble <modmaker@google.com>
|
||||
Jim Ray <jimray@google.com>
|
||||
Marco Wang <m.aesophor@gmail.com>
|
||||
Michael Darr <mdarr@matician.com>
|
||||
Michael Tanner <michael@tannertaxpro.com>
|
||||
MiniLight <MiniLightAR@Gmail.com>
|
||||
Peter Collingbourne <pcc@google.com>
|
||||
Rodrigo Queiro <rodrigoq@google.com>
|
||||
romange <romange@users.noreply.github.com>
|
||||
Roman Perepelitsa <roman.perepelitsa@gmail.com>
|
||||
Sergiu Deitsch <sergiu.deitsch@gmail.com>
|
||||
Shinichiro Hamaji <hamaji@google.com>
|
||||
tbennun <tbennun@gmail.com>
|
||||
Teddy Reed <teddy@prosauce.org>
|
||||
Vijaymahantesh Sattigeri <vijaymahantesh016@gmail.com>
|
||||
Zhongming Qu <qzmfranklin@gmail.com>
|
||||
Zhuoran Shen <cmsflash99@gmail.com>
|
65
third_party/glog/COPYING
vendored
65
third_party/glog/COPYING
vendored
@ -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 <j@w1.fi> 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.
|
109
third_party/glog/ChangeLog
vendored
109
third_party/glog/ChangeLog
vendored
@ -1,109 +0,0 @@
|
||||
2022-04-05 Google Inc. <opensource@google.com>
|
||||
|
||||
* google-glog: version 0.6.0.
|
||||
* See git log for the details.
|
||||
|
||||
2021-05-08 Google Inc. <opensource@google.com>
|
||||
|
||||
* google-glog: version 0.5.0.
|
||||
* See git log for the details.
|
||||
|
||||
2019-01-22 Google Inc. <opensource@google.com>
|
||||
|
||||
* google-glog: version 0.4.0.
|
||||
* See git log for the details.
|
||||
|
||||
2017-05-09 Google Inc. <opensource@google.com>
|
||||
|
||||
* google-glog: version 0.3.5
|
||||
* See git log for the details.
|
||||
|
||||
2015-03-09 Google Inc. <opensource@google.com>
|
||||
|
||||
* google-glog: version 0.3.4
|
||||
* See git log for the details.
|
||||
|
||||
2013-02-01 Google Inc. <opensource@google.com>
|
||||
|
||||
* 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. <opensource@google.com>
|
||||
|
||||
* 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. <opensource@google.com>
|
||||
|
||||
* 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. <opensource@google.com>
|
||||
|
||||
* 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. <opensource@google.com>
|
||||
* 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. <opensource@google.com>
|
||||
* 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. <opensource@google.com>
|
||||
* 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. <opensource@google.com>
|
||||
* 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. <opensource@google.com>
|
||||
|
||||
* 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.
|
879
third_party/glog/README.rst
vendored
879
third_party/glog/README.rst
vendored
@ -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``\ (<a
|
||||
particular `severity level <#severity-levels>`__>), e.g.,
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Initialize Google’s logging library.
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
// ...
|
||||
LOG(INFO) << "Found " << num_cookies << " cookies";
|
||||
}
|
||||
|
||||
|
||||
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 <https://bazel.build/>`__ 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
|
||||
<glog/logging.h>` 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 <http://www.cmake.org>`__.
|
||||
|
||||
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 <generator-name>`, and see :cmd:`cmake --help`
|
||||
for the available generators. Also see :cmd:`-T <toolset-name>`, 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
|
||||
<https://github.com/Microsoft/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
|
||||
<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/\<program name\>.\<hostname\>.\<user name\>.log.\<severity level\>.\<date\>-\<time\>.\<pid\>``
|
||||
(e.g.,
|
||||
``/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474``).
|
||||
By default, glog copies the log messages of severity level ``ERROR`` or
|
||||
``FATAL`` to standard error (``stderr``) in addition to log files.
|
||||
|
||||
Setting Flags
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Several flags influence glog’s output behavior. If the `Google gflags library
|
||||
<https://github.com/gflags/gflags>`__ 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 <module name>=<log level>. <module name> is a
|
||||
glob pattern (e.g., ``gfs*`` for all modules whose name starts with
|
||||
"gfs"), matched against the filename base (that is, name ignoring
|
||||
.cc/.h./-inl.h). <log level> overrides any value given by :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<SomeType*>(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 ``<glog/raw_logging.h>`` can be used for thread-safe logging,
|
||||
which does not allocate any memory or acquire any locks. Therefore, the macros
|
||||
defined in this header file can be used by low-level memory allocation and
|
||||
synchronization code. Please check `src/glog/raw_logging.h.in
|
||||
<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 <glog/logging.h>
|
||||
|
||||
The compiler will remove the log messages whose severities are less than
|
||||
the specified integer value. Since ``VLOG`` logs at the severity level
|
||||
``INFO`` (numeric value ``0``), setting ``GOOGLE_STRIP_LOG`` to 1 or
|
||||
greater removes all log messages associated with ``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 <windows.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
// ...
|
||||
|
||||
LOG(ERROR) << "This should work";
|
||||
LOG_IF(ERROR, x > y) << "This should be also OK";
|
||||
|
||||
However, you cannot use ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL``
|
||||
anymore for functions defined in ``glog/logging.h`` .
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
#define GLOG_NO_ABBREVIATED_SEVERITIES
|
||||
#include <windows.h>
|
||||
#include <glog/logging.h>
|
||||
|
||||
// ...
|
||||
|
||||
// This won’t work.
|
||||
// google::FlushLogFiles(google::ERROR);
|
||||
|
||||
// Use this instead.
|
||||
google::FlushLogFiles(google::GLOG_ERROR);
|
||||
|
||||
If you don’t need ``ERROR`` defined by ``windows.h``, there are a couple
|
||||
of more workarounds which sometimes don’t work:
|
||||
|
||||
- ``#define WIN32_LEAN_AND_MEAN`` or ``NOGDI`` **before** you
|
||||
``#include windows.h``.
|
||||
- ``#undef ERROR`` **after** you ``#include windows.h`` .
|
||||
|
||||
See `this
|
||||
issue <http://code.google.com/p/google-glog/issues/detail?id=33>`__ 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 <http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz>`__.
|
||||
|
||||
Even if you already have ``libunwind`` installed, you will probably
|
||||
still need to install from the snapshot to get the latest version.
|
||||
|
||||
Caution: if you install libunwind from the URL above, be aware that you
|
||||
may have trouble if you try to statically link your binary with glog:
|
||||
that is, if you link with ``gcc -static -lgcc_eh ...``. This is because
|
||||
both ``libunwind`` and ``libgcc`` implement the same C++ exception
|
||||
handling APIs, but they implement them differently on some platforms.
|
||||
This is not likely to be a problem on ia64, but may be on x86-64.
|
||||
|
||||
Also, if you link binaries statically, make sure that you add
|
||||
: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 <https://developers.google.com/open-source/cla/individual>`__.
|
||||
* If you work for a company that wants to allow you to contribute your
|
||||
work, then you’ll need to sign a `corporate
|
||||
CLA <https://developers.google.com/open-source/cla/corporate>`__.
|
||||
|
||||
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 <https://help.github.com/articles/creating-a-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 <https://help.github.com/articles/fork-a-repo>`__ 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 <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`__
|
||||
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 <https://help.github.com/articles/creating-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
|
11
third_party/glog/WORKSPACE
vendored
11
third_party/glog/WORKSPACE
vendored
@ -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",
|
||||
],
|
||||
)
|
9
third_party/glog/bazel/example/BUILD.bazel
vendored
9
third_party/glog/bazel/example/BUILD.bazel
vendored
@ -1,9 +0,0 @@
|
||||
cc_test(
|
||||
name = "main",
|
||||
size = "small",
|
||||
srcs = ["main.cc"],
|
||||
deps = [
|
||||
"//:glog",
|
||||
"@com_github_gflags_gflags//:gflags",
|
||||
],
|
||||
)
|
22
third_party/glog/bazel/example/main.cc
vendored
22
third_party/glog/bazel/example/main.cc
vendored
@ -1,22 +0,0 @@
|
||||
#include <gflags/gflags.h>
|
||||
#include <glog/logging.h>
|
||||
#include <glog/stl_logging.h>
|
||||
|
||||
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<int> x;
|
||||
x.push_back(1);
|
||||
x.push_back(2);
|
||||
x.push_back(3);
|
||||
LOG(INFO) << "ABC, it's easy as " << x;
|
||||
|
||||
return 0;
|
||||
}
|
276
third_party/glog/bazel/glog.bzl
vendored
276
third_party/glog/bazel/glog.bzl
vendored
@ -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",
|
||||
]
|
||||
]
|
@ -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 <gflags/gflags.h>
|
||||
|
||||
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 ()
|
61
third_party/glog/cmake/FindUnwind.cmake
vendored
61
third_party/glog/cmake/FindUnwind.cmake
vendored
@ -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)
|
70
third_party/glog/cmake/GetCacheVariables.cmake
vendored
70
third_party/glog/cmake/GetCacheVariables.cmake
vendored
@ -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)
|
22
third_party/glog/cmake/RunCleanerTest1.cmake
vendored
22
third_party/glog/cmake/RunCleanerTest1.cmake
vendored
@ -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)
|
22
third_party/glog/cmake/RunCleanerTest2.cmake
vendored
22
third_party/glog/cmake/RunCleanerTest2.cmake
vendored
@ -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)
|
28
third_party/glog/cmake/RunCleanerTest3.cmake
vendored
28
third_party/glog/cmake/RunCleanerTest3.cmake
vendored
@ -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})
|
@ -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}")
|
40
third_party/glog/cmake/TestPackageConfig.cmake
vendored
40
third_party/glog/cmake/TestPackageConfig.cmake
vendored
@ -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)
|
13
third_party/glog/glog-config.cmake.in
vendored
13
third_party/glog/glog-config.cmake.in
vendored
@ -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)
|
18
third_party/glog/glog-modules.cmake.in
vendored
18
third_party/glog/glog-modules.cmake.in
vendored
@ -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)
|
11
third_party/glog/libglog.pc.in
vendored
11
third_party/glog/libglog.pc.in
vendored
@ -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}
|
147
third_party/glog/src/base/commandlineflags.h
vendored
147
third_party/glog/src/base/commandlineflags.h
vendored
@ -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 <cstdlib> // for getenv
|
||||
#include <cstring> // for memchr
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#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__
|
51
third_party/glog/src/base/googleinit.h
vendored
51
third_party/glog/src/base/googleinit.h
vendored
@ -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 */
|
333
third_party/glog/src/base/mutex.h
vendored
333
third_party/glog/src/base/mutex.h
vendored
@ -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 <windows.h>
|
||||
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 <pthread.h>
|
||||
typedef pthread_rwlock_t MutexType;
|
||||
#elif defined(HAVE_PTHREAD)
|
||||
# include <pthread.h>
|
||||
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 <cassert>
|
||||
#include <cstdlib> // 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__ */
|
@ -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 <glog/logging.h>
|
||||
#include <glog/raw_logging.h>
|
||||
|
||||
#include "base/commandlineflags.h"
|
||||
#include "googletest.h"
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
using namespace GFLAGS_NAMESPACE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIB_GMOCK
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#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);
|
||||
}
|
@ -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 <glog/logging.h>
|
||||
#include <glog/raw_logging.h>
|
||||
|
||||
#include "base/commandlineflags.h"
|
||||
#include "googletest.h"
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
using namespace GFLAGS_NAMESPACE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIB_GMOCK
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#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);
|
||||
}
|
@ -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 <glog/logging.h>
|
||||
#include <glog/raw_logging.h>
|
||||
|
||||
#include "base/commandlineflags.h"
|
||||
#include "googletest.h"
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
using namespace GFLAGS_NAMESPACE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIB_GMOCK
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#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);
|
||||
}
|
231
third_party/glog/src/config.h.cmake.in
vendored
231
third_party/glog/src/config.h.cmake.in
vendored
@ -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 <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
||||
#cmakedefine HAVE_EXECINFO_H
|
||||
|
||||
/* Define if you have the `fcntl' function */
|
||||
#cmakedefine HAVE_FCNTL
|
||||
|
||||
/* Define to 1 if you have the <glob.h> header file. */
|
||||
#cmakedefine HAVE_GLOB_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> 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 <memory.h> 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 <pwd.h> 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 <stdint.h> header file. */
|
||||
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <syscall.h> header file. */
|
||||
#cmakedefine HAVE_SYSCALL_H
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#cmakedefine HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#cmakedefine HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/syscall.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SYSCALL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
|
||||
|
||||
/* Define to 1 if you have the <sys/ucontext.h> header file. */
|
||||
#cmakedefine HAVE_SYS_UCONTEXT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#cmakedefine HAVE_SYS_UTSNAME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#cmakedefine HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <ucontext.h> header file. */
|
||||
#cmakedefine HAVE_UCONTEXT_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
|
||||
|
||||
/* Define if you have the <unwind.h> 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
|
1364
third_party/glog/src/demangle.cc
vendored
1364
third_party/glog/src/demangle.cc
vendored
File diff suppressed because it is too large
Load Diff
85
third_party/glog/src/demangle.h
vendored
85
third_party/glog/src/demangle.h
vendored
@ -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>(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<char,
|
||||
// | | | std::char_traits<char>,
|
||||
// | | | std::allocator<char> >)
|
||||
//
|
||||
// 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 <glog/logging.h>
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// Demangle "mangled". On success, return true and write the
|
||||
// demangled symbol name to "out". Otherwise, return false.
|
||||
// "out" is modified even if demangling is unsuccessful.
|
||||
bool GLOG_EXPORT Demangle(const char *mangled, char *out, size_t out_size);
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // BASE_DEMANGLE_H_
|
170
third_party/glog/src/demangle_unittest.cc
vendored
170
third_party/glog/src/demangle_unittest.cc
vendored
@ -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 <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <glog/logging.h>
|
||||
#include "demangle.h"
|
||||
#include "googletest.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
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();
|
||||
}
|
||||
}
|
95
third_party/glog/src/demangle_unittest.sh
vendored
95
third_party/glog/src/demangle_unittest.sh
vendored
@ -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
|
145
third_party/glog/src/demangle_unittest.txt
vendored
145
third_party/glog/src/demangle_unittest.txt
vendored
@ -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<>()
|
98
third_party/glog/src/glog/log_severity.h
vendored
98
third_party/glog/src/glog/log_severity.h
vendored
@ -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__
|
2002
third_party/glog/src/glog/logging.h.in
vendored
2002
third_party/glog/src/glog/logging.h.in
vendored
File diff suppressed because it is too large
Load Diff
58
third_party/glog/src/glog/platform.h
vendored
58
third_party/glog/src/glog/platform.h
vendored
@ -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
|
179
third_party/glog/src/glog/raw_logging.h.in
vendored
179
third_party/glog/src/glog/raw_logging.h.in
vendored
@ -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 <ctime>
|
||||
|
||||
@ac_google_start_namespace@
|
||||
|
||||
#include <glog/log_severity.h>
|
||||
#include <glog/logging.h>
|
||||
#include <glog/vlog_is_on.h>
|
||||
|
||||
#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
|
220
third_party/glog/src/glog/stl_logging.h.in
vendored
220
third_party/glog/src/glog/stl_logging.h.in
vendored
@ -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<string> x;
|
||||
// LOG(INFO) << "data: " << x;
|
||||
// vector<int> 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 - <unordered_map> and <unordered_set>
|
||||
// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
|
||||
// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)>
|
||||
// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <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 <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
|
||||
# include <unordered_map>
|
||||
# include <unordered_set>
|
||||
#endif
|
||||
|
||||
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
|
||||
# include <tr1/unordered_map>
|
||||
# include <tr1/unordered_set>
|
||||
#endif
|
||||
|
||||
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
|
||||
# include <ext/hash_set>
|
||||
# include <ext/hash_map>
|
||||
#endif
|
||||
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
|
||||
# include <ext/slist>
|
||||
#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<class First, class Second>
|
||||
std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
|
||||
|
||||
@ac_google_start_namespace@
|
||||
|
||||
template<class Iter>
|
||||
void PrintSequence(std::ostream& out, Iter begin, Iter end);
|
||||
|
||||
@ac_google_end_namespace@
|
||||
|
||||
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
|
||||
template<class T1, class T2> \
|
||||
inline std::ostream& operator<<(std::ostream& out, \
|
||||
const Sequence<T1, T2>& 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<class T1, class T2, class T3> \
|
||||
inline std::ostream& operator<<(std::ostream& out, \
|
||||
const Sequence<T1, T2, T3>& 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<class T1, class T2, class T3, class T4> \
|
||||
inline std::ostream& operator<<(std::ostream& out, \
|
||||
const Sequence<T1, T2, T3, T4>& 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<class T1, class T2, class T3, class T4, class T5> \
|
||||
inline std::ostream& operator<<(std::ostream& out, \
|
||||
const Sequence<T1, T2, T3, T4, T5>& 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<class First, class Second>
|
||||
inline std::ostream& operator<<(std::ostream& out,
|
||||
const std::pair<First, Second>& p) {
|
||||
out << '(' << p.first << ", " << p.second << ')';
|
||||
return out;
|
||||
}
|
||||
|
||||
@ac_google_start_namespace@
|
||||
|
||||
template<class Iter>
|
||||
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<class T>
|
||||
// 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_
|
118
third_party/glog/src/glog/vlog_is_on.h.in
vendored
118
third_party/glog/src/glog/vlog_is_on.h.in
vendored
@ -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=<n> Gives the default maximal active V-logging level;
|
||||
// 0 is the default.
|
||||
// Normally positive values are used for V-logging levels.
|
||||
// --vmodule=<str> Gives the per-module maximal V-logging levels to override
|
||||
// the value given by --v.
|
||||
// E.g. "my_module=2,foo*=3" would change the logging level
|
||||
// for all code in source files "my_module.*" and "foo*.*"
|
||||
// ("-inl" suffixes are also disregarded for this matching).
|
||||
//
|
||||
// SetVLOGLevel helper function is provided to do limited dynamic control over
|
||||
// V-logging by overriding the per-module settings given via --vmodule flag.
|
||||
//
|
||||
// CAVEAT: --vmodule functionality is not available in non gcc compilers.
|
||||
//
|
||||
|
||||
#ifndef BASE_VLOG_IS_ON_H_
|
||||
#define BASE_VLOG_IS_ON_H_
|
||||
|
||||
#include <glog/log_severity.h>
|
||||
|
||||
#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_
|
672
third_party/glog/src/googletest.h
vendored
672
third_party/glog/src/googletest.h
vendored
@ -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 <cctype>
|
||||
#include <csetjmp>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#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<string> 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/<project name>
|
||||
// (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 <gtest/gtest.h>
|
||||
// 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<void (*)()> 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<void (*)()>::const_iterator it;
|
||||
for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
|
||||
(*it)();
|
||||
}
|
||||
fprintf(stderr, "Passed %d tests\n\nPASS\n",
|
||||
static_cast<int>(g_testlist.size()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // ! HAVE_LIB_GTEST
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
static bool g_called_abort;
|
||||
static jmp_buf g_jmp_buf;
|
||||
static inline void CalledAbort() {
|
||||
g_called_abort = true;
|
||||
longjmp(g_jmp_buf, 1);
|
||||
}
|
||||
|
||||
#ifdef 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<string, void (*)(int)> 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<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
|
||||
iter != g_benchlist.end();
|
||||
++iter) {
|
||||
clock_t start = clock();
|
||||
iter->second(iter_cnt);
|
||||
double elapsed_ns = (static_cast<double>(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<size_t>(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<void*>(NULL));
|
||||
snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(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<Thread*>(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);
|
||||
}
|
2691
third_party/glog/src/logging.cc
vendored
2691
third_party/glog/src/logging.cc
vendored
File diff suppressed because it is too large
Load Diff
1384
third_party/glog/src/logging_custom_prefix_unittest.cc
vendored
1384
third_party/glog/src/logging_custom_prefix_unittest.cc
vendored
File diff suppressed because it is too large
Load Diff
@ -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
|
79
third_party/glog/src/logging_striplog_test.sh
vendored
79
third_party/glog/src/logging_striplog_test.sh
vendored
@ -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"
|
35
third_party/glog/src/logging_striptest10.cc
vendored
35
third_party/glog/src/logging_striptest10.cc
vendored
@ -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"
|
35
third_party/glog/src/logging_striptest2.cc
vendored
35
third_party/glog/src/logging_striptest2.cc
vendored
@ -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"
|
73
third_party/glog/src/logging_striptest_main.cc
vendored
73
third_party/glog/src/logging_striptest_main.cc
vendored
@ -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 <cstdio>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <glog/logging.h>
|
||||
#include "base/commandlineflags.h"
|
||||
#include "config.h"
|
||||
|
||||
DECLARE_bool(logtostderr);
|
||||
GLOG_DEFINE_bool(check_mode, false, "Prints 'opt' or 'dbg'");
|
||||
|
||||
using std::string;
|
||||
using namespace GOOGLE_NAMESPACE;
|
||||
|
||||
int CheckNoReturn(bool b) {
|
||||
string s;
|
||||
if (b) {
|
||||
LOG(FATAL) << "Fatal";
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct A { };
|
||||
std::ostream &operator<<(std::ostream &str, const A&) {return str;}
|
||||
|
||||
int main(int, char* argv[]) {
|
||||
FLAGS_logtostderr = true;
|
||||
InitGoogleLogging(argv[0]);
|
||||
if (FLAGS_check_mode) {
|
||||
printf("%s\n", DEBUG_MODE ? "dbg" : "opt");
|
||||
return 0;
|
||||
}
|
||||
LOG(INFO) << "TESTMESSAGE INFO";
|
||||
LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING"
|
||||
<< 1 << 'c' << A() << std::endl;
|
||||
LOG(ERROR) << "TESTMESSAGE ERROR";
|
||||
bool flag = true;
|
||||
(flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND";
|
||||
LOG(FATAL) << "TESTMESSAGE FATAL";
|
||||
}
|
1477
third_party/glog/src/logging_unittest.cc
vendored
1477
third_party/glog/src/logging_unittest.cc
vendored
File diff suppressed because it is too large
Load Diff
308
third_party/glog/src/logging_unittest.err
vendored
308
third_party/glog/src/logging_unittest.err
vendored
@ -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
|
150
third_party/glog/src/logging_unittest.out
vendored
150
third_party/glog/src/logging_unittest.out
vendored
@ -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
|
156
third_party/glog/src/mock-log.h
vendored
156
third_party/glog/src/mock-log.h
vendored
@ -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 <string>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
namespace glog_testing {
|
||||
|
||||
// A ScopedMockLog object intercepts LOG() messages issued during its
|
||||
// lifespan. Using this together with Google C++ Mocking Framework,
|
||||
// it's very easy to test how a piece of code calls LOG(). The
|
||||
// typical usage:
|
||||
//
|
||||
// TEST(FooTest, LogsCorrectly) {
|
||||
// ScopedMockLog log;
|
||||
//
|
||||
// // We expect the WARNING "Something bad!" exactly twice.
|
||||
// EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
|
||||
// .Times(2);
|
||||
//
|
||||
// // We allow foo.cc to call LOG(INFO) any number of times.
|
||||
// EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
|
||||
// .Times(AnyNumber());
|
||||
//
|
||||
// Foo(); // Exercises the code under test.
|
||||
// }
|
||||
class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
|
||||
public:
|
||||
// When a ScopedMockLog object is constructed, it starts to
|
||||
// intercept logs.
|
||||
ScopedMockLog() { AddLogSink(this); }
|
||||
|
||||
// When the object is destructed, it stops intercepting logs.
|
||||
~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_
|
108
third_party/glog/src/mock-log_unittest.cc
vendored
108
third_party/glog/src/mock-log_unittest.cc
vendored
@ -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 <string>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
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();
|
||||
}
|
@ -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)
|
@ -1,6 +0,0 @@
|
||||
#include <glog/logging.h>
|
||||
|
||||
int main(int /*argc*/, char** argv)
|
||||
{
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
}
|
178
third_party/glog/src/raw_logging.cc
vendored
178
third_party/glog/src/raw_logging.cc
vendored
@ -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 <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h> // for close() and write()
|
||||
#endif
|
||||
#include <fcntl.h> // for open()
|
||||
#include <ctime>
|
||||
#include "config.h"
|
||||
#include <glog/logging.h> // To pick up flag settings etc.
|
||||
#include <glog/raw_logging.h>
|
||||
#include "base/commandlineflags.h"
|
||||
|
||||
#ifdef HAVE_STACKTRACE
|
||||
# include "stacktrace.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYSCALL_H)
|
||||
#include <syscall.h> // for syscall()
|
||||
#elif defined(HAVE_SYS_SYSCALL_H)
|
||||
#include <sys/syscall.h> // for syscall()
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#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<size_t>(n) > *size) return false;
|
||||
*size -= static_cast<size_t>(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<size_t>(n) > *size) return false;
|
||||
*size -= static_cast<size_t>(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<unsigned int>(GetTID()),
|
||||
const_basename(const_cast<char *>(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_
|
409
third_party/glog/src/signalhandler.cc
vendored
409
third_party/glog/src/signalhandler.cc
vendored
@ -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 <glog/logging.h>
|
||||
|
||||
#include <csignal>
|
||||
#include <ctime>
|
||||
#ifdef HAVE_UCONTEXT_H
|
||||
# include <ucontext.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UCONTEXT_H
|
||||
# include <sys/ucontext.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
_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_t *>(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<std::size_t>(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<char>(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<uint64>(time_in_sec), 10);
|
||||
formatter.AppendString(" (unix time)");
|
||||
formatter.AppendString(" try \"date -d @");
|
||||
formatter.AppendUint64(static_cast<uint64>(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<uint64>(signal_number), 10);
|
||||
}
|
||||
formatter.AppendString(" (@0x");
|
||||
formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
|
||||
formatter.AppendString(")");
|
||||
formatter.AppendString(" received by PID ");
|
||||
formatter.AppendUint64(static_cast<uint64>(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<uint64>(reinterpret_cast<const char*>(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<uint64>(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<char *>(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<uintptr_t>(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<pthread_t*>(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_
|
113
third_party/glog/src/signalhandler_unittest.cc
vendored
113
third_party/glog/src/signalhandler_unittest.cc
vendored
@ -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 <pthread.h>
|
||||
#endif
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <glog/logging.h>
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
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<const void*>(reinterpret_cast<const char*>(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;
|
||||
}
|
131
third_party/glog/src/signalhandler_unittest.sh
vendored
131
third_party/glog/src/signalhandler_unittest.sh
vendored
@ -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
|
61
third_party/glog/src/stacktrace.h
vendored
61
third_party/glog/src/stacktrace.h
vendored
@ -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 <glog/logging.h>
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// This is similar to the GetStackFrames routine, except that it returns
|
||||
// the stack trace only, and not the stack frame sizes as well.
|
||||
// Example:
|
||||
// main() { foo(); }
|
||||
// foo() { bar(); }
|
||||
// bar() {
|
||||
// void* result[10];
|
||||
// int depth = GetStackFrames(result, 10, 1);
|
||||
// }
|
||||
//
|
||||
// This produces:
|
||||
// result[0] foo
|
||||
// result[1] main
|
||||
// .... ...
|
||||
//
|
||||
// "result" must not be NULL.
|
||||
GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // BASE_STACKTRACE_H_
|
62
third_party/glog/src/stacktrace_generic-inl.h
vendored
62
third_party/glog/src/stacktrace_generic-inl.h
vendored
@ -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 <execinfo.h>
|
||||
#include <string.h>
|
||||
#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_
|
93
third_party/glog/src/stacktrace_libunwind-inl.h
vendored
93
third_party/glog/src/stacktrace_libunwind-inl.h
vendored
@ -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 <libunwind.h>
|
||||
}
|
||||
#include <glog/raw_logging.h>
|
||||
#include "stacktrace.h"
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// Sometimes, we can try to get a stack trace from within a stack
|
||||
// trace, because libunwind can call mmap (maybe indirectly via an
|
||||
// internal mmap based memory allocator), and that mmap gets trapped
|
||||
// and causes a stack-trace request. If were to try to honor that
|
||||
// recursive request, we'd end up with infinite recursion or deadlock.
|
||||
// Luckily, it's safe to ignore those subsequent traces. In such
|
||||
// cases, we return 0 to indicate the situation.
|
||||
// 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<unw_word_t *>(&ip));
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
if (skip_count > 0) {
|
||||
skip_count--;
|
||||
} else {
|
||||
result[n++] = ip;
|
||||
}
|
||||
ret = unw_step(&cursor);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_tl_entered = false;
|
||||
return n;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
130
third_party/glog/src/stacktrace_powerpc-inl.h
vendored
130
third_party/glog/src/stacktrace_powerpc-inl.h
vendored
@ -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 <cstdio>
|
||||
#include <stdint.h> // 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<bool STRICT_UNWINDING>
|
||||
static void **NextStackFrame(void **old_sp) {
|
||||
void **new_sp = static_cast<void **>(*old_sp);
|
||||
|
||||
// Check that the transition from frame pointer old_sp to frame
|
||||
// pointer new_sp isn't clearly bogus
|
||||
if (STRICT_UNWINDING) {
|
||||
// With the stack growing downwards, older stack frame must be
|
||||
// at a greater address that the current one.
|
||||
if (new_sp <= old_sp) return NULL;
|
||||
// Assume stack frames larger than 100,000 bytes are bogus.
|
||||
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
|
||||
} else {
|
||||
// In the non-strict mode, allow discontiguous stack frames.
|
||||
// (alternate-signal-stacks for example).
|
||||
if (new_sp == old_sp) return NULL;
|
||||
// And allow frames upto about 1MB.
|
||||
if ((new_sp > old_sp)
|
||||
&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
|
||||
}
|
||||
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
|
||||
return new_sp;
|
||||
}
|
||||
|
||||
// This ensures that GetStackTrace stes up the Link Register properly.
|
||||
void StacktracePowerPCDummyFunction() __attribute__((noinline));
|
||||
void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
|
||||
|
||||
// If you change this function, also change GetStackFrames below.
|
||||
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||
void **sp;
|
||||
// Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
|
||||
// and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a
|
||||
// different asm syntax. I don't know quite the best way to discriminate
|
||||
// systems using the old as from the new one; I've gone with __APPLE__.
|
||||
#ifdef __APPLE__
|
||||
__asm__ volatile ("mr %0,r1" : "=r" (sp));
|
||||
#else
|
||||
__asm__ volatile ("mr %0,1" : "=r" (sp));
|
||||
#endif
|
||||
|
||||
// On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
|
||||
// entry that holds the return address of the subroutine call (what
|
||||
// instruction we run after our function finishes). This is the
|
||||
// same as the stack-pointer of our parent routine, which is what we
|
||||
// want here. While the compiler will always(?) set up LR for
|
||||
// subroutine calls, it may not for leaf functions (such as this one).
|
||||
// This routine forces the compiler (at least gcc) to push it anyway.
|
||||
StacktracePowerPCDummyFunction();
|
||||
|
||||
// The LR save area is used by the callee, so the top entry is bogus.
|
||||
skip_count++;
|
||||
|
||||
int n = 0;
|
||||
while (sp && n < max_depth) {
|
||||
if (skip_count > 0) {
|
||||
skip_count--;
|
||||
} else {
|
||||
// PowerPC has 3 main ABIs, which say where in the stack the
|
||||
// Link Register is. For DARWIN and AIX (used by apple and
|
||||
// linux ppc64), it's in sp[2]. For SYSV (used by linux ppc),
|
||||
// it's in sp[1].
|
||||
#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
|
||||
result[n++] = *(sp+2);
|
||||
#elif defined(_CALL_SYSV)
|
||||
result[n++] = *(sp+1);
|
||||
#elif defined(__APPLE__) || ((defined(__linux) || defined(__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<true>(sp);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
239
third_party/glog/src/stacktrace_unittest.cc
vendored
239
third_party/glog/src/stacktrace_unittest.cc
vendored
@ -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 <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "config.h"
|
||||
#include "base/commandlineflags.h"
|
||||
#include <glog/logging.h>
|
||||
#include "stacktrace.h"
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
# include <execinfo.h>
|
||||
#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<const void *>(&fn); \
|
||||
(prange)->end = reinterpret_cast<const char *>(&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
|
106
third_party/glog/src/stacktrace_unwind-inl.h
vendored
106
third_party/glog/src/stacktrace_unwind-inl.h
vendored
@ -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 <cstdlib> // for NULL
|
||||
#include <unwind.h> // 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<trace_arg_t *>(opq);
|
||||
|
||||
if (targ->skip_count > 0) {
|
||||
targ->skip_count--;
|
||||
} else {
|
||||
targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
|
||||
}
|
||||
|
||||
if (targ->count == targ->max_depth) {
|
||||
return _URC_END_OF_STACK;
|
||||
}
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
// If you change this function, also change GetStackFrames below.
|
||||
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||
if (!ready_to_run) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_arg_t targ;
|
||||
|
||||
skip_count += 1; // Do not include the "GetStackTrace" frame
|
||||
|
||||
targ.result = result;
|
||||
targ.max_depth = max_depth;
|
||||
targ.skip_count = skip_count;
|
||||
targ.count = 0;
|
||||
|
||||
_Unwind_Backtrace(GetOneFrame, &targ);
|
||||
|
||||
return targ.count;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
50
third_party/glog/src/stacktrace_windows-inl.h
vendored
50
third_party/glog/src/stacktrace_windows-inl.h
vendored
@ -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 <dbghelp.h>
|
||||
|
||||
_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<DWORD>(skip_count), static_cast<DWORD>(max_depth), result, NULL);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
147
third_party/glog/src/stacktrace_x86-inl.h
vendored
147
third_party/glog/src/stacktrace_x86-inl.h
vendored
@ -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 <stdint.h> // for uintptr_t
|
||||
|
||||
#include "utilities.h" // for OS_* macros
|
||||
|
||||
#if !defined(GLOG_OS_WINDOWS)
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio> // 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<bool STRICT_UNWINDING>
|
||||
static void **NextStackFrame(void **old_sp) {
|
||||
void **new_sp = static_cast<void **>(*old_sp);
|
||||
|
||||
// Check that the transition from frame pointer old_sp to frame
|
||||
// pointer new_sp isn't clearly bogus
|
||||
if (STRICT_UNWINDING) {
|
||||
// With the stack growing downwards, older stack frame must be
|
||||
// at a greater address that the current one.
|
||||
if (new_sp <= old_sp) return NULL;
|
||||
// Assume stack frames larger than 100,000 bytes are bogus.
|
||||
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
|
||||
} else {
|
||||
// In the non-strict mode, allow discontiguous stack frames.
|
||||
// (alternate-signal-stacks for example).
|
||||
if (new_sp == old_sp) return NULL;
|
||||
// And allow frames upto about 1MB.
|
||||
if ((new_sp > old_sp)
|
||||
&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
|
||||
}
|
||||
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
|
||||
#ifdef __i386__
|
||||
// On 64-bit machines, the stack pointer can be very close to
|
||||
// 0xffffffff, so we explicitly check for a pointer into the
|
||||
// last two pages in the address space
|
||||
if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
|
||||
#endif
|
||||
#if !defined(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<false>() 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<void**>(__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<true>(sp);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
207
third_party/glog/src/stl_logging_unittest.cc
vendored
207
third_party/glog/src/stl_logging_unittest.cc
vendored
@ -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 <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 <glog/logging.h>
|
||||
#include <glog/stl_logging.h>
|
||||
#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<size_t>(x); }
|
||||
};
|
||||
|
||||
static void TestSTLLogging() {
|
||||
{
|
||||
// Test a sequence.
|
||||
vector<int> 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<int> 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<int> 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<int> 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<int, string> 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<int, string> copied_hm(hm);
|
||||
CHECK_EQ(hm, copied_hm); // this must compile
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// Test a long sequence.
|
||||
vector<int> 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<int> > 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<int> > 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<int, user_hash> 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<int, user_hash> 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 <iostream>
|
||||
|
||||
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
|
955
third_party/glog/src/symbolize.cc
vendored
955
third_party/glog/src/symbolize.cc
vendored
@ -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 <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#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<size_t>(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 <dlfcn.h>
|
||||
#endif
|
||||
#if defined(GLOG_OS_OPENBSD)
|
||||
#include <sys/exec_elf.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
#endif
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "symbolize.h"
|
||||
#include "config.h"
|
||||
#include <glog/raw_logging.h>
|
||||
|
||||
// Re-runs fn until it doesn't cause EINTR.
|
||||
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// Read up to "count" bytes from "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<size_t>(std::numeric_limits<ssize_t>::max()));
|
||||
char *buf0 = reinterpret_cast<char *>(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<off_t>(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<size_t>(len);
|
||||
}
|
||||
SAFE_ASSERT(num_bytes <= count);
|
||||
return static_cast<ssize_t>(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<size_t>(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<size_t>(len) % sizeof(buf[0]) == 0);
|
||||
const size_t num_headers_in_buf = static_cast<size_t>(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<size_t>(elf_header.e_shentsize) *
|
||||
static_cast<size_t>(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<size_t>(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<size_t>(len) % sizeof(buf[0]) == 0);
|
||||
const size_t num_symbols_in_buf = static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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<char *>(memchr(bol_, '\n', static_cast<size_t>(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<uint64_t>(ch - '0') : (ch & 0xF) + 9U);
|
||||
} else { // Encountered the first non-hex character.
|
||||
break;
|
||||
}
|
||||
}
|
||||
SAFE_ASSERT(p <= end);
|
||||
return const_cast<char *>(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<uintptr_t>(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<size_t>(num_bytes_written);
|
||||
out_size -= static_cast<size_t>(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 <dlfcn.h>
|
||||
#include <cstring>
|
||||
|
||||
_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 <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#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<SYMBOL_INFO *>(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<DWORD64>(pc), 0, symbol);
|
||||
if (ret == 1 && static_cast<int>(symbol->NameLen) < out_size) {
|
||||
// `NameLen` does not include the null terminating character.
|
||||
strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
|
||||
out[static_cast<size_t>(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 <cassert>
|
||||
|
||||
#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
|
159
third_party/glog/src/symbolize.h
vendored
159
third_party/glog/src/symbolize.h
vendored
@ -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 <glog/logging.h>
|
||||
|
||||
#ifdef HAVE_SYMBOLIZE
|
||||
|
||||
#if defined(__ELF__) // defined by gcc
|
||||
#if defined(__OpenBSD__)
|
||||
#include <sys/exec_elf.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
#endif
|
||||
|
||||
#if !defined(ANDROID)
|
||||
#include <link.h> // 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_
|
447
third_party/glog/src/symbolize_unittest.cc
vendored
447
third_party/glog/src/symbolize_unittest.cc
vendored
@ -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 <csignal>
|
||||
#include <iostream>
|
||||
|
||||
#include "config.h"
|
||||
#include <glog/logging.h>
|
||||
#include "googletest.h"
|
||||
#include "symbolize.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
using namespace GFLAGS_NAMESPACE;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace GOOGLE_NAMESPACE;
|
||||
|
||||
#if defined(HAVE_STACKTRACE)
|
||||
|
||||
#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<void *>(&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<void *>(&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<void *>(&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<void *>(&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<void *>(&Foo::func),
|
||||
&stack_consumed);
|
||||
|
||||
EXPECT_STREQ("Foo::func()", symbol);
|
||||
EXPECT_GT(stack_consumed, 0);
|
||||
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HAVE_SIGALTSTACK
|
||||
|
||||
// x86 specific tests. Uses some inline assembler.
|
||||
extern "C" {
|
||||
inline void* always_inline inline_func() {
|
||||
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 <intrin.h>
|
||||
#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
|
||||
}
|
402
third_party/glog/src/utilities.cc
vendored
402
third_party/glog/src/utilities.cc
vendored
@ -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 <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <csignal>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <ctime>
|
||||
#if defined(HAVE_SYSCALL_H)
|
||||
#include <syscall.h> // for syscall()
|
||||
#elif defined(HAVE_SYS_SYSCALL_H)
|
||||
#include <sys/syscall.h> // for syscall()
|
||||
#endif
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h> // For geteuid.
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#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<string*>(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<char *>(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<int64>(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<pid_t>(tid64);
|
||||
#else
|
||||
pid_t tid = static_cast<pid_t>(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<pid_t>(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<const CrashReason*>(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
|
217
third_party/glog/src/utilities.h
vendored
217
third_party/glog/src/utilities.h
vendored
@ -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 <string>
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#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<typename T>
|
||||
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__
|
58
third_party/glog/src/utilities_unittest.cc
vendored
58
third_party/glog/src/utilities_unittest.cc
vendored
@ -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 <glog/logging.h>
|
||||
|
||||
#ifdef HAVE_LIB_GFLAGS
|
||||
#include <gflags/gflags.h>
|
||||
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);
|
||||
}
|
293
third_party/glog/src/vlog_is_on.cc
vendored
293
third_party/glog/src/vlog_is_on.cc
vendored
@ -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 <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include "base/commandlineflags.h"
|
||||
#include <glog/logging.h>
|
||||
#include <glog/raw_logging.h>
|
||||
#include "base/googleinit.h"
|
||||
|
||||
// glog doesn't have annotation
|
||||
#define ANNOTATE_BENIGN_RACE(address, description)
|
||||
|
||||
using std::string;
|
||||
|
||||
GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this."
|
||||
" Overridable by --vmodule.");
|
||||
|
||||
GLOG_DEFINE_string(vmodule, "", "per-module verbose level."
|
||||
" Argument is a comma-separated list of <module name>=<log level>."
|
||||
" <module name> is a glob pattern, matched against the filename base"
|
||||
" (that is, name ignoring .cc/.h./-inl.h)."
|
||||
" <log level> 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<size_t>(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_
|
1159
third_party/glog/src/windows/dirent.h
vendored
1159
third_party/glog/src/windows/dirent.h
vendored
File diff suppressed because it is too large
Load Diff
71
third_party/glog/src/windows/port.cc
vendored
71
third_party/glog/src/windows/port.cc
vendored
@ -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 <cstdarg> // 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
|
181
third_party/glog/src/windows/port.h
vendored
181
third_party/glog/src/windows/port.h
vendored
@ -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 <windows.h>
|
||||
#include <winsock.h> /* for gethostname */
|
||||
#include <io.h> /* because we so often use open/close/etc */
|
||||
#include <direct.h> /* for _getcwd() */
|
||||
#include <process.h> /* for _getpid() */
|
||||
#include <cstdarg> /* template_dictionary.cc uses va_copy */
|
||||
#include <cstdio> /* read in vsnprintf decl. before redifining it */
|
||||
#include <cstring> /* for _strnicmp(), strerror_s() */
|
||||
#include <ctime> /* 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 <glog/logging.h>
|
||||
|
||||
#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 <pthread.h>
|
||||
#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_ */
|
@ -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
|
||||
|
||||
|
@ -175,6 +175,8 @@ private:
|
||||
};
|
||||
for (auto &&item : m) {}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LinkToParent(Slice rel_path, ExposedVarGroup *parent)
|
||||
{
|
||||
|
@ -1,62 +1,14 @@
|
||||
#include "tile/base/internal/logging.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
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 <set>
|
||||
|
||||
namespace tile {
|
||||
namespace internal {
|
||||
namespace logging {
|
||||
|
||||
namespace {
|
||||
std::vector<PrefixAppender *> *
|
||||
GetProviers()
|
||||
@ -64,7 +16,7 @@ GetProviers()
|
||||
static std::vector<PrefixAppender *> providers;
|
||||
return &providers;
|
||||
}
|
||||
}// namespace
|
||||
} // namespace
|
||||
|
||||
namespace details {
|
||||
std::string
|
||||
@ -72,13 +24,10 @@ DescribeFormatArguments(const std::vector<std::string> &args)
|
||||
{
|
||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
}// namespace details
|
||||
|
||||
void
|
||||
InstallPrefixProvider(PrefixAppender *writer)
|
||||
{
|
||||
GetProviers()->push_back(writer);
|
||||
void InstallPrefixProvider(PrefixAppender *writer) {
|
||||
GetProviers()->push_back(writer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -90,53 +39,240 @@ WritePrefixTo(std::string *to)
|
||||
if (to->size() != was) { to->push_back(' '); }
|
||||
}
|
||||
}
|
||||
}// namespace logging
|
||||
}// namespace internal
|
||||
}// namespace tile
|
||||
} // namespace logging
|
||||
} // namespace internal
|
||||
} // namespace tile
|
||||
|
||||
namespace tile {
|
||||
static std::mutex g_sink_mutex;
|
||||
static std::set<LogSink::Ptr> g_sinks;
|
||||
static std::atomic<int> 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<std::mutex> _{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)
|
||||
{
|
||||
std::time_t timestamp = std::mktime(&t);
|
||||
init(t, timestamp, 0);
|
||||
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)
|
||||
{
|
||||
std::tm t;
|
||||
if (FLAGS_log_utc_time)
|
||||
gmtime_r(×tamp, &t);
|
||||
else
|
||||
localtime_r(×tamp, &t);
|
||||
init(t, timestamp, now);
|
||||
: use_localtime_(false) {
|
||||
std::tm t;
|
||||
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<std::chrono::microseconds>(
|
||||
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<std::int32_t>((now - timestamp) * 1000000);
|
||||
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
||||
WallTime now) {
|
||||
time_struct_ = t;
|
||||
timestamp_ = timestamp;
|
||||
if (now < timestamp) {
|
||||
usecs_ = 0;
|
||||
} else {
|
||||
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000) % 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);
|
||||
}
|
||||
void LogMessageTime::CalcGmtOffset() {
|
||||
std::tm gmt_struct;
|
||||
int isDst = 0;
|
||||
if (true) {
|
||||
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;
|
||||
@ -146,6 +282,11 @@ LogMessageTime::CalcGmtOffset()
|
||||
}
|
||||
|
||||
LogSink::~LogSink() {}
|
||||
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) {
|
||||
|
||||
void
|
||||
LogSink::send(LogSeverity severity,
|
||||
@ -159,91 +300,104 @@ LogSink::send(LogSeverity severity,
|
||||
|
||||
// do nothing
|
||||
}
|
||||
void LogSink::Flush() {}
|
||||
|
||||
void
|
||||
LogSink::WaitTillSent()
|
||||
{}
|
||||
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) {
|
||||
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());
|
||||
|
||||
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);
|
||||
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) {}
|
||||
static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity,
|
||||
const char *message, size_t len) {
|
||||
fwrite(message, len, 1, output);
|
||||
fflush(output);
|
||||
}
|
||||
|
||||
~LogSinkWrapper() override {}
|
||||
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 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 AddLogSink(LogSink::Ptr dest) {
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
g_sinks.insert(dest);
|
||||
g_sink_count.fetch_add(1);
|
||||
}
|
||||
|
||||
void RemoveLogSink(LogSink::Ptr dest) {
|
||||
std::lock_guard<std::mutex> _(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<std::mutex> _(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 WaitTillSent() override { dest_->WaitTillSent(); }
|
||||
|
||||
private:
|
||||
tile::LogSink *dest_;
|
||||
};
|
||||
|
||||
struct LogSinkPair {
|
||||
struct LogSinWrapper *wrapper;
|
||||
LogSink *sink;
|
||||
};
|
||||
|
||||
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
|
||||
static std::mutex sink_registry_mutex;
|
||||
|
||||
void
|
||||
AddLogSink(LogSink *dest)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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 WaitForSinks() {
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
for (auto &&sink : g_sinks) {
|
||||
sink->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RemoveLogSink(LogSink *dest)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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;
|
||||
}
|
||||
const char *GetLogSeverityName(LogSeverity severity) {
|
||||
const static std::map<LogSeverity, const char *> 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";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetStderrLogging(LogSeverity min_severity)
|
||||
{
|
||||
google::SetStderrLogging(min_severity);
|
||||
}
|
||||
|
||||
void
|
||||
LogToStderr()
|
||||
{
|
||||
google::LogToStderr();
|
||||
}
|
||||
|
||||
const char *
|
||||
GetLogSeverityName(LogSeverity severity)
|
||||
{
|
||||
return google::GetLogSeverityName(severity);
|
||||
}
|
||||
}// namespace tile
|
||||
} // namespace tile
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
@ -17,31 +18,98 @@
|
||||
#include <type_traits>
|
||||
|
||||
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<size_t>(pptr() - pbase()); }
|
||||
char *pbase() const { return std::streambuf::pbase(); }
|
||||
};
|
||||
|
||||
class LogSink;
|
||||
class LogMessageTime;
|
||||
class LogMessage {
|
||||
public:
|
||||
LogMessage(const char *file, int line, int severity);
|
||||
~LogMessage();
|
||||
std::ostream &stream();
|
||||
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> 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> impl_;
|
||||
LogMessageFatal(const char *file, int line);
|
||||
~LogMessageFatal();
|
||||
std::ostream &stream();
|
||||
};
|
||||
|
||||
class LogMessageVoidify {
|
||||
@ -482,76 +550,67 @@ FormatLog(const char *file, int line, Ts &&...args) noexcept
|
||||
|
||||
namespace tile {
|
||||
typedef double WallTime;
|
||||
|
||||
struct LogMessageTime {
|
||||
LogMessageTime();
|
||||
LogMessageTime(std::tm t);
|
||||
LogMessageTime(std::time_t timestamp, WallTime now);
|
||||
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; }
|
||||
|
||||
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_; }
|
||||
const time_t ×tamp() 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_; }
|
||||
const bool use_localtime() const { return use_localtime_; }
|
||||
|
||||
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 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_;
|
||||
bool use_localtime_;
|
||||
|
||||
void CalcGmtOffset();
|
||||
};
|
||||
|
||||
class LogSink {
|
||||
public:
|
||||
virtual ~LogSink();
|
||||
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,
|
||||
const LogMessageTime &logmsgtime,
|
||||
const char *message,
|
||||
size_t message_len);
|
||||
using Ptr = std::shared_ptr<LogSink>;
|
||||
|
||||
virtual ~LogSink();
|
||||
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 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
|
||||
|
187
tile/base/internal/logging_glog.cc
Normal file
187
tile/base/internal/logging_glog.cc
Normal file
@ -0,0 +1,187 @@
|
||||
#include "tile/base/internal/logging.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
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<PrefixAppender *> *GetProviers() {
|
||||
static std::vector<PrefixAppender *> providers;
|
||||
return &providers;
|
||||
}
|
||||
} // namespace
|
||||
namespace details {
|
||||
std::string DescribeFormatArguments(const std::vector<std::string> &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<std::int32_t>((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<long int>(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<LogSink *, LogSinkWrapper *> sink_registry;
|
||||
static std::mutex sink_registry_mutex;
|
||||
|
||||
void AddLogSink(LogSink *dest) {
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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
|
@ -9,18 +9,13 @@
|
||||
#include <thread>
|
||||
|
||||
struct AwesomeLogSink : public tile::LogSink {
|
||||
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);
|
||||
}
|
||||
|
||||
std::vector<std::string> msgs;
|
||||
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(std::string(message, message_len));
|
||||
}
|
||||
std::vector<std::string> msgs;
|
||||
};
|
||||
|
||||
std::string my_prefix, my_prefix2;
|
||||
@ -37,11 +32,26 @@ WriteLoggingPrefix2(std::string *s)
|
||||
*s += my_prefix2;
|
||||
}
|
||||
|
||||
void
|
||||
ResetLogPrefix()
|
||||
{
|
||||
my_prefix = "";
|
||||
my_prefix2 = "";
|
||||
TEST(Logging, Prefix) {
|
||||
auto sink = std::make_shared<AwesomeLogSink>();
|
||||
tile::AddLogSink(sink);
|
||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
||||
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
my_prefix = "[prefix]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
my_prefix = "[prefix1]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
my_prefix2 = "[prefix2]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
ASSERT_THAT(sink->msgs,
|
||||
::testing::ElementsAre("something", "[prefix] something",
|
||||
"[prefix1] something",
|
||||
"[prefix1] [prefix2] something"));
|
||||
}
|
||||
|
||||
TEST(Logging, CHECK)
|
||||
@ -61,20 +71,16 @@ TEST(Logging, Prefix)
|
||||
tile::AddLogSink(&sink);
|
||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); });
|
||||
|
||||
TILE_LOG_INFO("something");
|
||||
auto sink = std::make_shared<AwesomeLogSink>();
|
||||
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));
|
||||
}
|
||||
|
||||
my_prefix = "[prefix]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
my_prefix = "[prefix1]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
my_prefix2 = "[prefix2]";
|
||||
TILE_LOG_INFO("something");
|
||||
|
||||
ASSERT_THAT(sink.msgs,
|
||||
::testing::ElementsAre(
|
||||
"something", "[prefix] something", "[prefix1] something", "[prefix1] [prefix2] something"));
|
||||
ASSERT_THAT(sink->msgs,
|
||||
::testing::ElementsAre("something", "something", "something"));
|
||||
}
|
||||
|
||||
TEST(Logging, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
|
||||
|
@ -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, ...)
|
||||
|
||||
|
24
tile/base/logging/basic_file_sink.cc
Normal file
24
tile/base/logging/basic_file_sink.cc
Normal file
@ -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<BasicFileSink>(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
|
36
tile/base/logging/basic_file_sink.h
Normal file
36
tile/base/logging/basic_file_sink.h
Normal file
@ -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 <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace tile {
|
||||
class BasicFileSink : public LogSink {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<BasicFileSink>;
|
||||
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
|
32
tile/base/logging/console_sink.cc
Normal file
32
tile/base/logging/console_sink.cc
Normal file
@ -0,0 +1,32 @@
|
||||
#include "tile/base/logging/console_sink.h"
|
||||
|
||||
#include <stdio.h>
|
||||
namespace tile {
|
||||
|
||||
ConsoleSink::Ptr ConsoleSink::Create() {
|
||||
return std::shared_ptr<ConsoleSink>(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
|
25
tile/base/logging/console_sink.h
Normal file
25
tile/base/logging/console_sink.h
Normal file
@ -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<ConsoleSink>;
|
||||
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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user