feat/update_config #10
@ -7,6 +7,7 @@ set(tile_VERSION_BUILD $ENV{CI_STEP_NUMBER})
|
|||||||
if (NOT tile_VERSION_BUILD)
|
if (NOT tile_VERSION_BUILD)
|
||||||
set(tile_VERSION_BUILD "0")
|
set(tile_VERSION_BUILD "0")
|
||||||
endif()
|
endif()
|
||||||
|
set(TILE_VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}.${tile_VERSION_BUILD}")
|
||||||
project(
|
project(
|
||||||
tile
|
tile
|
||||||
VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}"
|
VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}"
|
||||||
@ -30,7 +31,7 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
@ -88,7 +89,7 @@ add_subdirectory("third_party/googletest")
|
|||||||
add_subdirectory("third_party/gflags")
|
add_subdirectory("third_party/gflags")
|
||||||
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
||||||
set(gflags_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags")
|
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")
|
# add_subdirectory("third_party/context")
|
||||||
|
|
||||||
set(CURL_DISABLE_TESTS ON)
|
set(CURL_DISABLE_TESTS ON)
|
||||||
@ -166,6 +167,9 @@ set(TILE_SRCS
|
|||||||
"tile/base/internal/thread_pool.cc"
|
"tile/base/internal/thread_pool.cc"
|
||||||
"tile/base/internal/time_keeper.cc"
|
"tile/base/internal/time_keeper.cc"
|
||||||
"tile/base/internal/time_keeper.h"
|
"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/net/endpoint.cc"
|
||||||
"tile/base/object_pool/disabled.cc"
|
"tile/base/object_pool/disabled.cc"
|
||||||
"tile/base/object_pool/global.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")
|
list(APPEND TILE_SRCS "tile/base/net/detail/android/ifaddrs.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(tile OBJECT ${TILE_SRCS})
|
add_library(tile SHARED ${TILE_SRCS})
|
||||||
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
|
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
|
||||||
target_precompile_headers(tile PUBLIC inja/inja.h)
|
target_precompile_headers(tile PUBLIC inja/inja.h)
|
||||||
target_precompile_headers(tile PUBLIC inja/string_view.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_SOURCE_DIR}/third_party/mustache.hpp"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
|
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
# "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
# "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
${THIRD_PARTY_INCLUDE_DIRS}
|
${THIRD_PARTY_INCLUDE_DIRS}
|
||||||
RPIVATE
|
RPIVATE
|
||||||
@ -241,7 +245,7 @@ target_link_libraries(
|
|||||||
tile
|
tile
|
||||||
PUBLIC # -Wl,--start-group
|
PUBLIC # -Wl,--start-group
|
||||||
# nova_context
|
# nova_context
|
||||||
zlib gflags::gflags glog::glog
|
zlib gflags::gflags # glog::glog
|
||||||
jsoncpp_static
|
jsoncpp_static
|
||||||
# -Wl,--end-group
|
# -Wl,--end-group
|
||||||
libcurl fmt)
|
libcurl fmt)
|
||||||
@ -302,9 +306,7 @@ function(add_test_group prefix group_name)
|
|||||||
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
|
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
|
||||||
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
|
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
|
||||||
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
|
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
|
||||||
string(REPLACE ".cpp" "" TEST_NAME "${TEST_NAME}")
|
string(REPLACE "_test.cc" "_test" TEST_NAME "${TEST_NAME}")
|
||||||
string(REPLACE ".cc" "" TEST_NAME "${TEST_NAME}")
|
|
||||||
string(REPLACE ".c" "" TEST_NAME "${TEST_NAME}")
|
|
||||||
# if group_name is not empty, add suffix _
|
# if group_name is not empty, add suffix _
|
||||||
if (NOT group_name STREQUAL "")
|
if (NOT group_name STREQUAL "")
|
||||||
set(TEST_NAME "${group_name}_${TEST_NAME}")
|
set(TEST_NAME "${group_name}_${TEST_NAME}")
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
## TILE
|
## TILE
|
||||||
一个`C++11`工具库,集成常见的编码工具
|
一个`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_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@"
|
||||||
#define TILE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
|
#define TILE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
|
||||||
#define TILE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@"
|
#define TILE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@"
|
||||||
#define TILE_VERSION "@PROJECT_VERSOIN@"
|
#define TILE_VERSION "@TILE_VERSION@"
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -175,6 +175,8 @@ private:
|
|||||||
};
|
};
|
||||||
for (auto &&item : m) {}
|
for (auto &&item : m) {}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void LinkToParent(Slice rel_path, ExposedVarGroup *parent)
|
void LinkToParent(Slice rel_path, ExposedVarGroup *parent)
|
||||||
{
|
{
|
||||||
|
@ -1,62 +1,14 @@
|
|||||||
#include "tile/base/internal/logging.h"
|
#include "tile/base/internal/logging.h"
|
||||||
|
#include <cassert>
|
||||||
#include "glog/logging.h"
|
#include <iostream>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <set>
|
||||||
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 tile {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
namespace logging {
|
namespace logging {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::vector<PrefixAppender *> *
|
std::vector<PrefixAppender *> *
|
||||||
GetProviers()
|
GetProviers()
|
||||||
@ -64,7 +16,7 @@ GetProviers()
|
|||||||
static std::vector<PrefixAppender *> providers;
|
static std::vector<PrefixAppender *> providers;
|
||||||
return &providers;
|
return &providers;
|
||||||
}
|
}
|
||||||
}// namespace
|
} // namespace
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
std::string
|
std::string
|
||||||
@ -72,12 +24,9 @@ DescribeFormatArguments(const std::vector<std::string> &args)
|
|||||||
{
|
{
|
||||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||||
}
|
}
|
||||||
|
} // namespace details
|
||||||
|
|
||||||
}// namespace details
|
void InstallPrefixProvider(PrefixAppender *writer) {
|
||||||
|
|
||||||
void
|
|
||||||
InstallPrefixProvider(PrefixAppender *writer)
|
|
||||||
{
|
|
||||||
GetProviers()->push_back(writer);
|
GetProviers()->push_back(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,46 +39,233 @@ WritePrefixTo(std::string *to)
|
|||||||
if (to->size() != was) { to->push_back(' '); }
|
if (to->size() != was) { to->push_back(' '); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}// namespace logging
|
} // namespace logging
|
||||||
}// namespace internal
|
} // namespace internal
|
||||||
}// namespace tile
|
} // namespace tile
|
||||||
|
|
||||||
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() : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::tm t)
|
LogMessageTime::LogMessageTime(std::tm t) : use_localtime_(true) {
|
||||||
{
|
|
||||||
std::time_t timestamp = std::mktime(&t);
|
std::time_t timestamp = std::mktime(&t);
|
||||||
init(t, timestamp, 0);
|
init(t, timestamp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
|
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
|
||||||
{
|
: use_localtime_(false) {
|
||||||
std::tm t;
|
std::tm t;
|
||||||
if (FLAGS_log_utc_time)
|
if (use_localtime_) {
|
||||||
gmtime_r(×tamp, &t);
|
|
||||||
else
|
|
||||||
localtime_r(×tamp, &t);
|
localtime_r(×tamp, &t);
|
||||||
|
} else {
|
||||||
|
gmtime_r(×tamp, &t);
|
||||||
|
}
|
||||||
|
|
||||||
init(t, timestamp, now);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
init(t, timestamp, 0);
|
||||||
LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now)
|
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;
|
time_struct_ = t;
|
||||||
timestamp_ = timestamp;
|
timestamp_ = timestamp;
|
||||||
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000);
|
if (now < timestamp) {
|
||||||
|
usecs_ = 0;
|
||||||
|
} else {
|
||||||
|
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000) % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
CalcGmtOffset();
|
CalcGmtOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void LogMessageTime::CalcGmtOffset() {
|
||||||
LogMessageTime::CalcGmtOffset()
|
|
||||||
{
|
|
||||||
std::tm gmt_struct;
|
std::tm gmt_struct;
|
||||||
int isDst = 0;
|
int isDst = 0;
|
||||||
if (FLAGS_log_utc_time) {
|
if (true) {
|
||||||
localtime_r(×tamp_, &gmt_struct);
|
localtime_r(×tamp_, &gmt_struct);
|
||||||
isDst = gmt_struct.tm_isdst;
|
isDst = gmt_struct.tm_isdst;
|
||||||
gmt_struct = time_struct_;
|
gmt_struct = time_struct_;
|
||||||
@ -146,6 +282,11 @@ LogMessageTime::CalcGmtOffset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogSink::~LogSink() {}
|
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
|
void
|
||||||
LogSink::send(LogSeverity severity,
|
LogSink::send(LogSeverity severity,
|
||||||
@ -159,91 +300,104 @@ LogSink::send(LogSeverity severity,
|
|||||||
|
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
void LogSink::Flush() {}
|
||||||
|
|
||||||
void
|
std::string LogSink::ToString(LogSeverity severity, const char *file,
|
||||||
LogSink::WaitTillSent()
|
const char *base_filename, int line,
|
||||||
{}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
LogSink::ToString(LogSeverity severity,
|
|
||||||
const char *file,
|
|
||||||
int line,
|
|
||||||
const LogMessageTime &logmsgtime,
|
const LogMessageTime &logmsgtime,
|
||||||
const char *message,
|
const char *message, size_t message_len) {
|
||||||
size_t message_len)
|
std::stringstream ss;
|
||||||
{
|
char date_time[64];
|
||||||
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), message, message_len);
|
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());
|
||||||
|
|
||||||
class LogSinkWrapper : public google::LogSink {
|
ss << date_time;
|
||||||
public:
|
|
||||||
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
|
|
||||||
|
|
||||||
~LogSinkWrapper() override {}
|
if (logmsgtime.gmtoff() != 0) {
|
||||||
|
auto hour = logmsgtime.gmtoff() / 3600;
|
||||||
void send(LogSeverity severity,
|
auto min = std::abs(logmsgtime.gmtoff() % 3600) / 60;
|
||||||
const char *full_filename,
|
sprintf(date_time, "%+03ld:%02ld", hour, min);
|
||||||
const char *base_filename,
|
ss << date_time;
|
||||||
int line,
|
} else if (!logmsgtime.use_localtime()) {
|
||||||
const google::LogMessageTime &logmsgtime,
|
ss << "Z";
|
||||||
const char *message,
|
|
||||||
size_t message_len) override
|
|
||||||
{
|
|
||||||
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(), message, message_len);
|
|
||||||
}
|
}
|
||||||
|
ss << " " << GetLogSeverityName(severity)[0] << " ";
|
||||||
|
ss << base_filename << ":" << line << " ";
|
||||||
|
|
||||||
void WaitTillSent() override { dest_->WaitTillSent(); }
|
// return google::LogSink::ToString(severity, file, line, logmsgtime.tm(),
|
||||||
|
// message, message_len);
|
||||||
|
|
||||||
private:
|
ss.write(message, message_len);
|
||||||
tile::LogSink *dest_;
|
return ss.str();
|
||||||
};
|
|
||||||
|
|
||||||
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
|
static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity,
|
||||||
RemoveLogSink(LogSink *dest)
|
const char *message, size_t len) {
|
||||||
{
|
fwrite(message, len, 1, output);
|
||||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
fflush(output);
|
||||||
auto iter = sink_registry.find(dest);
|
}
|
||||||
if (iter != sink_registry.end()) {
|
|
||||||
google::RemoveLogSink(iter->second);
|
void ColoredWriteToStdout(LogSeverity severity, const char *message,
|
||||||
sink_registry.erase(iter);
|
size_t len) {
|
||||||
delete iter->second;
|
FILE *output = stdout;
|
||||||
|
if (severity >= TILE_FATAL) {
|
||||||
|
output = stderr;
|
||||||
|
}
|
||||||
|
ColoredWriteToStderrOrStdout(output, severity, message, len);
|
||||||
|
}
|
||||||
|
void ColoredWriteToStderr(LogSeverity severity, const char *message,
|
||||||
|
size_t len) {
|
||||||
|
ColoredWriteToStderrOrStdout(stderr, severity, message, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddLogSink(LogSink::Ptr dest) {
|
||||||
|
std::lock_guard<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 WaitForSinks() {
|
||||||
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
|
for (auto &&sink : g_sinks) {
|
||||||
|
sink->Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
const char *GetLogSeverityName(LogSeverity severity) {
|
||||||
SetStderrLogging(LogSeverity min_severity)
|
const static std::map<LogSeverity, const char *> severity_names = {
|
||||||
{
|
{TILE_INFO, "INFO"},
|
||||||
google::SetStderrLogging(min_severity);
|
{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
|
} // namespace tile
|
||||||
LogToStderr()
|
|
||||||
{
|
|
||||||
google::LogToStderr();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
GetLogSeverityName(LogSeverity severity)
|
|
||||||
{
|
|
||||||
return google::GetLogSeverityName(severity);
|
|
||||||
}
|
|
||||||
}// namespace tile
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -17,31 +18,98 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
typedef int LogSeverity;
|
// typedef int LogSeverity;
|
||||||
const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3;
|
// 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);
|
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 {
|
class LogMessage {
|
||||||
public:
|
public:
|
||||||
LogMessage(const char *file, int line, int severity);
|
class LogStream : public std::ostream {
|
||||||
|
public:
|
||||||
|
LogStream(char *buf, int len, int64_t ctr)
|
||||||
|
: std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this) {
|
||||||
|
rdbuf(&streambuf_);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogStream(LogStream &other) noexcept
|
||||||
|
: std::ostream(nullptr), streambuf_(std::move(other.streambuf_)),
|
||||||
|
ctr_(internal::Exchange(other.ctr_, 0)), self_(this) {
|
||||||
|
rdbuf(&streambuf_);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogStream &operator=(LogStream &&other) noexcept {
|
||||||
|
streambuf_ = std::move(other.streambuf_);
|
||||||
|
ctr_ = internal::Exchange(other.ctr_, 0);
|
||||||
|
self_ = this;
|
||||||
|
rdbuf(&streambuf_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ctr() const { return ctr_; }
|
||||||
|
void set_ctr(int64_t ctr) { ctr_ = ctr; }
|
||||||
|
|
||||||
|
LogStream *self() { return self_; }
|
||||||
|
|
||||||
|
size_t pcount() const { return streambuf_.pcount(); }
|
||||||
|
char *pbase() const { return streambuf_.pbase(); }
|
||||||
|
char *str() const { return pbase(); }
|
||||||
|
|
||||||
|
LogStream(const LogStream &) = delete;
|
||||||
|
LogStream &operator=(const LogStream &) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LogStreamBuf streambuf_;
|
||||||
|
int64_t ctr_;
|
||||||
|
LogStream *self_;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const size_t kMaxLogMessageLen = 30000;
|
||||||
|
LogMessage(const char *file, int line);
|
||||||
|
LogMessage(const char *file, int line, LogSeverity severity);
|
||||||
|
LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink,
|
||||||
|
bool also_send_to_log = true);
|
||||||
|
|
||||||
~LogMessage();
|
~LogMessage();
|
||||||
std::ostream &stream();
|
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:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> impl_;
|
std::unique_ptr<Impl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogMessageFatal {
|
class LogMessageFatal : public LogMessage {
|
||||||
public:
|
public:
|
||||||
LogMessageFatal(const char *file, int line);
|
LogMessageFatal(const char *file, int line);
|
||||||
~LogMessageFatal();
|
~LogMessageFatal();
|
||||||
std::ostream &stream();
|
std::ostream &stream();
|
||||||
|
|
||||||
private:
|
|
||||||
class Impl;
|
|
||||||
std::unique_ptr<Impl> impl_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogMessageVoidify {
|
class LogMessageVoidify {
|
||||||
@ -482,76 +550,67 @@ FormatLog(const char *file, int line, Ts &&...args) noexcept
|
|||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
typedef double WallTime;
|
typedef double WallTime;
|
||||||
|
|
||||||
struct LogMessageTime {
|
struct LogMessageTime {
|
||||||
LogMessageTime();
|
LogMessageTime();
|
||||||
LogMessageTime(std::tm t);
|
LogMessageTime(std::tm t);
|
||||||
LogMessageTime(std::time_t timestamp, WallTime now);
|
LogMessageTime(std::time_t timestamp, WallTime now);
|
||||||
|
LogMessageTime(std::chrono::system_clock::time_point tp);
|
||||||
|
|
||||||
const time_t ×tamp() const { return timestamp_; }
|
const time_t ×tamp() const { return timestamp_; }
|
||||||
|
|
||||||
const int &sec() const { return time_struct_.tm_sec; }
|
const int &sec() const { return time_struct_.tm_sec; }
|
||||||
|
|
||||||
const int32_t &usec() const { return usecs_; }
|
const int32_t &usec() const { return usecs_; }
|
||||||
|
const int &(min)() const { return time_struct_.tm_min; }
|
||||||
const int &(min) () const { return time_struct_.tm_min; }
|
|
||||||
|
|
||||||
const int &hour() const { return time_struct_.tm_hour; }
|
const int &hour() const { return time_struct_.tm_hour; }
|
||||||
|
|
||||||
const int &day() const { return time_struct_.tm_mday; }
|
const int &day() const { return time_struct_.tm_mday; }
|
||||||
|
|
||||||
const int &month() const { return time_struct_.tm_mon; }
|
const int &month() const { return time_struct_.tm_mon; }
|
||||||
|
|
||||||
const int &year() const { return time_struct_.tm_year; }
|
const int &year() const { return time_struct_.tm_year; }
|
||||||
|
|
||||||
const int &dayOfWeek() const { return time_struct_.tm_wday; }
|
const int &dayOfWeek() const { return time_struct_.tm_wday; }
|
||||||
|
|
||||||
const int &dayInYear() const { return time_struct_.tm_yday; }
|
const int &dayInYear() const { return time_struct_.tm_yday; }
|
||||||
|
|
||||||
const int &dst() const { return time_struct_.tm_isdst; }
|
const int &dst() const { return time_struct_.tm_isdst; }
|
||||||
|
|
||||||
const long int &gmtoff() const { return gmtoffset_; }
|
const long int &gmtoff() const { return gmtoffset_; }
|
||||||
|
|
||||||
const std::tm &tm() const { return time_struct_; }
|
const std::tm &tm() const { return time_struct_; }
|
||||||
|
const bool use_localtime() const { return use_localtime_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(const std::tm &t, std::time_t timestamp, WallTime now);
|
void init(const std::tm &t, std::time_t timestamp, WallTime now);
|
||||||
std::tm time_struct_;// Time of creation of LogMessage
|
std::tm time_struct_; // Time of creation of LogMessage
|
||||||
time_t timestamp_; // Time of creation of LogMessage in seconds
|
time_t timestamp_; // Time of creation of LogMessage in seconds
|
||||||
int32_t usecs_; // Time of creation of LogMessage - microseconds part
|
int32_t usecs_; // Time of creation of LogMessage - microseconds part
|
||||||
long int gmtoffset_;
|
long int gmtoffset_;
|
||||||
|
bool use_localtime_;
|
||||||
|
|
||||||
void CalcGmtOffset();
|
void CalcGmtOffset();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogSink {
|
class LogSink {
|
||||||
public:
|
public:
|
||||||
|
using Ptr = std::shared_ptr<LogSink>;
|
||||||
|
|
||||||
virtual ~LogSink();
|
virtual ~LogSink();
|
||||||
virtual void send(LogSeverity severity,
|
virtual bool ShouldLog(LogSeverity severity);
|
||||||
const char *full_filename,
|
virtual void Send(LogSeverity severity, const char *full_filename,
|
||||||
const char *base_filename,
|
const char *base_filename, int line,
|
||||||
int line,
|
const LogMessageTime &logmsgtime, const char *message,
|
||||||
const LogMessageTime &logmsgtime,
|
|
||||||
const char *message,
|
|
||||||
size_t message_len);
|
size_t message_len);
|
||||||
virtual void WaitTillSent();
|
virtual void Flush();
|
||||||
std::string ToString(LogSeverity severity,
|
std::string ToString(LogSeverity severity, const char *file,
|
||||||
const char *file,
|
const char *base_file, int line,
|
||||||
int line,
|
const LogMessageTime &logmsgtime, const char *message,
|
||||||
const LogMessageTime &logmsgtime,
|
|
||||||
const char *message,
|
|
||||||
size_t message_len);
|
size_t message_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileLogSink : public LogSink {
|
void ColoredWriteToStdout(LogSeverity severity, const char *message,
|
||||||
public:
|
size_t len);
|
||||||
FileLogSink(const std::string &file_path_template);
|
void ColoredWriteToStderr(LogSeverity severity, const char *message,
|
||||||
};
|
size_t len);
|
||||||
|
void AddLogSink(LogSink::Ptr dest);
|
||||||
void AddLogSink(LogSink *dest);
|
void RemoveLogSink(LogSink::Ptr dest);
|
||||||
void RemoveLogSink(LogSink *dest);
|
|
||||||
void SetStderrLogging(LogSeverity min_severity);
|
void SetStderrLogging(LogSeverity min_severity);
|
||||||
void LogToStderr();
|
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);
|
const char *GetLogSeverityName(LogSeverity severity);
|
||||||
|
|
||||||
}// namespace tile
|
}// 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,17 +9,12 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
struct AwesomeLogSink : public tile::LogSink {
|
struct AwesomeLogSink : public tile::LogSink {
|
||||||
virtual void send(tile::LogSeverity severity,
|
virtual void Send(tile::LogSeverity severity, const char *full_filename,
|
||||||
const char *full_filename,
|
const char *base_filename, int line,
|
||||||
const char *base_filename,
|
const tile::LogMessageTime &logmsgtime, const char *message,
|
||||||
int line,
|
size_t message_len) override {
|
||||||
const tile::LogMessageTime &logmsgtime,
|
msgs.emplace_back(std::string(message, message_len));
|
||||||
const char *message,
|
|
||||||
size_t message_len) override
|
|
||||||
{
|
|
||||||
msgs.emplace_back(message, message_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> msgs;
|
std::vector<std::string> msgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,11 +32,26 @@ WriteLoggingPrefix2(std::string *s)
|
|||||||
*s += my_prefix2;
|
*s += my_prefix2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
TEST(Logging, Prefix) {
|
||||||
ResetLogPrefix()
|
auto sink = std::make_shared<AwesomeLogSink>();
|
||||||
{
|
tile::AddLogSink(sink);
|
||||||
my_prefix = "";
|
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
||||||
my_prefix2 = "";
|
|
||||||
|
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)
|
TEST(Logging, CHECK)
|
||||||
@ -61,20 +71,16 @@ TEST(Logging, Prefix)
|
|||||||
tile::AddLogSink(&sink);
|
tile::AddLogSink(&sink);
|
||||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&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]";
|
ASSERT_THAT(sink->msgs,
|
||||||
TILE_LOG_INFO("something");
|
::testing::ElementsAre("something", "something", "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, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
|
TEST(Logging, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tile/base/internal/logging.h"
|
#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, ...)
|
// #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…
Reference in New Issue
Block a user