move to C++14 (#902)
This commit is contained in:
parent
35f4efbb0a
commit
6742834201
@ -157,7 +157,7 @@ SpacesInCStyleCastParentheses: false
|
|||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
SpaceBeforeSquareBrackets: false
|
SpaceBeforeSquareBrackets: false
|
||||||
Standard: Auto
|
Standard: c++14
|
||||||
StatementMacros:
|
StatementMacros:
|
||||||
- Q_UNUSED
|
- Q_UNUSED
|
||||||
- QT_REQUIRE_VERSION
|
- QT_REQUIRE_VERSION
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,google-*'
|
Checks: 'clang-diagnostic-*,clang-analyzer-*,google-*,modernize-*,-modernize-use-trailing-return-type,readability-*,portability-*,performance-*,bugprone-*,android-*,darwin-*,clang-analyzer-*'
|
||||||
WarningsAsErrors: ''
|
WarningsAsErrors: ''
|
||||||
HeaderFilterRegex: ''
|
HeaderFilterRegex: ''
|
||||||
AnalyzeTemporaryDtors: false
|
AnalyzeTemporaryDtors: false
|
||||||
|
|||||||
7
.github/workflows/android.yml
vendored
7
.github/workflows/android.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
std: [98, 11, 14, 17, 20]
|
std: [14, 17, 20]
|
||||||
abi: [arm64-v8a, armeabi-v7a, x86_64, x86]
|
abi: [arm64-v8a, armeabi-v7a, x86_64, x86]
|
||||||
build_type: [Debug, Release]
|
build_type: [Debug, Release]
|
||||||
|
|
||||||
@ -26,11 +26,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: 1.10.0
|
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: Setup NDK
|
- name: Setup NDK
|
||||||
env:
|
env:
|
||||||
ANDROID_SDK_ROOT: /usr/local/lib/android/sdk
|
ANDROID_SDK_ROOT: /usr/local/lib/android/sdk
|
||||||
|
|||||||
7
.github/workflows/emscripten.yml
vendored
7
.github/workflows/emscripten.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
build_type: [Release, Debug]
|
build_type: [Release, Debug]
|
||||||
lib: [static]
|
lib: [static]
|
||||||
std: [98, 11, 14, 17, 20]
|
std: [14, 17, 20]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@ -27,11 +27,6 @@ jobs:
|
|||||||
cmake \
|
cmake \
|
||||||
ninja-build
|
ninja-build
|
||||||
|
|
||||||
- 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
|
- name: Configure
|
||||||
env:
|
env:
|
||||||
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror -Wno-error=wasm-exception-spec ${{env.CXXFLAGS}}
|
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror -Wno-error=wasm-exception-spec ${{env.CXXFLAGS}}
|
||||||
|
|||||||
7
.github/workflows/linux.yml
vendored
7
.github/workflows/linux.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
build_type: [Release, Debug]
|
build_type: [Release, Debug]
|
||||||
lib: [shared, static]
|
lib: [shared, static]
|
||||||
std: [98, 11, 14, 17, 20]
|
std: [14, 17, 20]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@ -59,11 +59,6 @@ jobs:
|
|||||||
echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV
|
echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV
|
||||||
echo 'GTest_ROOT=${{github.workspace}}/gtest' >> $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
|
- name: Configure
|
||||||
env:
|
env:
|
||||||
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
|
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
|
||||||
|
|||||||
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@ -9,7 +9,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
std: [98, 11, 14, 17, 20]
|
std: [14, 17, 20]
|
||||||
include:
|
include:
|
||||||
- generator: Ninja
|
- generator: Ninja
|
||||||
- build_type: Debug
|
- build_type: Debug
|
||||||
|
|||||||
8
.github/workflows/windows.yml
vendored
8
.github/workflows/windows.yml
vendored
@ -19,7 +19,6 @@ jobs:
|
|||||||
build_type: [Debug, Release]
|
build_type: [Debug, Release]
|
||||||
lib: [shared, static]
|
lib: [shared, static]
|
||||||
msvc: [VS-16-2019, VS-17-2022]
|
msvc: [VS-16-2019, VS-17-2022]
|
||||||
# Visual Studio 17 2022 does not support C++11 and older language standard
|
|
||||||
std: [14, 17, 20]
|
std: [14, 17, 20]
|
||||||
include:
|
include:
|
||||||
- msvc: VS-16-2019
|
- msvc: VS-16-2019
|
||||||
@ -139,7 +138,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
build_type: [Debug]
|
build_type: [Debug]
|
||||||
lib: [shared, static]
|
lib: [shared, static]
|
||||||
std: [98, 11, 14, 17, 20]
|
std: [14, 17, 20]
|
||||||
sys: [mingw32, mingw64]
|
sys: [mingw32, mingw64]
|
||||||
include:
|
include:
|
||||||
- sys: mingw32
|
- sys: mingw32
|
||||||
@ -159,11 +158,6 @@ jobs:
|
|||||||
mingw-w64-${{matrix.env}}-gflags
|
mingw-w64-${{matrix.env}}-gflags
|
||||||
mingw-w64-${{matrix.env}}-ninja
|
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
|
- name: Setup Environment
|
||||||
if: matrix.build_type == 'Debug'
|
if: matrix.build_type == 'Debug'
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
174
CMakeLists.txt
174
CMakeLists.txt
@ -104,10 +104,8 @@ endif (Unwind_FOUND)
|
|||||||
|
|
||||||
check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
|
check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
|
||||||
check_include_file_cxx (glob.h HAVE_GLOB_H)
|
check_include_file_cxx (glob.h HAVE_GLOB_H)
|
||||||
check_include_file_cxx (inttypes.h HAVE_INTTYPES_H)
|
|
||||||
check_include_file_cxx (memory.h HAVE_MEMORY_H)
|
check_include_file_cxx (memory.h HAVE_MEMORY_H)
|
||||||
check_include_file_cxx (pwd.h HAVE_PWD_H)
|
check_include_file_cxx (pwd.h HAVE_PWD_H)
|
||||||
check_include_file_cxx (stdint.h HAVE_STDINT_H)
|
|
||||||
check_include_file_cxx (strings.h HAVE_STRINGS_H)
|
check_include_file_cxx (strings.h HAVE_STRINGS_H)
|
||||||
check_include_file_cxx (sys/stat.h HAVE_SYS_STAT_H)
|
check_include_file_cxx (sys/stat.h HAVE_SYS_STAT_H)
|
||||||
check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H)
|
check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H)
|
||||||
@ -120,19 +118,8 @@ check_include_file_cxx (syslog.h HAVE_SYSLOG_H)
|
|||||||
check_include_file_cxx (ucontext.h HAVE_UCONTEXT_H)
|
check_include_file_cxx (ucontext.h HAVE_UCONTEXT_H)
|
||||||
check_include_file_cxx (unistd.h HAVE_UNISTD_H)
|
check_include_file_cxx (unistd.h HAVE_UNISTD_H)
|
||||||
|
|
||||||
check_include_file_cxx ("ext/hash_map" HAVE_EXT_HASH_MAP)
|
|
||||||
check_include_file_cxx ("ext/hash_set" HAVE_EXT_HASH_SET)
|
|
||||||
check_include_file_cxx ("ext/slist" HAVE_EXT_SLIST)
|
|
||||||
check_include_file_cxx ("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP)
|
|
||||||
check_include_file_cxx ("tr1/unordered_set" HAVE_TR1_UNORDERED_SET)
|
|
||||||
check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
|
|
||||||
check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
|
|
||||||
|
|
||||||
check_type_size ("unsigned __int16" HAVE___UINT16 LANGUAGE CXX)
|
|
||||||
check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX)
|
check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX)
|
||||||
check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
|
check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
|
||||||
check_type_size (u_int16_t HAVE_U_INT16_T LANGUAGE CXX)
|
|
||||||
check_type_size (uint16_t HAVE_UINT16_T LANGUAGE CXX)
|
|
||||||
|
|
||||||
check_function_exists (dladdr HAVE_DLADDR)
|
check_function_exists (dladdr HAVE_DLADDR)
|
||||||
check_function_exists (fcntl HAVE_FCNTL)
|
check_function_exists (fcntl HAVE_FCNTL)
|
||||||
@ -221,82 +208,8 @@ __declspec(selectany) int a;
|
|||||||
int main(void) { return 0; }
|
int main(void) { return 0; }
|
||||||
" HAVE___DECLSPEC)
|
" HAVE___DECLSPEC)
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <vector>
|
|
||||||
vector<int> t; int main() { }
|
|
||||||
" STL_NO_NAMESPACE)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <vector>
|
|
||||||
std::vector<int> t; int main() { }
|
|
||||||
" STL_STD_NAMESPACE)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <iostream>
|
|
||||||
std::ostream& operator<<(std::ostream&, struct s);
|
|
||||||
using ::operator<<;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_USING_OPERATOR)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
namespace Outer { namespace Inner { int i = 0; }}
|
|
||||||
using namespace Outer::Inner;;
|
|
||||||
int main() { return i; }
|
|
||||||
" HAVE_NAMESPACES)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
__thread int tls;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_GCC_TLS)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
__declspec(thread) int tls;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_MSVC_TLS)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
thread_local int tls;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_CXX11_TLS)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <type_traits>
|
|
||||||
std::aligned_storage<sizeof(char), alignof(char)>::type data;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_ALIGNED_STORAGE)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <atomic>
|
|
||||||
std::atomic<int> i;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_CXX11_ATOMIC)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
constexpr int x = 0;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_CXX11_CONSTEXPR)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <chrono>
|
|
||||||
std::chrono::seconds s;
|
|
||||||
int main() { }
|
|
||||||
" HAVE_CXX11_CHRONO)
|
|
||||||
|
|
||||||
check_cxx_source_compiles ("
|
|
||||||
#include <cstddef>
|
|
||||||
void foo(std::nullptr_t) {}
|
|
||||||
int main(void) { foo(nullptr); }
|
|
||||||
" HAVE_CXX11_NULLPTR_T)
|
|
||||||
|
|
||||||
if (WITH_TLS)
|
if (WITH_TLS)
|
||||||
# Cygwin does not support the thread attribute. Don't bother.
|
set (GLOG_THREAD_LOCAL_STORAGE 1)
|
||||||
if (HAVE_GCC_TLS)
|
|
||||||
set (GLOG_THREAD_LOCAL_STORAGE "__thread")
|
|
||||||
elseif (HAVE_MSVC_TLS)
|
|
||||||
set (GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)")
|
|
||||||
elseif (HAVE_CXX11_TLS)
|
|
||||||
set (GLOG_THREAD_LOCAL_STORAGE thread_local)
|
|
||||||
endif (HAVE_GCC_TLS)
|
|
||||||
endif (WITH_TLS)
|
endif (WITH_TLS)
|
||||||
|
|
||||||
set (_PC_FIELDS
|
set (_PC_FIELDS
|
||||||
@ -345,59 +258,23 @@ int main(void)
|
|||||||
endforeach (_PC_FIELD)
|
endforeach (_PC_FIELD)
|
||||||
endif (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
|
endif (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
|
||||||
|
|
||||||
if (STL_STD_NAMESPACE)
|
|
||||||
set (STL_NAMESPACE std)
|
|
||||||
else (STL_STD_NAMESPACE)
|
|
||||||
set (STL_NAMESPACE "")
|
|
||||||
endif (STL_STD_NAMESPACE)
|
|
||||||
|
|
||||||
set (GOOGLE_NAMESPACE google)
|
set (GOOGLE_NAMESPACE google)
|
||||||
set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
|
set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
|
||||||
set (_END_GOOGLE_NAMESPACE_ "}")
|
set (_END_GOOGLE_NAMESPACE_ "}")
|
||||||
set (ac_cv_have_glog_export 1)
|
set (ac_cv_have_glog_export 1)
|
||||||
|
|
||||||
if (HAVE___UINT16)
|
|
||||||
set (ac_cv_have___uint16 1)
|
|
||||||
else (HAVE___UINT16)
|
|
||||||
set (ac_cv_have___uint16 0)
|
|
||||||
endif (HAVE___UINT16)
|
|
||||||
|
|
||||||
if (HAVE_INTTYPES_H)
|
|
||||||
set (ac_cv_have_inttypes_h 1)
|
|
||||||
else (HAVE_INTTYPES_H)
|
|
||||||
set (ac_cv_have_inttypes_h 0)
|
|
||||||
endif (HAVE_INTTYPES_H)
|
|
||||||
|
|
||||||
if (HAVE_LIB_GFLAGS)
|
if (HAVE_LIB_GFLAGS)
|
||||||
set (ac_cv_have_libgflags 1)
|
set (ac_cv_have_libgflags 1)
|
||||||
else (HAVE_LIB_GFLAGS)
|
else (HAVE_LIB_GFLAGS)
|
||||||
set (ac_cv_have_libgflags 0)
|
set (ac_cv_have_libgflags 0)
|
||||||
endif (HAVE_LIB_GFLAGS)
|
endif (HAVE_LIB_GFLAGS)
|
||||||
|
|
||||||
if (HAVE_STDINT_H)
|
|
||||||
set (ac_cv_have_stdint_h 1)
|
|
||||||
else (HAVE_STDINT_H)
|
|
||||||
set (ac_cv_have_stdint_h 0)
|
|
||||||
endif (HAVE_STDINT_H)
|
|
||||||
|
|
||||||
if (HAVE_SYS_TYPES_H)
|
if (HAVE_SYS_TYPES_H)
|
||||||
set (ac_cv_have_systypes_h 1)
|
set (ac_cv_have_systypes_h 1)
|
||||||
else (HAVE_SYS_TYPES_H)
|
else (HAVE_SYS_TYPES_H)
|
||||||
set (ac_cv_have_systypes_h 0)
|
set (ac_cv_have_systypes_h 0)
|
||||||
endif (HAVE_SYS_TYPES_H)
|
endif (HAVE_SYS_TYPES_H)
|
||||||
|
|
||||||
if (HAVE_U_INT16_T)
|
|
||||||
set (ac_cv_have_u_int16_t 1)
|
|
||||||
else (HAVE_U_INT16_T)
|
|
||||||
set (ac_cv_have_u_int16_t 0)
|
|
||||||
endif (HAVE_U_INT16_T)
|
|
||||||
|
|
||||||
if (HAVE_UINT16_T)
|
|
||||||
set (ac_cv_have_uint16_t 1)
|
|
||||||
else (HAVE_UINT16_T)
|
|
||||||
set (ac_cv_have_uint16_t 0)
|
|
||||||
endif (HAVE_UINT16_T)
|
|
||||||
|
|
||||||
if (HAVE_SSIZE_T)
|
if (HAVE_SSIZE_T)
|
||||||
set (ac_cv_have_ssize_t 1)
|
set (ac_cv_have_ssize_t 1)
|
||||||
else (HAVE_SSIZE_T)
|
else (HAVE_SSIZE_T)
|
||||||
@ -421,11 +298,9 @@ set (ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_})
|
|||||||
set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
|
set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
|
||||||
|
|
||||||
if (HAVE___ATTRIBUTE__)
|
if (HAVE___ATTRIBUTE__)
|
||||||
set (ac_cv___attribute___noreturn "__attribute__((noreturn))")
|
|
||||||
set (ac_cv___attribute___noinline "__attribute__((noinline))")
|
set (ac_cv___attribute___noinline "__attribute__((noinline))")
|
||||||
set (ac_cv___attribute___printf_4_5 "__attribute__((__format__(__printf__, 4, 5)))")
|
set (ac_cv___attribute___printf_4_5 "__attribute__((__format__(__printf__, 4, 5)))")
|
||||||
elseif (HAVE___DECLSPEC)
|
elseif (HAVE___DECLSPEC)
|
||||||
set (ac_cv___attribute___noreturn "__declspec(noreturn)")
|
|
||||||
#set (ac_cv___attribute___noinline "__declspec(noinline)")
|
#set (ac_cv___attribute___noinline "__declspec(noinline)")
|
||||||
endif (HAVE___ATTRIBUTE__)
|
endif (HAVE___ATTRIBUTE__)
|
||||||
|
|
||||||
@ -435,40 +310,10 @@ else (HAVE___BUILTIN_EXPECT)
|
|||||||
set (ac_cv_have___builtin_expect 0)
|
set (ac_cv_have___builtin_expect 0)
|
||||||
endif (HAVE___BUILTIN_EXPECT)
|
endif (HAVE___BUILTIN_EXPECT)
|
||||||
|
|
||||||
if (HAVE_USING_OPERATOR)
|
|
||||||
set (ac_cv_cxx_using_operator 1)
|
|
||||||
else (HAVE_USING_OPERATOR)
|
|
||||||
set (ac_cv_cxx_using_operator 0)
|
|
||||||
endif (HAVE_USING_OPERATOR)
|
|
||||||
|
|
||||||
if (HAVE_CXX11_CONSTEXPR)
|
|
||||||
set (ac_cv_cxx11_constexpr 1)
|
|
||||||
else (HAVE_CXX11_CONSTEXPR)
|
|
||||||
set (ac_cv_cxx11_constexpr 0)
|
|
||||||
endif (HAVE_CXX11_CONSTEXPR)
|
|
||||||
|
|
||||||
if (HAVE_CXX11_CHRONO)
|
|
||||||
set (ac_cv_cxx11_chrono 1)
|
|
||||||
else (HAVE_CXX11_CHRONO)
|
|
||||||
set (ac_cv_cxx11_chrono 0)
|
|
||||||
endif (HAVE_CXX11_CHRONO)
|
|
||||||
|
|
||||||
if (HAVE_CXX11_NULLPTR_T)
|
|
||||||
set (ac_cv_cxx11_nullptr_t 1)
|
|
||||||
else (HAVE_CXX11_NULLPTR_T)
|
|
||||||
set (ac_cv_cxx11_nullptr_t 0)
|
|
||||||
endif (HAVE_CXX11_NULLPTR_T)
|
|
||||||
|
|
||||||
if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
|
if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
|
||||||
set (HAVE_STACKTRACE 1)
|
set (HAVE_STACKTRACE 1)
|
||||||
endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
|
endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
|
||||||
|
|
||||||
if (HAVE_CXX11_ATOMIC)
|
|
||||||
set (ac_cv_cxx11_atomic 1)
|
|
||||||
else (HAVE_CXX11_ATOMIC)
|
|
||||||
set (ac_cv_cxx11_atomic 0)
|
|
||||||
endif (HAVE_CXX11_ATOMIC)
|
|
||||||
|
|
||||||
if (WITH_SYMBOLIZE)
|
if (WITH_SYMBOLIZE)
|
||||||
if (WIN32 OR CYGWIN)
|
if (WIN32 OR CYGWIN)
|
||||||
cmake_push_check_state (RESET)
|
cmake_push_check_state (RESET)
|
||||||
@ -645,10 +490,12 @@ add_library (glog_internal OBJECT
|
|||||||
${_glog_BINARY_CMake_MODULES}
|
${_glog_BINARY_CMake_MODULES}
|
||||||
${GLOG_SRCS}
|
${GLOG_SRCS}
|
||||||
)
|
)
|
||||||
|
target_compile_features (glog_internal PUBLIC $<TARGET_PROPERTY:glog,COMPILE_FEATURES>)
|
||||||
|
|
||||||
add_library (glog
|
add_library (glog
|
||||||
$<TARGET_OBJECTS:glog_internal>
|
$<TARGET_OBJECTS:glog_internal>
|
||||||
)
|
)
|
||||||
|
target_compile_features (glog PUBLIC cxx_std_14)
|
||||||
|
|
||||||
add_library (glog::glog ALIAS glog)
|
add_library (glog::glog ALIAS glog)
|
||||||
|
|
||||||
@ -806,21 +653,6 @@ if (BUILD_TESTING)
|
|||||||
-Wno-deprecated)
|
-Wno-deprecated)
|
||||||
endif (HAVE_NO_DEPRECATED)
|
endif (HAVE_NO_DEPRECATED)
|
||||||
|
|
||||||
if (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
|
|
||||||
target_compile_definitions (stl_logging_unittest PRIVATE
|
|
||||||
GLOG_STL_LOGGING_FOR_UNORDERED)
|
|
||||||
endif (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
|
|
||||||
|
|
||||||
if (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
|
|
||||||
target_compile_definitions (stl_logging_unittest PRIVATE
|
|
||||||
GLOG_STL_LOGGING_FOR_TR1_UNORDERED)
|
|
||||||
endif (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
|
|
||||||
|
|
||||||
if (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
|
|
||||||
target_compile_definitions (stl_logging_unittest PRIVATE
|
|
||||||
GLOG_STL_LOGGING_FOR_EXT_HASH)
|
|
||||||
endif (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
|
|
||||||
|
|
||||||
if (HAVE_EXT_SLIST)
|
if (HAVE_EXT_SLIST)
|
||||||
target_compile_definitions (stl_logging_unittest PRIVATE
|
target_compile_definitions (stl_logging_unittest PRIVATE
|
||||||
GLOG_STL_LOGGING_FOR_EXT_SLIST)
|
GLOG_STL_LOGGING_FOR_EXT_SLIST)
|
||||||
|
|||||||
16
README.rst
16
README.rst
@ -3,7 +3,7 @@ Google Logging Library
|
|||||||
|
|
||||||
|Linux Github actions| |Windows Github actions| |macOS Github actions| |Codecov|
|
|Linux Github actions| |Windows Github actions| |macOS Github actions| |Codecov|
|
||||||
|
|
||||||
Google Logging (glog) is a C++98 library that implements application-level
|
Google Logging (glog) is a C++14 library that implements application-level
|
||||||
logging. The library provides logging APIs based on C++-style streams and
|
logging. The library provides logging APIs based on C++-style streams and
|
||||||
various helper macros.
|
various helper macros.
|
||||||
|
|
||||||
@ -430,12 +430,12 @@ for example:
|
|||||||
CHECK_EQ(string("abc")[1], ’b’);
|
CHECK_EQ(string("abc")[1], ’b’);
|
||||||
|
|
||||||
The compiler reports an error if one of the arguments is a pointer and the other
|
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
|
is :cpp:`nullptr`. To work around this, simply :cpp:`static_cast` :cpp:`nullptr` to
|
||||||
the type of the desired pointer.
|
the type of the desired pointer.
|
||||||
|
|
||||||
.. code:: cpp
|
.. code:: cpp
|
||||||
|
|
||||||
CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL));
|
CHECK_EQ(some_ptr, static_cast<SomeType*>(nullptr));
|
||||||
|
|
||||||
Better yet, use the ``CHECK_NOTNULL`` macro:
|
Better yet, use the ``CHECK_NOTNULL`` macro:
|
||||||
|
|
||||||
@ -461,8 +461,8 @@ aborting the application.
|
|||||||
If you are comparing C strings (:cpp:`char *`), a handy set of macros performs
|
If you are comparing C strings (:cpp:`char *`), a handy set of macros performs
|
||||||
case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``,
|
case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``,
|
||||||
``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions
|
``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions
|
||||||
are case-insensitive. You can safely pass :cpp:`NULL` pointers for this macro. They
|
are case-insensitive. You can safely pass :cpp:`nullptr` pointers for this macro. They
|
||||||
treat :cpp:`NULL` and any non-:cpp:`NULL` string as not equal. Two :cpp:`NULL`\
|
treat :cpp:`nullptr` and any non-:cpp:`nullptr` string as not equal. Two :cpp:`nullptr`\
|
||||||
s are equal.
|
s are equal.
|
||||||
|
|
||||||
Note that both arguments may be temporary strings which are destructed
|
Note that both arguments may be temporary strings which are destructed
|
||||||
@ -563,7 +563,7 @@ For example:
|
|||||||
|
|
||||||
/* This function writes a prefix that matches glog's default format.
|
/* This function writes a prefix that matches glog's default format.
|
||||||
* (The third parameter can be used to receive user-supplied data, and is
|
* (The third parameter can be used to receive user-supplied data, and is
|
||||||
* NULL by default.)
|
* nullptr by default.)
|
||||||
*/
|
*/
|
||||||
void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) {
|
void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) {
|
||||||
s << l.severity[0]
|
s << l.severity[0]
|
||||||
@ -668,13 +668,13 @@ description of the current state of errno to their output lines. E.g.
|
|||||||
|
|
||||||
.. code:: cpp
|
.. code:: cpp
|
||||||
|
|
||||||
PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed";
|
PCHECK(write(1, nullptr, 2) >= 0) << "Write nullptr failed";
|
||||||
|
|
||||||
This check fails with the following error message.
|
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]
|
F0825 185142 test.cc:22] Check failed: write(1, nullptr, 2) >= 0 Write nullptr failed: Bad address [14]
|
||||||
|
|
||||||
Syslog
|
Syslog
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|||||||
@ -53,11 +53,10 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
|
|||||||
)
|
)
|
||||||
|
|
||||||
common_copts = [
|
common_copts = [
|
||||||
|
"-std=c++14",
|
||||||
"-DGLOG_BAZEL_BUILD",
|
"-DGLOG_BAZEL_BUILD",
|
||||||
# Inject a C++ namespace.
|
# Inject a C++ namespace.
|
||||||
"-DGOOGLE_NAMESPACE='%s'" % namespace,
|
"-DGOOGLE_NAMESPACE='%s'" % namespace,
|
||||||
"-DHAVE_CXX11_NULLPTR_T",
|
|
||||||
"-DHAVE_STDINT_H",
|
|
||||||
"-DHAVE_STRING_H",
|
"-DHAVE_STRING_H",
|
||||||
"-I%s/glog_internal" % gendir,
|
"-I%s/glog_internal" % gendir,
|
||||||
] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else [])
|
] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else [])
|
||||||
@ -260,12 +259,6 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
|
|||||||
)
|
)
|
||||||
|
|
||||||
common_config = {
|
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_u_int16_t@": "0",
|
||||||
"@ac_cv_have_glog_export@": "0",
|
"@ac_cv_have_glog_export@": "0",
|
||||||
"@ac_google_start_namespace@": "namespace google {",
|
"@ac_google_start_namespace@": "namespace google {",
|
||||||
@ -275,31 +268,23 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
|
|||||||
|
|
||||||
posix_config = dict_union(common_config, {
|
posix_config = dict_union(common_config, {
|
||||||
"@ac_cv___attribute___noinline@": "__attribute__((noinline))",
|
"@ac_cv___attribute___noinline@": "__attribute__((noinline))",
|
||||||
"@ac_cv___attribute___noreturn@": "__attribute__((noreturn))",
|
|
||||||
"@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))",
|
"@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))",
|
||||||
"@ac_cv_have___builtin_expect@": "1",
|
"@ac_cv_have___builtin_expect@": "1",
|
||||||
"@ac_cv_have___uint16@": "0",
|
|
||||||
"@ac_cv_have_libgflags@": "1" if with_gflags else "0",
|
"@ac_cv_have_libgflags@": "1" if with_gflags else "0",
|
||||||
"@ac_cv_have_mode_t@": "1",
|
"@ac_cv_have_mode_t@": "1",
|
||||||
"@ac_cv_have_ssize_t@": "1",
|
"@ac_cv_have_ssize_t@": "1",
|
||||||
"@ac_cv_have_stdint_h@": "1",
|
|
||||||
"@ac_cv_have_systypes_h@": "1",
|
"@ac_cv_have_systypes_h@": "1",
|
||||||
"@ac_cv_have_uint16_t@": "1",
|
|
||||||
"@ac_cv_have_unistd_h@": "1",
|
"@ac_cv_have_unistd_h@": "1",
|
||||||
})
|
})
|
||||||
|
|
||||||
windows_config = dict_union(common_config, {
|
windows_config = dict_union(common_config, {
|
||||||
"@ac_cv___attribute___noinline@": "",
|
"@ac_cv___attribute___noinline@": "",
|
||||||
"@ac_cv___attribute___noreturn@": "__declspec(noreturn)",
|
|
||||||
"@ac_cv___attribute___printf_4_5@": "",
|
"@ac_cv___attribute___printf_4_5@": "",
|
||||||
"@ac_cv_have___builtin_expect@": "0",
|
"@ac_cv_have___builtin_expect@": "0",
|
||||||
"@ac_cv_have___uint16@": "1",
|
|
||||||
"@ac_cv_have_libgflags@": "0",
|
"@ac_cv_have_libgflags@": "0",
|
||||||
"@ac_cv_have_mode_t@": "0",
|
"@ac_cv_have_mode_t@": "0",
|
||||||
"@ac_cv_have_ssize_t@": "0",
|
"@ac_cv_have_ssize_t@": "0",
|
||||||
"@ac_cv_have_stdint_h@": "0",
|
|
||||||
"@ac_cv_have_systypes_h@": "0",
|
"@ac_cv_have_systypes_h@": "0",
|
||||||
"@ac_cv_have_uint16_t@": "0",
|
|
||||||
"@ac_cv_have_unistd_h@": "0",
|
"@ac_cv_have_unistd_h@": "0",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -135,13 +135,14 @@
|
|||||||
#define EnvToString(envname, dflt) \
|
#define EnvToString(envname, dflt) \
|
||||||
(!getenv(envname) ? (dflt) : getenv(envname))
|
(!getenv(envname) ? (dflt) : getenv(envname))
|
||||||
|
|
||||||
#define EnvToBool(envname, dflt) \
|
#define EnvToBool(envname, dflt) \
|
||||||
(!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
|
(!getenv(envname) ? (dflt) \
|
||||||
|
: memchr("tTyY1\0", getenv(envname)[0], 6) != nullptr)
|
||||||
|
|
||||||
#define EnvToInt(envname, dflt) \
|
#define EnvToInt(envname, dflt) \
|
||||||
(!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
|
(!getenv(envname) ? (dflt) : strtol(getenv(envname), nullptr, 10))
|
||||||
|
|
||||||
#define EnvToUInt(envname, dflt) \
|
#define EnvToUInt(envname, dflt) \
|
||||||
(!getenv(envname) ? (dflt) : strtoul(getenv(envname), NULL, 10))
|
(!getenv(envname) ? (dflt) : strtoul(getenv(envname), nullptr, 10))
|
||||||
|
|
||||||
#endif // BASE_COMMANDLINEFLAGS_H__
|
#endif // BASE_COMMANDLINEFLAGS_H__
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
class GoogleInitializer {
|
class GoogleInitializer {
|
||||||
public:
|
public:
|
||||||
typedef void (*void_function)(void);
|
using void_function = void (*)();
|
||||||
GoogleInitializer(const char*, void_function f) {
|
GoogleInitializer(const char*, void_function f) {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,7 +139,7 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
typedef pthread_rwlock_t MutexType;
|
using MutexType = pthread_rwlock_t;
|
||||||
#elif defined(HAVE_PTHREAD)
|
#elif defined(HAVE_PTHREAD)
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
typedef pthread_mutex_t MutexType;
|
typedef pthread_mutex_t MutexType;
|
||||||
@ -194,10 +194,10 @@ class Mutex {
|
|||||||
inline void SetIsSafe() { is_safe_ = true; }
|
inline void SetIsSafe() { is_safe_ = true; }
|
||||||
|
|
||||||
// Catch the error of writing Mutex when intending MutexLock.
|
// Catch the error of writing Mutex when intending MutexLock.
|
||||||
Mutex(Mutex* /*ignored*/) {}
|
explicit Mutex(Mutex * /*ignored*/) {}
|
||||||
// Disallow "evil" constructors
|
// Disallow "evil" constructors
|
||||||
Mutex(const Mutex&);
|
Mutex(const Mutex &) = delete;
|
||||||
void operator=(const Mutex&);
|
void operator=(const Mutex &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Now the implementation of Mutex for various systems
|
// Now the implementation of Mutex for various systems
|
||||||
@ -244,7 +244,7 @@ void Mutex::ReaderUnlock() { Unlock(); }
|
|||||||
|
|
||||||
Mutex::Mutex() {
|
Mutex::Mutex() {
|
||||||
SetIsSafe();
|
SetIsSafe();
|
||||||
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
|
if (is_safe_ && pthread_rwlock_init(&mutex_, nullptr) != 0) abort();
|
||||||
}
|
}
|
||||||
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
|
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
|
||||||
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
|
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
|
||||||
@ -266,7 +266,7 @@ void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
|
|||||||
|
|
||||||
Mutex::Mutex() {
|
Mutex::Mutex() {
|
||||||
SetIsSafe();
|
SetIsSafe();
|
||||||
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
|
if (is_safe_ && pthread_mutex_init(&mutex_, nullptr) != 0) abort();
|
||||||
}
|
}
|
||||||
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
|
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
|
||||||
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
|
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
|
||||||
@ -292,8 +292,8 @@ class MutexLock {
|
|||||||
private:
|
private:
|
||||||
Mutex * const mu_;
|
Mutex * const mu_;
|
||||||
// Disallow "evil" constructors
|
// Disallow "evil" constructors
|
||||||
MutexLock(const MutexLock&);
|
MutexLock(const MutexLock &) = delete;
|
||||||
void operator=(const MutexLock&);
|
void operator=(const MutexLock &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
|
// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
|
||||||
@ -304,8 +304,8 @@ class ReaderMutexLock {
|
|||||||
private:
|
private:
|
||||||
Mutex * const mu_;
|
Mutex * const mu_;
|
||||||
// Disallow "evil" constructors
|
// Disallow "evil" constructors
|
||||||
ReaderMutexLock(const ReaderMutexLock&);
|
ReaderMutexLock(const ReaderMutexLock &) = delete;
|
||||||
void operator=(const ReaderMutexLock&);
|
void operator=(const ReaderMutexLock &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WriterMutexLock {
|
class WriterMutexLock {
|
||||||
@ -315,8 +315,8 @@ class WriterMutexLock {
|
|||||||
private:
|
private:
|
||||||
Mutex * const mu_;
|
Mutex * const mu_;
|
||||||
// Disallow "evil" constructors
|
// Disallow "evil" constructors
|
||||||
WriterMutexLock(const WriterMutexLock&);
|
WriterMutexLock(const WriterMutexLock &) = delete;
|
||||||
void operator=(const WriterMutexLock&);
|
void operator=(const WriterMutexLock &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
|
// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
|
||||||
|
|||||||
@ -74,7 +74,7 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
// Make sure stderr is not buffered as stderr seems to be buffered
|
// Make sure stderr is not buffered as stderr seems to be buffered
|
||||||
// on recent windows.
|
// on recent windows.
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, nullptr);
|
||||||
|
|
||||||
// Test some basics before InitGoogleLogging:
|
// Test some basics before InitGoogleLogging:
|
||||||
CaptureTestStderr();
|
CaptureTestStderr();
|
||||||
|
|||||||
@ -79,7 +79,7 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
// Make sure stderr is not buffered as stderr seems to be buffered
|
// Make sure stderr is not buffered as stderr seems to be buffered
|
||||||
// on recent windows.
|
// on recent windows.
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, nullptr);
|
||||||
|
|
||||||
// Test some basics before InitGoogleLogging:
|
// Test some basics before InitGoogleLogging:
|
||||||
CaptureTestStderr();
|
CaptureTestStderr();
|
||||||
|
|||||||
@ -75,7 +75,7 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
// Make sure stderr is not buffered as stderr seems to be buffered
|
// Make sure stderr is not buffered as stderr seems to be buffered
|
||||||
// on recent windows.
|
// on recent windows.
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, nullptr);
|
||||||
|
|
||||||
// Test some basics before InitGoogleLogging:
|
// Test some basics before InitGoogleLogging:
|
||||||
CaptureTestStderr();
|
CaptureTestStderr();
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
#ifndef GLOG_CONFIG_H
|
#ifndef GLOG_CONFIG_H
|
||||||
#define GLOG_CONFIG_H
|
#define GLOG_CONFIG_H
|
||||||
|
|
||||||
/* define if glog doesn't use RTTI */
|
|
||||||
#cmakedefine DISABLE_RTTI
|
|
||||||
|
|
||||||
/* Namespace for Google classes */
|
/* Namespace for Google classes */
|
||||||
#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE}
|
#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE}
|
||||||
|
|
||||||
@ -28,9 +25,6 @@
|
|||||||
/* Define to 1 if you have the <glob.h> header file. */
|
/* Define to 1 if you have the <glob.h> header file. */
|
||||||
#cmakedefine HAVE_GLOB_H
|
#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). */
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
#cmakedefine HAVE_LIBPTHREAD
|
#cmakedefine HAVE_LIBPTHREAD
|
||||||
|
|
||||||
@ -55,9 +49,6 @@
|
|||||||
/* define to disable multithreading support. */
|
/* define to disable multithreading support. */
|
||||||
#cmakedefine NO_THREADS
|
#cmakedefine NO_THREADS
|
||||||
|
|
||||||
/* define if the compiler implements namespaces */
|
|
||||||
#cmakedefine HAVE_NAMESPACES
|
|
||||||
|
|
||||||
/* Define if you have the 'pread' function */
|
/* Define if you have the 'pread' function */
|
||||||
#cmakedefine HAVE_PREAD
|
#cmakedefine HAVE_PREAD
|
||||||
|
|
||||||
@ -79,9 +70,6 @@
|
|||||||
/* Define if you have the `sigaltstack' function */
|
/* Define if you have the `sigaltstack' function */
|
||||||
#cmakedefine HAVE_SIGALTSTACK
|
#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. */
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
#cmakedefine HAVE_STRINGS_H
|
#cmakedefine HAVE_STRINGS_H
|
||||||
|
|
||||||
@ -124,9 +112,6 @@
|
|||||||
/* Define if you linking to _Unwind_GetIP is possible. */
|
/* Define if you linking to _Unwind_GetIP is possible. */
|
||||||
#cmakedefine HAVE__UNWIND_GETIP
|
#cmakedefine HAVE__UNWIND_GETIP
|
||||||
|
|
||||||
/* define if the compiler supports using expression for operator */
|
|
||||||
#cmakedefine HAVE_USING_OPERATOR
|
|
||||||
|
|
||||||
/* define if your compiler has __attribute__ */
|
/* define if your compiler has __attribute__ */
|
||||||
#cmakedefine HAVE___ATTRIBUTE__
|
#cmakedefine HAVE___ATTRIBUTE__
|
||||||
|
|
||||||
@ -149,27 +134,6 @@
|
|||||||
*/
|
*/
|
||||||
#cmakedefine LT_OBJDIR
|
#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 */
|
/* How to access the PC from a struct ucontext */
|
||||||
#cmakedefine PC_FROM_UCONTEXT
|
#cmakedefine PC_FROM_UCONTEXT
|
||||||
|
|
||||||
@ -183,29 +147,11 @@
|
|||||||
/* The size of `void *', as computed by sizeof. */
|
/* The size of `void *', as computed by sizeof. */
|
||||||
#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P}
|
#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P}
|
||||||
|
|
||||||
/* the namespace where STL code like vector<> is defined */
|
|
||||||
#cmakedefine STL_NAMESPACE ${STL_NAMESPACE}
|
|
||||||
|
|
||||||
/* location of source code */
|
/* location of source code */
|
||||||
#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
|
#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
|
||||||
|
|
||||||
/* Define to necessary thread-local storage attribute. */
|
/* Define if thread-local storage is enabled. */
|
||||||
#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE}
|
#cmakedefine 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
|
#ifdef GLOG_BAZEL_BUILD
|
||||||
|
|
||||||
|
|||||||
161
src/demangle.cc
161
src/demangle.cc
@ -34,9 +34,10 @@
|
|||||||
//
|
//
|
||||||
// Note that we only have partial C++0x support yet.
|
// Note that we only have partial C++0x support yet.
|
||||||
|
|
||||||
#include <cstdio> // for NULL
|
|
||||||
|
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
|
|
||||||
|
#include <cstdio> // for nullptr
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
#if defined(GLOG_OS_WINDOWS)
|
#if defined(GLOG_OS_WINDOWS)
|
||||||
@ -53,99 +54,49 @@ struct AbbrevPair {
|
|||||||
|
|
||||||
// List of operators from Itanium C++ ABI.
|
// List of operators from Itanium C++ ABI.
|
||||||
static const AbbrevPair kOperatorList[] = {
|
static const AbbrevPair kOperatorList[] = {
|
||||||
{ "nw", "new" },
|
{"nw", "new"}, {"na", "new[]"}, {"dl", "delete"}, {"da", "delete[]"},
|
||||||
{ "na", "new[]" },
|
{"ps", "+"}, {"ng", "-"}, {"ad", "&"}, {"de", "*"},
|
||||||
{ "dl", "delete" },
|
{"co", "~"}, {"pl", "+"}, {"mi", "-"}, {"ml", "*"},
|
||||||
{ "da", "delete[]" },
|
{"dv", "/"}, {"rm", "%"}, {"an", "&"}, {"or", "|"},
|
||||||
{ "ps", "+" },
|
{"eo", "^"}, {"aS", "="}, {"pL", "+="}, {"mI", "-="},
|
||||||
{ "ng", "-" },
|
{"mL", "*="}, {"dV", "/="}, {"rM", "%="}, {"aN", "&="},
|
||||||
{ "ad", "&" },
|
{"oR", "|="}, {"eO", "^="}, {"ls", "<<"}, {"rs", ">>"},
|
||||||
{ "de", "*" },
|
{"lS", "<<="}, {"rS", ">>="}, {"eq", "=="}, {"ne", "!="},
|
||||||
{ "co", "~" },
|
{"lt", "<"}, {"gt", ">"}, {"le", "<="}, {"ge", ">="},
|
||||||
{ "pl", "+" },
|
{"nt", "!"}, {"aa", "&&"}, {"oo", "||"}, {"pp", "++"},
|
||||||
{ "mi", "-" },
|
{"mm", "--"}, {"cm", ","}, {"pm", "->*"}, {"pt", "->"},
|
||||||
{ "ml", "*" },
|
{"cl", "()"}, {"ix", "[]"}, {"qu", "?"}, {"st", "sizeof"},
|
||||||
{ "dv", "/" },
|
{"sz", "sizeof"}, {nullptr, nullptr},
|
||||||
{ "rm", "%" },
|
|
||||||
{ "an", "&" },
|
|
||||||
{ "or", "|" },
|
|
||||||
{ "eo", "^" },
|
|
||||||
{ "aS", "=" },
|
|
||||||
{ "pL", "+=" },
|
|
||||||
{ "mI", "-=" },
|
|
||||||
{ "mL", "*=" },
|
|
||||||
{ "dV", "/=" },
|
|
||||||
{ "rM", "%=" },
|
|
||||||
{ "aN", "&=" },
|
|
||||||
{ "oR", "|=" },
|
|
||||||
{ "eO", "^=" },
|
|
||||||
{ "ls", "<<" },
|
|
||||||
{ "rs", ">>" },
|
|
||||||
{ "lS", "<<=" },
|
|
||||||
{ "rS", ">>=" },
|
|
||||||
{ "eq", "==" },
|
|
||||||
{ "ne", "!=" },
|
|
||||||
{ "lt", "<" },
|
|
||||||
{ "gt", ">" },
|
|
||||||
{ "le", "<=" },
|
|
||||||
{ "ge", ">=" },
|
|
||||||
{ "nt", "!" },
|
|
||||||
{ "aa", "&&" },
|
|
||||||
{ "oo", "||" },
|
|
||||||
{ "pp", "++" },
|
|
||||||
{ "mm", "--" },
|
|
||||||
{ "cm", "," },
|
|
||||||
{ "pm", "->*" },
|
|
||||||
{ "pt", "->" },
|
|
||||||
{ "cl", "()" },
|
|
||||||
{ "ix", "[]" },
|
|
||||||
{ "qu", "?" },
|
|
||||||
{ "st", "sizeof" },
|
|
||||||
{ "sz", "sizeof" },
|
|
||||||
{ NULL, NULL },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// List of builtin types from Itanium C++ ABI.
|
// List of builtin types from Itanium C++ ABI.
|
||||||
static const AbbrevPair kBuiltinTypeList[] = {
|
static const AbbrevPair kBuiltinTypeList[] = {
|
||||||
{ "v", "void" },
|
{"v", "void"}, {"w", "wchar_t"},
|
||||||
{ "w", "wchar_t" },
|
{"b", "bool"}, {"c", "char"},
|
||||||
{ "b", "bool" },
|
{"a", "signed char"}, {"h", "unsigned char"},
|
||||||
{ "c", "char" },
|
{"s", "short"}, {"t", "unsigned short"},
|
||||||
{ "a", "signed char" },
|
{"i", "int"}, {"j", "unsigned int"},
|
||||||
{ "h", "unsigned char" },
|
{"l", "long"}, {"m", "unsigned long"},
|
||||||
{ "s", "short" },
|
{"x", "long long"}, {"y", "unsigned long long"},
|
||||||
{ "t", "unsigned short" },
|
{"n", "__int128"}, {"o", "unsigned __int128"},
|
||||||
{ "i", "int" },
|
{"f", "float"}, {"d", "double"},
|
||||||
{ "j", "unsigned int" },
|
{"e", "long double"}, {"g", "__float128"},
|
||||||
{ "l", "long" },
|
{"z", "ellipsis"}, {nullptr, nullptr}};
|
||||||
{ "m", "unsigned long" },
|
|
||||||
{ "x", "long long" },
|
|
||||||
{ "y", "unsigned long long" },
|
|
||||||
{ "n", "__int128" },
|
|
||||||
{ "o", "unsigned __int128" },
|
|
||||||
{ "f", "float" },
|
|
||||||
{ "d", "double" },
|
|
||||||
{ "e", "long double" },
|
|
||||||
{ "g", "__float128" },
|
|
||||||
{ "z", "ellipsis" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
// List of substitutions Itanium C++ ABI.
|
// List of substitutions Itanium C++ ABI.
|
||||||
static const AbbrevPair kSubstitutionList[] = {
|
static const AbbrevPair kSubstitutionList[] = {
|
||||||
{ "St", "" },
|
{"St", ""},
|
||||||
{ "Sa", "allocator" },
|
{"Sa", "allocator"},
|
||||||
{ "Sb", "basic_string" },
|
{"Sb", "basic_string"},
|
||||||
// std::basic_string<char, std::char_traits<char>,std::allocator<char> >
|
// std::basic_string<char, std::char_traits<char>,std::allocator<char> >
|
||||||
{ "Ss", "string"},
|
{"Ss", "string"},
|
||||||
// std::basic_istream<char, std::char_traits<char> >
|
// std::basic_istream<char, std::char_traits<char> >
|
||||||
{ "Si", "istream" },
|
{"Si", "istream"},
|
||||||
// std::basic_ostream<char, std::char_traits<char> >
|
// std::basic_ostream<char, std::char_traits<char> >
|
||||||
{ "So", "ostream" },
|
{"So", "ostream"},
|
||||||
// std::basic_iostream<char, std::char_traits<char> >
|
// std::basic_iostream<char, std::char_traits<char> >
|
||||||
{ "Sd", "iostream" },
|
{"Sd", "iostream"},
|
||||||
{ NULL, NULL }
|
{nullptr, nullptr}};
|
||||||
};
|
|
||||||
|
|
||||||
// State needed for demangling.
|
// State needed for demangling.
|
||||||
struct State {
|
struct State {
|
||||||
@ -197,7 +148,7 @@ static void InitState(State *state, const char *mangled,
|
|||||||
state->out_cur = out;
|
state->out_cur = out;
|
||||||
state->out_begin = out;
|
state->out_begin = out;
|
||||||
state->out_end = out + out_size;
|
state->out_end = out + out_size;
|
||||||
state->prev_name = NULL;
|
state->prev_name = nullptr;
|
||||||
state->prev_name_length = -1;
|
state->prev_name_length = -1;
|
||||||
state->nest_level = -1;
|
state->nest_level = -1;
|
||||||
state->append = true;
|
state->append = true;
|
||||||
@ -246,7 +197,7 @@ static bool Optional(bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function is used for handling <non-terminal>+ syntax.
|
// This function is used for handling <non-terminal>+ syntax.
|
||||||
typedef bool (*ParseFunc)(State *);
|
using ParseFunc = bool (*)(State *);
|
||||||
static bool OneOrMore(ParseFunc parse_func, State *state) {
|
static bool OneOrMore(ParseFunc parse_func, State *state) {
|
||||||
if (parse_func(state)) {
|
if (parse_func(state)) {
|
||||||
while (parse_func(state)) {
|
while (parse_func(state)) {
|
||||||
@ -650,7 +601,7 @@ static bool ParseNumber(State *state, int *number_out) {
|
|||||||
}
|
}
|
||||||
if (p != state->mangled_cur) { // Conversion succeeded.
|
if (p != state->mangled_cur) { // Conversion succeeded.
|
||||||
state->mangled_cur = p;
|
state->mangled_cur = p;
|
||||||
if (number_out != NULL) {
|
if (number_out != nullptr) {
|
||||||
*number_out = number * sign;
|
*number_out = number * sign;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -755,7 +706,7 @@ static bool ParseOperatorName(State *state) {
|
|||||||
}
|
}
|
||||||
// We may want to perform a binary search if we really need speed.
|
// We may want to perform a binary search if we really need speed.
|
||||||
const AbbrevPair *p;
|
const AbbrevPair *p;
|
||||||
for (p = kOperatorList; p->abbrev != NULL; ++p) {
|
for (p = kOperatorList; p->abbrev != nullptr; ++p) {
|
||||||
if (state->mangled_cur[0] == p->abbrev[0] &&
|
if (state->mangled_cur[0] == p->abbrev[0] &&
|
||||||
state->mangled_cur[1] == p->abbrev[1]) {
|
state->mangled_cur[1] == p->abbrev[1]) {
|
||||||
MaybeAppend(state, "operator");
|
MaybeAppend(state, "operator");
|
||||||
@ -817,9 +768,8 @@ static bool ParseSpecialName(State *state) {
|
|||||||
|
|
||||||
// G++ extensions
|
// G++ extensions
|
||||||
if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
|
if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
|
||||||
ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
|
ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
|
||||||
DisableAppend(state) &&
|
DisableAppend(state) && ParseType(state)) {
|
||||||
ParseType(state)) {
|
|
||||||
RestoreAppend(state, copy.append);
|
RestoreAppend(state, copy.append);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -869,15 +819,13 @@ static bool ParseCallOffset(State *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// <nv-offset> ::= <(offset) number>
|
// <nv-offset> ::= <(offset) number>
|
||||||
static bool ParseNVOffset(State *state) {
|
static bool ParseNVOffset(State *state) { return ParseNumber(state, nullptr); }
|
||||||
return ParseNumber(state, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// <v-offset> ::= <(offset) number> _ <(virtual offset) number>
|
// <v-offset> ::= <(offset) number> _ <(virtual offset) number>
|
||||||
static bool ParseVOffset(State *state) {
|
static bool ParseVOffset(State *state) {
|
||||||
State copy = *state;
|
State copy = *state;
|
||||||
if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
|
if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
|
||||||
ParseNumber(state, NULL)) {
|
ParseNumber(state, nullptr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
@ -997,7 +945,7 @@ static bool ParseCVQualifiers(State *state) {
|
|||||||
// ::= u <source-name>
|
// ::= u <source-name>
|
||||||
static bool ParseBuiltinType(State *state) {
|
static bool ParseBuiltinType(State *state) {
|
||||||
const AbbrevPair *p;
|
const AbbrevPair *p;
|
||||||
for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
|
for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
|
||||||
if (state->mangled_cur[0] == p->abbrev[0]) {
|
if (state->mangled_cur[0] == p->abbrev[0]) {
|
||||||
MaybeAppend(state, p->real_name);
|
MaybeAppend(state, p->real_name);
|
||||||
++state->mangled_cur;
|
++state->mangled_cur;
|
||||||
@ -1047,7 +995,7 @@ static bool ParseClassEnumType(State *state) {
|
|||||||
// ::= A [<(dimension) expression>] _ <(element) type>
|
// ::= A [<(dimension) expression>] _ <(element) type>
|
||||||
static bool ParseArrayType(State *state) {
|
static bool ParseArrayType(State *state) {
|
||||||
State copy = *state;
|
State copy = *state;
|
||||||
if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) &&
|
if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
|
||||||
ParseOneCharToken(state, '_') && ParseType(state)) {
|
ParseOneCharToken(state, '_') && ParseType(state)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1081,7 +1029,7 @@ static bool ParseTemplateParam(State *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
State copy = *state;
|
State copy = *state;
|
||||||
if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) &&
|
if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
|
||||||
ParseOneCharToken(state, '_')) {
|
ParseOneCharToken(state, '_')) {
|
||||||
MaybeAppend(state, "?"); // We don't support template substitutions.
|
MaybeAppend(state, "?"); // We don't support template substitutions.
|
||||||
return true;
|
return true;
|
||||||
@ -1205,8 +1153,7 @@ static bool ParseExpression(State *state) {
|
|||||||
static bool ParseExprPrimary(State *state) {
|
static bool ParseExprPrimary(State *state) {
|
||||||
State copy = *state;
|
State copy = *state;
|
||||||
if (ParseOneCharToken(state, 'L') && ParseType(state) &&
|
if (ParseOneCharToken(state, 'L') && ParseType(state) &&
|
||||||
ParseNumber(state, NULL) &&
|
ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
|
||||||
ParseOneCharToken(state, 'E')) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
@ -1256,7 +1203,7 @@ static bool ParseLocalName(State *state) {
|
|||||||
// <discriminator> := _ <(non-negative) number>
|
// <discriminator> := _ <(non-negative) number>
|
||||||
static bool ParseDiscriminator(State *state) {
|
static bool ParseDiscriminator(State *state) {
|
||||||
State copy = *state;
|
State copy = *state;
|
||||||
if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) {
|
if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*state = copy;
|
*state = copy;
|
||||||
@ -1283,7 +1230,7 @@ static bool ParseSubstitution(State *state) {
|
|||||||
// Expand abbreviations like "St" => "std".
|
// Expand abbreviations like "St" => "std".
|
||||||
if (ParseOneCharToken(state, 'S')) {
|
if (ParseOneCharToken(state, 'S')) {
|
||||||
const AbbrevPair *p;
|
const AbbrevPair *p;
|
||||||
for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
|
for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
|
||||||
if (state->mangled_cur[0] == p->abbrev[1]) {
|
if (state->mangled_cur[0] == p->abbrev[1]) {
|
||||||
MaybeAppend(state, "std");
|
MaybeAppend(state, "std");
|
||||||
if (p->real_name[0] != '\0') {
|
if (p->real_name[0] != '\0') {
|
||||||
|
|||||||
@ -94,7 +94,7 @@ TEST(Demangle, CornerCases) {
|
|||||||
EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough.
|
EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough.
|
||||||
EXPECT_FALSE(Demangle(mangled, tmp, 1));
|
EXPECT_FALSE(Demangle(mangled, tmp, 1));
|
||||||
EXPECT_FALSE(Demangle(mangled, tmp, 0));
|
EXPECT_FALSE(Demangle(mangled, tmp, 0));
|
||||||
EXPECT_FALSE(Demangle(mangled, NULL, 0)); // Should not cause SEGV.
|
EXPECT_FALSE(Demangle(mangled, nullptr, 0)); // Should not cause SEGV.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test handling of functions suffixed with .clone.N, which is used by GCC
|
// Test handling of functions suffixed with .clone.N, which is used by GCC
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007, Google Inc.
|
// Copyright (c) 2023, Google Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
@ -48,7 +48,7 @@
|
|||||||
// Variables of type LogSeverity are widely taken to lie in the range
|
// Variables of type LogSeverity are widely taken to lie in the range
|
||||||
// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
|
// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
|
||||||
// you ever need to change their values or add a new severity.
|
// you ever need to change their values or add a new severity.
|
||||||
typedef int LogSeverity;
|
using LogSeverity = int;
|
||||||
|
|
||||||
const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
|
const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
|
||||||
NUM_SEVERITIES = 4;
|
NUM_SEVERITIES = 4;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2022, Google Inc.
|
// Copyright (c) 2023, Google Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
@ -36,11 +36,8 @@
|
|||||||
#ifndef GLOG_LOGGING_H
|
#ifndef GLOG_LOGGING_H
|
||||||
#define GLOG_LOGGING_H
|
#define GLOG_LOGGING_H
|
||||||
|
|
||||||
#if @ac_cv_cxx11_chrono@ && __cplusplus >= 201103L
|
|
||||||
#include <chrono>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <chrono>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -75,46 +72,23 @@
|
|||||||
// Note: these commands below may look like "#if 1" or "#if 0", but
|
// Note: these commands below may look like "#if 1" or "#if 0", but
|
||||||
// that's because they were constructed that way at ./configure time.
|
// that's because they were constructed that way at ./configure time.
|
||||||
// Look at logging.h.in to see how they're calculated (based on your config).
|
// Look at logging.h.in to see how they're calculated (based on your config).
|
||||||
#if @ac_cv_have_stdint_h@
|
#include <cstdint> // the normal place uint16_t is defined
|
||||||
#include <stdint.h> // the normal place uint16_t is defined
|
|
||||||
#endif
|
|
||||||
#if @ac_cv_have_systypes_h@
|
#if @ac_cv_have_systypes_h@
|
||||||
#include <sys/types.h> // the normal place u_int16_t is defined
|
#include <sys/types.h> // the normal place u_int16_t is defined
|
||||||
#endif
|
#endif
|
||||||
#if @ac_cv_have_inttypes_h@
|
|
||||||
#include <inttypes.h> // a third place for uint16_t or u_int16_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if @ac_cv_have_libgflags@
|
#if @ac_cv_have_libgflags@
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ac_google_start_namespace@
|
@ac_google_start_namespace@
|
||||||
|
|
||||||
#if @ac_cv_have_stdint_h@ // the C99 format
|
typedef std::int32_t int32;
|
||||||
typedef int32_t int32;
|
typedef std::uint32_t uint32;
|
||||||
typedef uint32_t uint32;
|
typedef std::int64_t int64;
|
||||||
typedef int64_t int64;
|
typedef std::uint64_t uint64;
|
||||||
typedef uint64_t uint64;
|
|
||||||
#elif @ac_cv_have_u_int16_t@ // the BSD format
|
|
||||||
typedef int32_t int32;
|
|
||||||
typedef u_int32_t uint32;
|
|
||||||
typedef int64_t int64;
|
|
||||||
typedef u_int64_t uint64;
|
|
||||||
#elif @ac_cv_have___uint16@ // the windows (vc7) format
|
|
||||||
typedef __int32 int32;
|
|
||||||
typedef unsigned __int32 uint32;
|
|
||||||
typedef __int64 int64;
|
|
||||||
typedef unsigned __int64 uint64;
|
|
||||||
#else
|
|
||||||
#error Do not know how to define a 32-bit integer quantity on your system
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !(@ac_cv_have_ssize_t@)
|
#if !(@ac_cv_have_ssize_t@)
|
||||||
typedef ptrdiff_t ssize_t;
|
typedef ptrdiff_t ssize_t;
|
||||||
@ -743,13 +717,11 @@ inline unsigned short GetReferenceableValue(unsigned short t) { return t; }
|
|||||||
inline int GetReferenceableValue(int t) { return t; }
|
inline int GetReferenceableValue(int t) { return t; }
|
||||||
inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
|
inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
|
||||||
inline long GetReferenceableValue(long t) { return t; }
|
inline long GetReferenceableValue(long t) { return t; }
|
||||||
inline unsigned long GetReferenceableValue(unsigned long t) { return t; }
|
inline unsigned long GetReferenceableValue(unsigned long t) { return t; }
|
||||||
#if __cplusplus >= 201103L
|
|
||||||
inline long long GetReferenceableValue(long long t) { return t; }
|
inline long long GetReferenceableValue(long long t) { return t; }
|
||||||
inline unsigned long long GetReferenceableValue(unsigned long long t) {
|
inline unsigned long long GetReferenceableValue(unsigned long long t) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is a dummy class to define the following operator.
|
// This is a dummy class to define the following operator.
|
||||||
struct DummyClassToDefineOperator {};
|
struct DummyClassToDefineOperator {};
|
||||||
@ -782,12 +754,10 @@ void MakeCheckOpValueString(std::ostream* os, const signed char& v);
|
|||||||
template <> GLOG_EXPORT
|
template <> GLOG_EXPORT
|
||||||
void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
|
void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
|
||||||
|
|
||||||
// This is required because nullptr is only present in c++ 11 and later.
|
|
||||||
#if @ac_cv_cxx11_nullptr_t@ && __cplusplus >= 201103L
|
|
||||||
// Provide printable value for nullptr_t
|
// Provide printable value for nullptr_t
|
||||||
template <> GLOG_EXPORT
|
template <>
|
||||||
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v);
|
GLOG_EXPORT void MakeCheckOpValueString(std::ostream* os,
|
||||||
#endif
|
const std::nullptr_t& v);
|
||||||
|
|
||||||
// Build the error message string. Specify no inlining for code size.
|
// Build the error message string. Specify no inlining for code size.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
@ -1031,12 +1001,6 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \
|
|||||||
#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
|
#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
|
||||||
#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
|
#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
|
||||||
|
|
||||||
#if @ac_cv_cxx11_constexpr@ && __cplusplus >= 201103L
|
|
||||||
#define GLOG_CONSTEXPR constexpr
|
|
||||||
#else
|
|
||||||
#define GLOG_CONSTEXPR const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__)
|
#define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__)
|
||||||
#define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__)
|
#define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__)
|
||||||
#define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__)
|
#define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__)
|
||||||
@ -1074,54 +1038,34 @@ extern "C" void AnnotateBenignRaceSized(
|
|||||||
namespace google {
|
namespace google {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus >= 201103L && @ac_cv_cxx11_chrono@ && @ac_cv_cxx11_atomic@ // Have <chrono> and <atomic>
|
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
|
||||||
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
|
constexpr std::chrono::nanoseconds LOG_TIME_PERIOD = \
|
||||||
GLOG_CONSTEXPR std::chrono::nanoseconds LOG_TIME_PERIOD = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(seconds)); \
|
std::chrono::duration_cast<std::chrono::nanoseconds>( \
|
||||||
static std::atomic<@ac_google_namespace@::int64> LOG_PREVIOUS_TIME_RAW; \
|
std::chrono::duration<double>(seconds)); \
|
||||||
GLOG_IFDEF_THREAD_SANITIZER( \
|
static std::atomic<@ac_google_namespace@ ::int64> LOG_PREVIOUS_TIME_RAW; \
|
||||||
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, sizeof(@ac_google_namespace@::int64), "")); \
|
GLOG_IFDEF_THREAD_SANITIZER( \
|
||||||
GLOG_IFDEF_THREAD_SANITIZER( \
|
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, \
|
||||||
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, sizeof(@ac_google_namespace@::int64), "")); \
|
sizeof(@ac_google_namespace @ ::int64), "")); \
|
||||||
const auto LOG_CURRENT_TIME = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()); \
|
GLOG_IFDEF_THREAD_SANITIZER( \
|
||||||
const auto LOG_PREVIOUS_TIME = LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \
|
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, \
|
||||||
const auto LOG_TIME_DELTA = LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \
|
sizeof(@ac_google_namespace @ ::int64), "")); \
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
|
const auto LOG_CURRENT_TIME = \
|
||||||
LOG_PREVIOUS_TIME_RAW.store(std::chrono::duration_cast<std::chrono::nanoseconds>(LOG_CURRENT_TIME).count(), std::memory_order_relaxed); \
|
std::chrono::duration_cast<std::chrono::nanoseconds>( \
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \
|
std::chrono::steady_clock::now().time_since_epoch()); \
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
|
const auto LOG_PREVIOUS_TIME = \
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \
|
||||||
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
|
const auto LOG_TIME_DELTA = \
|
||||||
GLOG_CONSTEXPR LONGLONG LOG_TIME_PERIOD = (seconds) * LONGLONG(1000000000); \
|
LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \
|
||||||
static LARGE_INTEGER LOG_PREVIOUS_TIME; \
|
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
|
||||||
LONGLONG LOG_TIME_DELTA; \
|
LOG_PREVIOUS_TIME_RAW.store( \
|
||||||
{ \
|
std::chrono::duration_cast<std::chrono::nanoseconds>(LOG_CURRENT_TIME) \
|
||||||
LARGE_INTEGER currTime; \
|
.count(), \
|
||||||
LARGE_INTEGER freq; \
|
std::memory_order_relaxed); \
|
||||||
QueryPerformanceCounter(&currTime); \
|
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
|
||||||
QueryPerformanceFrequency(&freq); \
|
@ac_google_namespace@ ::LogMessage( \
|
||||||
InterlockedCompareExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart, 0); \
|
__FILE__, __LINE__, @ac_google_namespace@ ::GLOG_##severity) \
|
||||||
LOG_TIME_DELTA = (currTime.QuadPart - LOG_PREVIOUS_TIME.QuadPart) * LONGLONG(1000000000) / freq.QuadPart; \
|
.stream()
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) InterlockedExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart); \
|
|
||||||
} \
|
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
|
|
||||||
#else
|
|
||||||
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
|
|
||||||
GLOG_CONSTEXPR @ac_google_namespace@::int64 LOG_TIME_PERIOD(seconds * 1000000000); \
|
|
||||||
static @ac_google_namespace@::int64 LOG_PREVIOUS_TIME; \
|
|
||||||
@ac_google_namespace@::int64 LOG_TIME_DELTA = 0; \
|
|
||||||
{ \
|
|
||||||
timespec currentTime = {}; \
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, ¤tTime); \
|
|
||||||
LOG_TIME_DELTA = (currentTime.tv_sec * 1000000000 + currentTime.tv_nsec) - LOG_PREVIOUS_TIME; \
|
|
||||||
} \
|
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) __sync_add_and_fetch(&LOG_PREVIOUS_TIME, LOG_TIME_DELTA); \
|
|
||||||
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
|
|
||||||
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
|
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
|
||||||
static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
|
static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
|
||||||
GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
|
GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
|
||||||
@ -1165,94 +1109,6 @@ namespace google {
|
|||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
||||||
&what_to_do).stream()
|
&what_to_do).stream()
|
||||||
|
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES = 0; \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
InterlockedIncrement(&LOG_OCCURRENCES); \
|
|
||||||
if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
|
|
||||||
InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
|
|
||||||
if (LOG_OCCURRENCES_MOD_N == 1) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES = 0; \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
InterlockedIncrement(&LOG_OCCURRENCES); \
|
|
||||||
if ((condition) && \
|
|
||||||
((InterlockedIncrement(&LOG_OCCURRENCES_MOD_N), \
|
|
||||||
(LOG_OCCURRENCES_MOD_N > n && InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n))), \
|
|
||||||
LOG_OCCURRENCES_MOD_N == 1)) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES = 0; \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
InterlockedIncrement(&LOG_OCCURRENCES); \
|
|
||||||
if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
|
|
||||||
InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
|
|
||||||
if (LOG_OCCURRENCES_MOD_N == 1) \
|
|
||||||
@ac_google_namespace@::ErrnoLogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
|
|
||||||
static volatile unsigned LOG_OCCURRENCES = 0; \
|
|
||||||
if (LOG_OCCURRENCES <= n) \
|
|
||||||
InterlockedIncrement(&LOG_OCCURRENCES); \
|
|
||||||
if (LOG_OCCURRENCES <= n) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
|
|
||||||
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
|
|
||||||
if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
|
|
||||||
__sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
|
|
||||||
if (LOG_OCCURRENCES_MOD_N == 1) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
|
|
||||||
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
|
|
||||||
if ((condition) && \
|
|
||||||
(__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) || true) && \
|
|
||||||
((LOG_OCCURRENCES_MOD_N >= n && __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n)) || true) && \
|
|
||||||
LOG_OCCURRENCES_MOD_N == (1 % n)) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
|
|
||||||
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
|
|
||||||
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
|
|
||||||
if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
|
|
||||||
__sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
|
|
||||||
if (LOG_OCCURRENCES_MOD_N == 1) \
|
|
||||||
@ac_google_namespace@::ErrnoLogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
|
|
||||||
#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
|
|
||||||
static int LOG_OCCURRENCES = 0; \
|
|
||||||
if (LOG_OCCURRENCES <= n) \
|
|
||||||
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
|
|
||||||
if (LOG_OCCURRENCES <= n) \
|
|
||||||
@ac_google_namespace@::LogMessage( \
|
|
||||||
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
|
|
||||||
&what_to_do).stream()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace glog_internal_namespace_ {
|
namespace glog_internal_namespace_ {
|
||||||
template <bool>
|
template <bool>
|
||||||
struct CompileAssert {
|
struct CompileAssert {
|
||||||
@ -1575,7 +1431,7 @@ public:
|
|||||||
void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs
|
void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs
|
||||||
|
|
||||||
// Call abort() or similar to perform LOG(FATAL) crash.
|
// Call abort() or similar to perform LOG(FATAL) crash.
|
||||||
static void @ac_cv___attribute___noreturn@ Fail();
|
[[noreturn]] static void Fail();
|
||||||
|
|
||||||
std::ostream& stream();
|
std::ostream& stream();
|
||||||
|
|
||||||
@ -1626,7 +1482,7 @@ class GLOG_EXPORT LogMessageFatal : public LogMessage {
|
|||||||
public:
|
public:
|
||||||
LogMessageFatal(const char* file, int line);
|
LogMessageFatal(const char* file, int line);
|
||||||
LogMessageFatal(const char* file, int line, const CheckOpString& result);
|
LogMessageFatal(const char* file, int line, const CheckOpString& result);
|
||||||
@ac_cv___attribute___noreturn@ ~LogMessageFatal();
|
[[noreturn]] ~LogMessageFatal();
|
||||||
};
|
};
|
||||||
|
|
||||||
// A non-macro interface to the log facility; (useful
|
// A non-macro interface to the log facility; (useful
|
||||||
@ -1641,17 +1497,6 @@ inline void LogAtLevel(int const severity, std::string const &msg) {
|
|||||||
// LOG macros, 2. this macro can be used as C++ stream.
|
// LOG macros, 2. this macro can be used as C++ stream.
|
||||||
#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream()
|
#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream()
|
||||||
|
|
||||||
// Check if it's compiled in C++11 mode.
|
|
||||||
//
|
|
||||||
// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least
|
|
||||||
// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1
|
|
||||||
// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is
|
|
||||||
// defined according to the language version in effect thereafter.
|
|
||||||
// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite
|
|
||||||
// reasonably good C++11 support, so we set LANG_CXX for it and
|
|
||||||
// newer versions (_MSC_VER >= 1900).
|
|
||||||
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
|
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined(__UCLIBCXX_MAJOR__)
|
|
||||||
// Helper for CHECK_NOTNULL().
|
// Helper for CHECK_NOTNULL().
|
||||||
//
|
//
|
||||||
// In C++11, all cases can be handled by a single function. Since the value
|
// In C++11, all cases can be handled by a single function. Since the value
|
||||||
@ -1668,18 +1513,6 @@ T CheckNotNull(const char* file, int line, const char* names, T&& t) {
|
|||||||
return std::forward<T>(t);
|
return std::forward<T>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// A small helper for CHECK_NOTNULL().
|
|
||||||
template <typename T>
|
|
||||||
T* CheckNotNull(const char *file, int line, const char *names, T* t) {
|
|
||||||
if (t == NULL) {
|
|
||||||
LogMessageFatal(file, line, new std::string(names));
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
|
// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
|
||||||
// only works if ostream is a LogStream. If the ostream is not a
|
// only works if ostream is a LogStream. If the ostream is not a
|
||||||
// LogStream you'll get an assert saying as much at runtime.
|
// LogStream you'll get an assert saying as much at runtime.
|
||||||
@ -1967,7 +1800,7 @@ class GLOG_EXPORT NullStreamFatal : public NullStream {
|
|||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4722)
|
#pragma warning(disable : 4722)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
@ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(EXIT_FAILURE); }
|
[[noreturn]] ~NullStreamFatal() throw() { _exit(EXIT_FAILURE); }
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|||||||
@ -47,36 +47,16 @@
|
|||||||
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
|
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
|
||||||
#define 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 <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#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
|
// Forward declare these two, and define them after all the container streams
|
||||||
// operators so that we can recurse from pair -> container -> container -> pair
|
// operators so that we can recurse from pair -> container -> container -> pair
|
||||||
// properly.
|
// properly.
|
||||||
@ -89,7 +69,6 @@ template<class Iter>
|
|||||||
void PrintSequence(std::ostream& out, Iter begin, Iter end);
|
void PrintSequence(std::ostream& out, Iter begin, Iter end);
|
||||||
|
|
||||||
@ac_google_end_namespace@
|
@ac_google_end_namespace@
|
||||||
|
|
||||||
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
|
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
|
||||||
template<class T1, class T2> \
|
template<class T1, class T2> \
|
||||||
inline std::ostream& operator<<(std::ostream& out, \
|
inline std::ostream& operator<<(std::ostream& out, \
|
||||||
@ -98,12 +77,8 @@ inline std::ostream& operator<<(std::ostream& out, \
|
|||||||
return out; \
|
return out; \
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT_TWO_ARG_CONTAINER(std::vector)
|
OUTPUT_TWO_ARG_CONTAINER(std::vector) OUTPUT_TWO_ARG_CONTAINER(std::deque)
|
||||||
OUTPUT_TWO_ARG_CONTAINER(std::deque)
|
OUTPUT_TWO_ARG_CONTAINER(std::list)
|
||||||
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
|
#undef OUTPUT_TWO_ARG_CONTAINER
|
||||||
|
|
||||||
@ -115,8 +90,8 @@ inline std::ostream& operator<<(std::ostream& out, \
|
|||||||
return out; \
|
return out; \
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT_THREE_ARG_CONTAINER(std::set)
|
OUTPUT_THREE_ARG_CONTAINER(std::set) OUTPUT_THREE_ARG_CONTAINER(
|
||||||
OUTPUT_THREE_ARG_CONTAINER(std::multiset)
|
std::multiset)
|
||||||
|
|
||||||
#undef OUTPUT_THREE_ARG_CONTAINER
|
#undef OUTPUT_THREE_ARG_CONTAINER
|
||||||
|
|
||||||
@ -128,20 +103,9 @@ inline std::ostream& operator<<(std::ostream& out, \
|
|||||||
return out; \
|
return out; \
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT_FOUR_ARG_CONTAINER(std::map)
|
OUTPUT_FOUR_ARG_CONTAINER(std::map) OUTPUT_FOUR_ARG_CONTAINER(
|
||||||
OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
|
std::multimap) OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
|
||||||
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
|
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
|
||||||
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
|
#undef OUTPUT_FOUR_ARG_CONTAINER
|
||||||
|
|
||||||
@ -154,23 +118,16 @@ inline std::ostream& operator<<(std::ostream& out, \
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
|
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
|
||||||
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
|
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
|
||||||
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
|
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
|
#endif
|
||||||
|
|
||||||
#undef OUTPUT_FIVE_ARG_CONTAINER
|
#undef OUTPUT_FIVE_ARG_CONTAINER
|
||||||
|
|
||||||
template<class First, class Second>
|
template <class First, class Second>
|
||||||
inline std::ostream& operator<<(std::ostream& out,
|
inline std::ostream& operator<<(
|
||||||
const std::pair<First, Second>& p) {
|
std::ostream& out,
|
||||||
|
const std::pair<First, Second>& p) {
|
||||||
out << '(' << p.first << ", " << p.second << ')';
|
out << '(' << p.first << ", " << p.second << ')';
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 1999, 2007, Google Inc.
|
// Copyright (c) 2023, Google Inc.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
@ -63,6 +63,8 @@
|
|||||||
|
|
||||||
#include <glog/log_severity.h>
|
#include <glog/log_severity.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
|
// 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,
|
// (Normally) the first time every VLOG_IS_ON(n) site is hit,
|
||||||
@ -98,7 +100,7 @@ extern GLOG_EXPORT int SetVLOGLevel(const char* module_pattern, int log_level);
|
|||||||
struct SiteFlag {
|
struct SiteFlag {
|
||||||
@ac_google_namespace@::int32* level;
|
@ac_google_namespace@::int32* level;
|
||||||
const char* base_name;
|
const char* base_name;
|
||||||
size_t base_len;
|
std::size_t base_len;
|
||||||
SiteFlag* next;
|
SiteFlag* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#define GOOGLETEST_H__
|
#define GOOGLETEST_H__
|
||||||
|
|
||||||
#include "utilities.h"
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <csetjmp>
|
#include <csetjmp>
|
||||||
@ -45,11 +47,10 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include "utilities.h"
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@ -270,19 +271,17 @@ static inline void RunSpecifiedBenchmarks() {
|
|||||||
|
|
||||||
int iter_cnt = FLAGS_benchmark_iters;
|
int iter_cnt = FLAGS_benchmark_iters;
|
||||||
puts("Benchmark\tTime(ns)\tIterations");
|
puts("Benchmark\tTime(ns)\tIterations");
|
||||||
for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
|
for (auto& iter : g_benchlist) {
|
||||||
iter != g_benchlist.end();
|
|
||||||
++iter) {
|
|
||||||
clock_t start = clock();
|
clock_t start = clock();
|
||||||
iter->second(iter_cnt);
|
iter.second(iter_cnt);
|
||||||
double elapsed_ns = (static_cast<double>(clock()) - start) /
|
double elapsed_ns = (static_cast<double>(clock()) - start) /
|
||||||
CLOCKS_PER_SEC * 1000 * 1000 * 1000;
|
CLOCKS_PER_SEC * 1000 * 1000 * 1000;
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wformat="
|
#pragma GCC diagnostic ignored "-Wformat="
|
||||||
#endif
|
#endif
|
||||||
printf("%s\t%8.2lf\t%10d\n",
|
printf("%s\t%8.2lf\t%10d\n", iter.first.c_str(), elapsed_ns / iter_cnt,
|
||||||
iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt);
|
iter_cnt);
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
@ -296,10 +295,10 @@ static inline void RunSpecifiedBenchmarks() {
|
|||||||
|
|
||||||
class CapturedStream {
|
class CapturedStream {
|
||||||
public:
|
public:
|
||||||
CapturedStream(int fd, const string & filename) :
|
CapturedStream(int fd, string filename)
|
||||||
fd_(fd),
|
: fd_(fd),
|
||||||
uncaptured_fd_(-1),
|
|
||||||
filename_(filename) {
|
filename_(std::move(filename)) {
|
||||||
Capture();
|
Capture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +322,7 @@ class CapturedStream {
|
|||||||
CHECK(cap_fd != -1);
|
CHECK(cap_fd != -1);
|
||||||
|
|
||||||
// Send stdout/stderr to this file
|
// Send stdout/stderr to this file
|
||||||
fflush(NULL);
|
fflush(nullptr);
|
||||||
CHECK(dup2(cap_fd, fd_) != -1);
|
CHECK(dup2(cap_fd, fd_) != -1);
|
||||||
CHECK(close(cap_fd) != -1);
|
CHECK(close(cap_fd) != -1);
|
||||||
}
|
}
|
||||||
@ -332,7 +331,7 @@ class CapturedStream {
|
|||||||
void StopCapture() {
|
void StopCapture() {
|
||||||
// Restore original stream
|
// Restore original stream
|
||||||
if (uncaptured_fd_ != -1) {
|
if (uncaptured_fd_ != -1) {
|
||||||
fflush(NULL);
|
fflush(nullptr);
|
||||||
CHECK(dup2(uncaptured_fd_, fd_) != -1);
|
CHECK(dup2(uncaptured_fd_, fd_) != -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,7 +340,7 @@ class CapturedStream {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int fd_; // file descriptor being captured
|
int fd_; // file descriptor being captured
|
||||||
int uncaptured_fd_; // where the stream was originally being sent to
|
int uncaptured_fd_{-1}; // where the stream was originally being sent to
|
||||||
string filename_; // file where stream is being saved
|
string filename_; // file where stream is being saved
|
||||||
};
|
};
|
||||||
static CapturedStream * s_captured_streams[STDERR_FILENO+1];
|
static CapturedStream * s_captured_streams[STDERR_FILENO+1];
|
||||||
@ -350,7 +349,7 @@ static CapturedStream * s_captured_streams[STDERR_FILENO+1];
|
|||||||
// filename - File where output should be stored
|
// filename - File where output should be stored
|
||||||
static inline void CaptureTestOutput(int fd, const string & filename) {
|
static inline void CaptureTestOutput(int fd, const string & filename) {
|
||||||
CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
|
CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
|
||||||
CHECK(s_captured_streams[fd] == NULL);
|
CHECK(s_captured_streams[fd] == nullptr);
|
||||||
s_captured_streams[fd] = new CapturedStream(fd, filename);
|
s_captured_streams[fd] = new CapturedStream(fd, filename);
|
||||||
}
|
}
|
||||||
static inline void CaptureTestStdout() {
|
static inline void CaptureTestStdout() {
|
||||||
@ -403,7 +402,7 @@ static inline string GetCapturedTestOutput(int fd) {
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
delete cap;
|
delete cap;
|
||||||
s_captured_streams[fd] = NULL;
|
s_captured_streams[fd] = nullptr;
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -479,7 +478,7 @@ static inline void StringReplace(string* str,
|
|||||||
|
|
||||||
static inline string Munge(const string& filename) {
|
static inline string Munge(const string& filename) {
|
||||||
FILE* fp = fopen(filename.c_str(), "rb");
|
FILE* fp = fopen(filename.c_str(), "rb");
|
||||||
CHECK(fp != NULL) << filename << ": couldn't open";
|
CHECK(fp != nullptr) << filename << ": couldn't open";
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
string result;
|
string result;
|
||||||
while (fgets(buf, 4095, fp)) {
|
while (fgets(buf, 4095, fp)) {
|
||||||
@ -487,7 +486,7 @@ static inline string Munge(const string& filename) {
|
|||||||
const size_t str_size = 256;
|
const size_t str_size = 256;
|
||||||
char null_str[str_size];
|
char null_str[str_size];
|
||||||
char ptr_str[str_size];
|
char ptr_str[str_size];
|
||||||
snprintf(null_str, str_size, "%p", static_cast<void*>(NULL));
|
snprintf(null_str, str_size, "%p", static_cast<void*>(nullptr));
|
||||||
snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE));
|
snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE));
|
||||||
|
|
||||||
StringReplace(&line, "__NULLP__", null_str);
|
StringReplace(&line, "__NULLP__", null_str);
|
||||||
@ -577,29 +576,20 @@ struct FlagSaver {
|
|||||||
|
|
||||||
class Thread {
|
class Thread {
|
||||||
public:
|
public:
|
||||||
virtual ~Thread() {}
|
virtual ~Thread() = default;
|
||||||
|
|
||||||
void SetJoinable(bool) {}
|
void SetJoinable(bool) {}
|
||||||
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
|
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
|
||||||
void Start() {
|
void Start() {
|
||||||
handle_ = CreateThread(NULL,
|
handle_ = CreateThread(nullptr, 0, &Thread::InvokeThreadW, this, 0, &th_);
|
||||||
0,
|
|
||||||
&Thread::InvokeThreadW,
|
|
||||||
this,
|
|
||||||
0,
|
|
||||||
&th_);
|
|
||||||
CHECK(handle_) << "CreateThread";
|
CHECK(handle_) << "CreateThread";
|
||||||
}
|
}
|
||||||
void Join() {
|
void Join() {
|
||||||
WaitForSingleObject(handle_, INFINITE);
|
WaitForSingleObject(handle_, INFINITE);
|
||||||
}
|
}
|
||||||
#elif defined(HAVE_PTHREAD)
|
#elif defined(HAVE_PTHREAD)
|
||||||
void Start() {
|
void Start() { pthread_create(&th_, nullptr, &Thread::InvokeThread, this); }
|
||||||
pthread_create(&th_, NULL, &Thread::InvokeThread, this);
|
void Join() { pthread_join(th_, nullptr); }
|
||||||
}
|
|
||||||
void Join() {
|
|
||||||
pthread_join(th_, NULL);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
# error No thread implementation.
|
# error No thread implementation.
|
||||||
#endif
|
#endif
|
||||||
@ -610,7 +600,7 @@ class Thread {
|
|||||||
private:
|
private:
|
||||||
static void* InvokeThread(void* self) {
|
static void* InvokeThread(void* self) {
|
||||||
(static_cast<Thread*>(self))->Run();
|
(static_cast<Thread*>(self))->Run();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
|
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
|
||||||
@ -629,7 +619,7 @@ static inline void SleepForMilliseconds(unsigned t) {
|
|||||||
#ifndef GLOG_OS_WINDOWS
|
#ifndef GLOG_OS_WINDOWS
|
||||||
# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
|
# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
|
||||||
const struct timespec req = {0, t * 1000 * 1000};
|
const struct timespec req = {0, t * 1000 * 1000};
|
||||||
nanosleep(&req, NULL);
|
nanosleep(&req, nullptr);
|
||||||
# else
|
# else
|
||||||
usleep(t * 1000);
|
usleep(t * 1000);
|
||||||
# endif
|
# endif
|
||||||
@ -640,7 +630,7 @@ static inline void SleepForMilliseconds(unsigned t) {
|
|||||||
|
|
||||||
// Add hook for operator new to ensure there are no memory allocation.
|
// Add hook for operator new to ensure there are no memory allocation.
|
||||||
|
|
||||||
void (*g_new_hook)() = NULL;
|
void (*g_new_hook)() = nullptr;
|
||||||
|
|
||||||
_END_GOOGLE_NAMESPACE_
|
_END_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
@ -655,18 +645,10 @@ void* operator new[](size_t size) GOOGLE_GLOG_THROW_BAD_ALLOC {
|
|||||||
return ::operator new(size);
|
return ::operator new(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p) throw() {
|
void operator delete(void* p) noexcept { free(p); }
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void* p, size_t) throw() {
|
void operator delete(void* p, size_t) noexcept { ::operator delete(p); }
|
||||||
::operator delete(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void* p) throw() {
|
void operator delete[](void* p) noexcept { ::operator delete(p); }
|
||||||
::operator delete(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void* p, size_t) throw() {
|
void operator delete[](void* p, size_t) noexcept { ::operator delete(p); }
|
||||||
::operator delete(p);
|
|
||||||
}
|
|
||||||
|
|||||||
345
src/logging.cc
345
src/logging.cc
@ -110,7 +110,7 @@ static bool BoolFromEnv(const char *varname, bool defval) {
|
|||||||
if (!valstr) {
|
if (!valstr) {
|
||||||
return defval;
|
return defval;
|
||||||
}
|
}
|
||||||
return memchr("tTyY1\0", valstr[0], 6) != NULL;
|
return memchr("tTyY1\0", valstr[0], 6) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOG_DEFINE_bool(timestamp_in_logfile_name,
|
GLOG_DEFINE_bool(timestamp_in_logfile_name,
|
||||||
@ -175,11 +175,11 @@ GLOG_DEFINE_string(logmailer, "",
|
|||||||
static const char* DefaultLogDir() {
|
static const char* DefaultLogDir() {
|
||||||
const char* env;
|
const char* env;
|
||||||
env = getenv("GOOGLE_LOG_DIR");
|
env = getenv("GOOGLE_LOG_DIR");
|
||||||
if (env != NULL && env[0] != '\0') {
|
if (env != nullptr && env[0] != '\0') {
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
env = getenv("TEST_TMPDIR");
|
env = getenv("TEST_TMPDIR");
|
||||||
if (env != NULL && env[0] != '\0') {
|
if (env != nullptr && env[0] != '\0') {
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@ -207,7 +207,7 @@ GLOG_DEFINE_bool(log_utc_time, false,
|
|||||||
"Use UTC time for logging.");
|
"Use UTC time for logging.");
|
||||||
|
|
||||||
// TODO(hamaji): consider windows
|
// TODO(hamaji): consider windows
|
||||||
#define PATH_SEPARATOR '/'
|
enum { PATH_SEPARATOR = '/' };
|
||||||
|
|
||||||
#ifndef HAVE_PREAD
|
#ifndef HAVE_PREAD
|
||||||
#if defined(GLOG_OS_WINDOWS)
|
#if defined(GLOG_OS_WINDOWS)
|
||||||
@ -277,7 +277,7 @@ static bool TerminalSupportsColor() {
|
|||||||
#else
|
#else
|
||||||
// On non-Windows platforms, we rely on the TERM variable.
|
// On non-Windows platforms, we rely on the TERM variable.
|
||||||
const char* const term = getenv("TERM");
|
const char* const term = getenv("TERM");
|
||||||
if (term != NULL && term[0] != '\0') {
|
if (term != nullptr && term[0] != '\0') {
|
||||||
term_supports_color =
|
term_supports_color =
|
||||||
!strcmp(term, "xterm") ||
|
!strcmp(term, "xterm") ||
|
||||||
!strcmp(term, "xterm-color") ||
|
!strcmp(term, "xterm-color") ||
|
||||||
@ -346,7 +346,7 @@ static const char* GetAnsiColorCode(GLogColor color) {
|
|||||||
case COLOR_YELLOW: return "3";
|
case COLOR_YELLOW: return "3";
|
||||||
case COLOR_DEFAULT: return "";
|
case COLOR_DEFAULT: return "";
|
||||||
};
|
};
|
||||||
return NULL; // stop warning about return type.
|
return nullptr; // stop warning about return type.
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GLOG_OS_WINDOWS
|
#endif // GLOG_OS_WINDOWS
|
||||||
@ -373,9 +373,10 @@ struct LogMessage::LogMessageData {
|
|||||||
int line_; // line number where logging call is.
|
int line_; // line number where logging call is.
|
||||||
void (LogMessage::*send_method_)(); // Call this in destructor to send
|
void (LogMessage::*send_method_)(); // Call this in destructor to send
|
||||||
union { // At most one of these is used: union to keep the size low.
|
union { // At most one of these is used: union to keep the size low.
|
||||||
LogSink* sink_; // NULL or sink to send message to
|
LogSink* sink_; // nullptr or sink to send message to
|
||||||
std::vector<std::string>* outvec_; // NULL or vector to push message onto
|
std::vector<std::string>*
|
||||||
std::string* message_; // NULL or string to write message into
|
outvec_; // nullptr or vector to push message onto
|
||||||
|
std::string* message_; // nullptr or string to write message into
|
||||||
};
|
};
|
||||||
size_t num_prefix_chars_; // # of chars of prefix in this message
|
size_t num_prefix_chars_; // # of chars of prefix in this message
|
||||||
size_t num_chars_to_log_; // # of chars of msg to send to log
|
size_t num_chars_to_log_; // # of chars of msg to send to log
|
||||||
@ -386,8 +387,8 @@ struct LogMessage::LogMessageData {
|
|||||||
bool first_fatal_; // true => this was first fatal msg
|
bool first_fatal_; // true => this was first fatal msg
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogMessageData(const LogMessageData&);
|
LogMessageData(const LogMessageData&) = delete;
|
||||||
void operator=(const LogMessageData&);
|
void operator=(const LogMessageData&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A mutex that allows only one thread to log at a time, to keep things from
|
// A mutex that allows only one thread to log at a time, to keep things from
|
||||||
@ -417,14 +418,13 @@ const char* GetLogSeverityName(LogSeverity severity) {
|
|||||||
static bool SendEmailInternal(const char*dest, const char *subject,
|
static bool SendEmailInternal(const char*dest, const char *subject,
|
||||||
const char*body, bool use_logging);
|
const char*body, bool use_logging);
|
||||||
|
|
||||||
base::Logger::~Logger() {
|
base::Logger::~Logger() = default;
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Optional user-configured callback to print custom prefixes.
|
// Optional user-configured callback to print custom prefixes.
|
||||||
CustomPrefixCallback custom_prefix_callback = NULL;
|
CustomPrefixCallback custom_prefix_callback = nullptr;
|
||||||
// User-provided data to pass to the callback:
|
// User-provided data to pass to the callback:
|
||||||
void* custom_prefix_callback_data = NULL;
|
void* custom_prefix_callback_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -433,12 +433,11 @@ namespace {
|
|||||||
class LogFileObject : public base::Logger {
|
class LogFileObject : public base::Logger {
|
||||||
public:
|
public:
|
||||||
LogFileObject(LogSeverity severity, const char* base_filename);
|
LogFileObject(LogSeverity severity, const char* base_filename);
|
||||||
~LogFileObject();
|
~LogFileObject() override;
|
||||||
|
|
||||||
virtual void Write(bool force_flush, // Should we force a flush here?
|
void Write(bool force_flush, // Should we force a flush here?
|
||||||
time_t timestamp, // Timestamp for this entry
|
time_t timestamp, // Timestamp for this entry
|
||||||
const char* message,
|
const char* message, size_t message_len) override;
|
||||||
size_t message_len);
|
|
||||||
|
|
||||||
// Configuration options
|
// Configuration options
|
||||||
void SetBasename(const char* basename);
|
void SetBasename(const char* basename);
|
||||||
@ -446,11 +445,11 @@ class LogFileObject : public base::Logger {
|
|||||||
void SetSymlinkBasename(const char* symlink_basename);
|
void SetSymlinkBasename(const char* symlink_basename);
|
||||||
|
|
||||||
// Normal flushing routine
|
// Normal flushing routine
|
||||||
virtual void Flush();
|
void Flush() override;
|
||||||
|
|
||||||
// It is the actual file length for the system loggers,
|
// It is the actual file length for the system loggers,
|
||||||
// i.e., INFO, ERROR, etc.
|
// i.e., INFO, ERROR, etc.
|
||||||
virtual uint32 LogSize() {
|
uint32 LogSize() override {
|
||||||
MutexLock l(&lock_);
|
MutexLock l(&lock_);
|
||||||
return file_length_;
|
return file_length_;
|
||||||
}
|
}
|
||||||
@ -468,13 +467,13 @@ class LogFileObject : public base::Logger {
|
|||||||
string base_filename_;
|
string base_filename_;
|
||||||
string symlink_basename_;
|
string symlink_basename_;
|
||||||
string filename_extension_; // option users can specify (eg to add port#)
|
string filename_extension_; // option users can specify (eg to add port#)
|
||||||
FILE* file_;
|
FILE* file_{nullptr};
|
||||||
LogSeverity severity_;
|
LogSeverity severity_;
|
||||||
uint32 bytes_since_flush_;
|
uint32 bytes_since_flush_{0};
|
||||||
uint32 dropped_mem_length_;
|
uint32 dropped_mem_length_{0};
|
||||||
uint32 file_length_;
|
uint32 file_length_{0};
|
||||||
unsigned int rollover_attempt_;
|
unsigned int rollover_attempt_;
|
||||||
int64 next_flush_time_; // cycle count at which to flush log
|
int64 next_flush_time_{0}; // cycle count at which to flush log
|
||||||
WallTime start_time_;
|
WallTime start_time_;
|
||||||
|
|
||||||
// Actually create a logfile using the value of base_filename_ and the
|
// Actually create a logfile using the value of base_filename_ and the
|
||||||
@ -512,9 +511,9 @@ class LogCleaner {
|
|||||||
|
|
||||||
bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const;
|
bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const;
|
||||||
|
|
||||||
bool enabled_;
|
bool enabled_{false};
|
||||||
unsigned int overdue_days_;
|
unsigned int overdue_days_{7};
|
||||||
int64 next_cleanup_time_; // cycle count at which to clean overdue log
|
int64 next_cleanup_time_{0}; // cycle count at which to clean overdue log
|
||||||
};
|
};
|
||||||
|
|
||||||
LogCleaner log_cleaner;
|
LogCleaner log_cleaner;
|
||||||
@ -613,8 +612,8 @@ class LogDestination {
|
|||||||
static Mutex sink_mutex_;
|
static Mutex sink_mutex_;
|
||||||
|
|
||||||
// Disallow
|
// Disallow
|
||||||
LogDestination(const LogDestination&);
|
LogDestination(const LogDestination&) = delete;
|
||||||
LogDestination& operator=(const LogDestination&);
|
LogDestination& operator=(const LogDestination&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Errors do not get logged to email by default.
|
// Errors do not get logged to email by default.
|
||||||
@ -623,7 +622,7 @@ LogSeverity LogDestination::email_logging_severity_ = 99999;
|
|||||||
string LogDestination::addresses_;
|
string LogDestination::addresses_;
|
||||||
string LogDestination::hostname_;
|
string LogDestination::hostname_;
|
||||||
|
|
||||||
vector<LogSink*>* LogDestination::sinks_ = NULL;
|
vector<LogSink*>* LogDestination::sinks_ = nullptr;
|
||||||
Mutex LogDestination::sink_mutex_;
|
Mutex LogDestination::sink_mutex_;
|
||||||
bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
|
bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
|
||||||
|
|
||||||
@ -666,7 +665,7 @@ inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
|
|||||||
// about it
|
// about it
|
||||||
for (int i = min_severity; i < NUM_SEVERITIES; i++) {
|
for (int i = min_severity; i < NUM_SEVERITIES; i++) {
|
||||||
LogDestination* log = log_destinations_[i];
|
LogDestination* log = log_destinations_[i];
|
||||||
if (log != NULL) {
|
if (log != nullptr) {
|
||||||
// Flush the base fileobject_ logger directly instead of going
|
// Flush the base fileobject_ logger directly instead of going
|
||||||
// through any wrappers to reduce chance of deadlock.
|
// through any wrappers to reduce chance of deadlock.
|
||||||
log->fileobject_.FlushUnlocked();
|
log->fileobject_.FlushUnlocked();
|
||||||
@ -680,7 +679,7 @@ inline void LogDestination::FlushLogFiles(int min_severity) {
|
|||||||
MutexLock l(&log_mutex);
|
MutexLock l(&log_mutex);
|
||||||
for (int i = min_severity; i < NUM_SEVERITIES; i++) {
|
for (int i = min_severity; i < NUM_SEVERITIES; i++) {
|
||||||
LogDestination* log = log_destination(i);
|
LogDestination* log = log_destination(i);
|
||||||
if (log != NULL) {
|
if (log != nullptr) {
|
||||||
log->logger_->Flush();
|
log->logger_->Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -921,7 +920,7 @@ inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
|
|||||||
const bool send_to_sink =
|
const bool send_to_sink =
|
||||||
(data->send_method_ == &LogMessage::SendToSink) ||
|
(data->send_method_ == &LogMessage::SendToSink) ||
|
||||||
(data->send_method_ == &LogMessage::SendToSinkAndLog);
|
(data->send_method_ == &LogMessage::SendToSinkAndLog);
|
||||||
if (send_to_sink && data->sink_ != NULL) {
|
if (send_to_sink && data->sink_ != nullptr) {
|
||||||
data->sink_->WaitTillSent();
|
data->sink_->WaitTillSent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -931,19 +930,19 @@ LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES];
|
|||||||
inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
|
inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
|
||||||
assert(severity >=0 && severity < NUM_SEVERITIES);
|
assert(severity >=0 && severity < NUM_SEVERITIES);
|
||||||
if (!log_destinations_[severity]) {
|
if (!log_destinations_[severity]) {
|
||||||
log_destinations_[severity] = new LogDestination(severity, NULL);
|
log_destinations_[severity] = new LogDestination(severity, nullptr);
|
||||||
}
|
}
|
||||||
return log_destinations_[severity];
|
return log_destinations_[severity];
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogDestination::DeleteLogDestinations() {
|
void LogDestination::DeleteLogDestinations() {
|
||||||
for (int severity = 0; severity < NUM_SEVERITIES; ++severity) {
|
for (auto& log_destination : log_destinations_) {
|
||||||
delete log_destinations_[severity];
|
delete log_destination;
|
||||||
log_destinations_[severity] = NULL;
|
log_destination = nullptr;
|
||||||
}
|
}
|
||||||
MutexLock l(&sink_mutex_);
|
MutexLock l(&sink_mutex_);
|
||||||
delete sinks_;
|
delete sinks_;
|
||||||
sinks_ = NULL;
|
sinks_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -976,30 +975,26 @@ string PrettyDuration(int secs) {
|
|||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogFileObject::LogFileObject(LogSeverity severity, const char* base_filename)
|
||||||
|
: base_filename_selected_(base_filename != nullptr),
|
||||||
|
base_filename_((base_filename != nullptr) ? base_filename : ""),
|
||||||
|
symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
|
||||||
|
filename_extension_(),
|
||||||
|
|
||||||
LogFileObject::LogFileObject(LogSeverity severity,
|
severity_(severity),
|
||||||
const char* base_filename)
|
|
||||||
: base_filename_selected_(base_filename != NULL),
|
rollover_attempt_(kRolloverAttemptFrequency - 1),
|
||||||
base_filename_((base_filename != NULL) ? base_filename : ""),
|
|
||||||
symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
|
start_time_(WallTime_Now()) {
|
||||||
filename_extension_(),
|
|
||||||
file_(NULL),
|
|
||||||
severity_(severity),
|
|
||||||
bytes_since_flush_(0),
|
|
||||||
dropped_mem_length_(0),
|
|
||||||
file_length_(0),
|
|
||||||
rollover_attempt_(kRolloverAttemptFrequency-1),
|
|
||||||
next_flush_time_(0),
|
|
||||||
start_time_(WallTime_Now()) {
|
|
||||||
assert(severity >= 0);
|
assert(severity >= 0);
|
||||||
assert(severity < NUM_SEVERITIES);
|
assert(severity < NUM_SEVERITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogFileObject::~LogFileObject() {
|
LogFileObject::~LogFileObject() {
|
||||||
MutexLock l(&lock_);
|
MutexLock l(&lock_);
|
||||||
if (file_ != NULL) {
|
if (file_ != nullptr) {
|
||||||
fclose(file_);
|
fclose(file_);
|
||||||
file_ = NULL;
|
file_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,9 +1003,9 @@ void LogFileObject::SetBasename(const char* basename) {
|
|||||||
base_filename_selected_ = true;
|
base_filename_selected_ = true;
|
||||||
if (base_filename_ != basename) {
|
if (base_filename_ != basename) {
|
||||||
// Get rid of old log file since we are changing names
|
// Get rid of old log file since we are changing names
|
||||||
if (file_ != NULL) {
|
if (file_ != nullptr) {
|
||||||
fclose(file_);
|
fclose(file_);
|
||||||
file_ = NULL;
|
file_ = nullptr;
|
||||||
rollover_attempt_ = kRolloverAttemptFrequency-1;
|
rollover_attempt_ = kRolloverAttemptFrequency-1;
|
||||||
}
|
}
|
||||||
base_filename_ = basename;
|
base_filename_ = basename;
|
||||||
@ -1021,9 +1016,9 @@ void LogFileObject::SetExtension(const char* ext) {
|
|||||||
MutexLock l(&lock_);
|
MutexLock l(&lock_);
|
||||||
if (filename_extension_ != ext) {
|
if (filename_extension_ != ext) {
|
||||||
// Get rid of old log file since we are changing names
|
// Get rid of old log file since we are changing names
|
||||||
if (file_ != NULL) {
|
if (file_ != nullptr) {
|
||||||
fclose(file_);
|
fclose(file_);
|
||||||
file_ = NULL;
|
file_ = nullptr;
|
||||||
rollover_attempt_ = kRolloverAttemptFrequency-1;
|
rollover_attempt_ = kRolloverAttemptFrequency-1;
|
||||||
}
|
}
|
||||||
filename_extension_ = ext;
|
filename_extension_ = ext;
|
||||||
@ -1041,7 +1036,7 @@ void LogFileObject::Flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LogFileObject::FlushUnlocked(){
|
void LogFileObject::FlushUnlocked(){
|
||||||
if (file_ != NULL) {
|
if (file_ != nullptr) {
|
||||||
fflush(file_);
|
fflush(file_);
|
||||||
bytes_since_flush_ = 0;
|
bytes_since_flush_ = 0;
|
||||||
}
|
}
|
||||||
@ -1076,9 +1071,10 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
|
|||||||
// locks are released on unlock or close() automatically, only after log is
|
// locks are released on unlock or close() automatically, only after log is
|
||||||
// released.
|
// released.
|
||||||
// This will work after a fork as it is not inherited (not stored in the fd).
|
// This will work after a fork as it is not inherited (not stored in the fd).
|
||||||
// Lock will not be lost because the file is opened with exclusive lock (write)
|
// Lock will not be lost because the file is opened with exclusive lock
|
||||||
// and we will never read from it inside the process.
|
// (write) and we will never read from it inside the process.
|
||||||
// TODO windows implementation of this (as flock is not available on mingw).
|
// TODO: windows implementation of this (as flock is not available on
|
||||||
|
// mingw).
|
||||||
static struct flock w_lock;
|
static struct flock w_lock;
|
||||||
|
|
||||||
w_lock.l_type = F_WRLCK;
|
w_lock.l_type = F_WRLCK;
|
||||||
@ -1095,9 +1091,9 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
|
|||||||
|
|
||||||
//fdopen in append mode so if the file exists it will fseek to the end
|
//fdopen in append mode so if the file exists it will fseek to the end
|
||||||
file_ = fdopen(fd, "a"); // Make a FILE*.
|
file_ = fdopen(fd, "a"); // Make a FILE*.
|
||||||
if (file_ == NULL) { // Man, we're screwed!
|
if (file_ == nullptr) { // Man, we're screwed!
|
||||||
close(fd);
|
close(fd);
|
||||||
if (FLAGS_timestamp_in_logfile_name) {
|
if (FLAGS_timestamp_in_logfile_name) {
|
||||||
unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it.
|
unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it.
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1164,14 +1160,14 @@ void LogFileObject::Write(bool force_flush,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) {
|
if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) {
|
||||||
if (file_ != NULL) fclose(file_);
|
if (file_ != nullptr) fclose(file_);
|
||||||
file_ = NULL;
|
file_ = nullptr;
|
||||||
file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
|
file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
|
||||||
rollover_attempt_ = kRolloverAttemptFrequency - 1;
|
rollover_attempt_ = kRolloverAttemptFrequency - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's no destination file, make one before outputting
|
// If there's no destination file, make one before outputting
|
||||||
if (file_ == NULL) {
|
if (file_ == nullptr) {
|
||||||
// Try to rollover the log file every 32 log messages. The only time
|
// Try to rollover the log file every 32 log messages. The only time
|
||||||
// this could matter would be when we have trouble creating the log
|
// this could matter would be when we have trouble creating the log
|
||||||
// file. If that happens, we'll lose lots of log messages, of course!
|
// file. If that happens, we'll lose lots of log messages, of course!
|
||||||
@ -1239,10 +1235,8 @@ void LogFileObject::Write(bool force_flush,
|
|||||||
// Go through the list of dirs, and try to create the log file in each
|
// Go through the list of dirs, and try to create the log file in each
|
||||||
// until we succeed or run out of options
|
// until we succeed or run out of options
|
||||||
bool success = false;
|
bool success = false;
|
||||||
for (vector<string>::const_iterator dir = log_dirs.begin();
|
for (const auto& log_dir : log_dirs) {
|
||||||
dir != log_dirs.end();
|
base_filename_ = log_dir + "/" + stripped_filename;
|
||||||
++dir) {
|
|
||||||
base_filename_ = *dir + "/" + stripped_filename;
|
|
||||||
if ( CreateLogfile(time_pid_string) ) {
|
if ( CreateLogfile(time_pid_string) ) {
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
@ -1353,7 +1347,7 @@ void LogFileObject::Write(bool force_flush,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogCleaner::LogCleaner() : enabled_(false), overdue_days_(7), next_cleanup_time_(0) {}
|
LogCleaner::LogCleaner() = default;
|
||||||
|
|
||||||
void LogCleaner::Enable(unsigned int overdue_days) {
|
void LogCleaner::Enable(unsigned int overdue_days) {
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
@ -1393,17 +1387,15 @@ void LogCleaner::Run(bool base_filename_selected,
|
|||||||
string dir = base_filename.substr(0, pos + 1);
|
string dir = base_filename.substr(0, pos + 1);
|
||||||
dirs.push_back(dir);
|
dirs.push_back(dir);
|
||||||
} else {
|
} else {
|
||||||
dirs.push_back(".");
|
dirs.emplace_back(".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < dirs.size(); i++) {
|
for (auto& dir : dirs) {
|
||||||
vector<string> logs = GetOverdueLogNames(dirs[i],
|
vector<string> logs = GetOverdueLogNames(dir, overdue_days_, base_filename,
|
||||||
overdue_days_,
|
|
||||||
base_filename,
|
|
||||||
filename_extension);
|
filename_extension);
|
||||||
for (size_t j = 0; j < logs.size(); j++) {
|
for (auto& log : logs) {
|
||||||
static_cast<void>(unlink(logs[j].c_str()));
|
static_cast<void>(unlink(log.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1457,9 +1449,7 @@ bool LogCleaner::IsLogFromCurrentProject(const string& filepath,
|
|||||||
possible_dir_delim + sizeof(possible_dir_delim);
|
possible_dir_delim + sizeof(possible_dir_delim);
|
||||||
|
|
||||||
size_t real_filepath_size = filepath.size();
|
size_t real_filepath_size = filepath.size();
|
||||||
for (size_t i = 0; i < base_filename.size(); ++i) {
|
for (char c : base_filename) {
|
||||||
const char& c = base_filename[i];
|
|
||||||
|
|
||||||
if (cleaned_base_filename.empty()) {
|
if (cleaned_base_filename.empty()) {
|
||||||
cleaned_base_filename += c;
|
cleaned_base_filename += c;
|
||||||
} else if (std::find(possible_dir_delim, dir_delim_end, c) ==
|
} else if (std::find(possible_dir_delim, dir_delim_end, c) ==
|
||||||
@ -1532,7 +1522,7 @@ bool LogCleaner::IsLogLastModifiedOver(const string& filepath,
|
|||||||
if (stat(filepath.c_str(), &file_stat) == 0) {
|
if (stat(filepath.c_str(), &file_stat) == 0) {
|
||||||
const time_t seconds_in_a_day = 60 * 60 * 24;
|
const time_t seconds_in_a_day = 60 * 60 * 24;
|
||||||
time_t last_modified_time = file_stat.st_mtime;
|
time_t last_modified_time = file_stat.st_mtime;
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(nullptr);
|
||||||
return difftime(current_time, last_modified_time) > days * seconds_in_a_day;
|
return difftime(current_time, last_modified_time) > days * seconds_in_a_day;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,16 +1548,11 @@ static LogMessage::LogMessageData fatal_msg_data_shared;
|
|||||||
// Static thread-local log data space to use, because typically at most one
|
// Static thread-local log data space to use, because typically at most one
|
||||||
// LogMessageData object exists (in this case glog makes zero heap memory
|
// LogMessageData object exists (in this case glog makes zero heap memory
|
||||||
// allocations).
|
// allocations).
|
||||||
static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
|
static thread_local bool thread_data_available = true;
|
||||||
|
|
||||||
#if defined(HAVE_ALIGNED_STORAGE) && __cplusplus >= 201103L
|
static thread_local std::aligned_storage<
|
||||||
static GLOG_THREAD_LOCAL_STORAGE
|
sizeof(LogMessage::LogMessageData),
|
||||||
std::aligned_storage<sizeof(LogMessage::LogMessageData),
|
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
|
||||||
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
|
|
||||||
#else
|
|
||||||
static GLOG_THREAD_LOCAL_STORAGE
|
|
||||||
char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
|
|
||||||
#endif // HAVE_ALIGNED_STORAGE
|
|
||||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||||
|
|
||||||
LogMessage::LogMessageData::LogMessageData()
|
LogMessage::LogMessageData::LogMessageData()
|
||||||
@ -1576,70 +1561,59 @@ LogMessage::LogMessageData::LogMessageData()
|
|||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||||
int64 ctr, void (LogMessage::*send_method)())
|
int64 ctr, void (LogMessage::*send_method)())
|
||||||
: allocated_(NULL) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, severity, send_method);
|
Init(file, line, severity, send_method);
|
||||||
data_->stream_.set_ctr(ctr);
|
data_->stream_.set_ctr(ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line,
|
LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
|
||||||
const CheckOpString& result)
|
: allocated_(nullptr) {
|
||||||
: allocated_(NULL) {
|
|
||||||
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
|
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
|
||||||
stream() << "Check failed: " << (*result.str_) << " ";
|
stream() << "Check failed: " << (*result.str_) << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line)
|
LogMessage::LogMessage(const char* file, int line) : allocated_(nullptr) {
|
||||||
: allocated_(NULL) {
|
|
||||||
Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
|
Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
|
||||||
: allocated_(NULL) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, severity, &LogMessage::SendToLog);
|
Init(file, line, severity, &LogMessage::SendToLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||||
LogSink* sink, bool also_send_to_log)
|
LogSink* sink, bool also_send_to_log)
|
||||||
: allocated_(NULL) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
|
Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
|
||||||
&LogMessage::SendToSink);
|
&LogMessage::SendToSink);
|
||||||
data_->sink_ = sink; // override Init()'s setting to NULL
|
data_->sink_ = sink; // override Init()'s setting to nullptr
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||||
vector<string> *outvec)
|
vector<string>* outvec)
|
||||||
: allocated_(NULL) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, severity, &LogMessage::SaveOrSendToLog);
|
Init(file, line, severity, &LogMessage::SaveOrSendToLog);
|
||||||
data_->outvec_ = outvec; // override Init()'s setting to NULL
|
data_->outvec_ = outvec; // override Init()'s setting to nullptr
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||||
string *message)
|
string* message)
|
||||||
: allocated_(NULL) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, severity, &LogMessage::WriteToStringAndLog);
|
Init(file, line, severity, &LogMessage::WriteToStringAndLog);
|
||||||
data_->message_ = message; // override Init()'s setting to NULL
|
data_->message_ = message; // override Init()'s setting to nullptr
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMessage::Init(const char* file,
|
void LogMessage::Init(const char* file,
|
||||||
int line,
|
int line,
|
||||||
LogSeverity severity,
|
LogSeverity severity,
|
||||||
void (LogMessage::*send_method)()) {
|
void (LogMessage::*send_method)()) {
|
||||||
allocated_ = NULL;
|
allocated_ = nullptr;
|
||||||
if (severity != GLOG_FATAL || !exit_on_dfatal) {
|
if (severity != GLOG_FATAL || !exit_on_dfatal) {
|
||||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||||
// No need for locking, because this is thread local.
|
// No need for locking, because this is thread local.
|
||||||
if (thread_data_available) {
|
if (thread_data_available) {
|
||||||
thread_data_available = false;
|
thread_data_available = false;
|
||||||
#ifdef HAVE_ALIGNED_STORAGE
|
|
||||||
data_ = new (&thread_msg_data) LogMessageData;
|
data_ = new (&thread_msg_data) LogMessageData;
|
||||||
#else
|
|
||||||
const uintptr_t kAlign = sizeof(void*) - 1;
|
|
||||||
|
|
||||||
char* align_ptr =
|
|
||||||
reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
|
|
||||||
data_ = new (align_ptr) LogMessageData;
|
|
||||||
assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
allocated_ = new LogMessageData();
|
allocated_ = new LogMessageData();
|
||||||
data_ = allocated_;
|
data_ = allocated_;
|
||||||
@ -1665,10 +1639,10 @@ void LogMessage::Init(const char* file,
|
|||||||
data_->severity_ = severity;
|
data_->severity_ = severity;
|
||||||
data_->line_ = line;
|
data_->line_ = line;
|
||||||
data_->send_method_ = send_method;
|
data_->send_method_ = send_method;
|
||||||
data_->sink_ = NULL;
|
data_->sink_ = nullptr;
|
||||||
data_->outvec_ = NULL;
|
data_->outvec_ = nullptr;
|
||||||
WallTime now = WallTime_Now();
|
WallTime now = WallTime_Now();
|
||||||
time_t timestamp_now = static_cast<time_t>(now);
|
auto timestamp_now = static_cast<time_t>(now);
|
||||||
logmsgtime_ = LogMessageTime(timestamp_now, now);
|
logmsgtime_ = LogMessageTime(timestamp_now, now);
|
||||||
|
|
||||||
data_->num_chars_to_log_ = 0;
|
data_->num_chars_to_log_ = 0;
|
||||||
@ -1682,36 +1656,29 @@ void LogMessage::Init(const char* file,
|
|||||||
// (log level, GMT year, month, date, time, thread_id, file basename, line)
|
// (log level, GMT year, month, date, time, thread_id, file basename, line)
|
||||||
// We exclude the thread_id for the default thread.
|
// We exclude the thread_id for the default thread.
|
||||||
if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
|
if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
|
||||||
std::ios saved_fmt(NULL);
|
std::ios saved_fmt(nullptr);
|
||||||
saved_fmt.copyfmt(stream());
|
saved_fmt.copyfmt(stream());
|
||||||
stream().fill('0');
|
stream().fill('0');
|
||||||
if (custom_prefix_callback == NULL) {
|
if (custom_prefix_callback == nullptr) {
|
||||||
stream() << LogSeverityNames[severity][0];
|
stream() << LogSeverityNames[severity][0];
|
||||||
if (FLAGS_log_year_in_prefix) {
|
if (FLAGS_log_year_in_prefix) {
|
||||||
stream() << setw(4) << 1900 + logmsgtime_.year();
|
stream() << setw(4) << 1900 + logmsgtime_.year();
|
||||||
}
|
|
||||||
stream() << setw(2) << 1 + logmsgtime_.month()
|
|
||||||
<< setw(2) << logmsgtime_.day()
|
|
||||||
<< ' '
|
|
||||||
<< setw(2) << logmsgtime_.hour() << ':'
|
|
||||||
<< setw(2) << logmsgtime_.min() << ':'
|
|
||||||
<< setw(2) << logmsgtime_.sec() << "."
|
|
||||||
<< setw(6) << logmsgtime_.usec()
|
|
||||||
<< ' '
|
|
||||||
<< setfill(' ') << setw(5)
|
|
||||||
<< static_cast<unsigned int>(GetTID()) << setfill('0')
|
|
||||||
<< ' '
|
|
||||||
<< data_->basename_ << ':' << data_->line_ << "] ";
|
|
||||||
} else {
|
|
||||||
custom_prefix_callback(
|
|
||||||
stream(),
|
|
||||||
LogMessageInfo(LogSeverityNames[severity],
|
|
||||||
data_->basename_, data_->line_, GetTID(),
|
|
||||||
logmsgtime_),
|
|
||||||
custom_prefix_callback_data
|
|
||||||
);
|
|
||||||
stream() << " ";
|
|
||||||
}
|
}
|
||||||
|
stream() << setw(2) << 1 + logmsgtime_.month() << setw(2)
|
||||||
|
<< logmsgtime_.day() << ' ' << setw(2) << logmsgtime_.hour()
|
||||||
|
<< ':' << setw(2) << logmsgtime_.min() << ':' << setw(2)
|
||||||
|
<< logmsgtime_.sec() << "." << setw(6) << logmsgtime_.usec()
|
||||||
|
<< ' ' << setfill(' ') << setw(5)
|
||||||
|
<< static_cast<unsigned int>(GetTID()) << setfill('0') << ' '
|
||||||
|
<< data_->basename_ << ':' << data_->line_ << "] ";
|
||||||
|
} else {
|
||||||
|
custom_prefix_callback(
|
||||||
|
stream(),
|
||||||
|
LogMessageInfo(LogSeverityNames[severity], data_->basename_,
|
||||||
|
data_->line_, GetTID(), logmsgtime_),
|
||||||
|
custom_prefix_callback_data);
|
||||||
|
stream() << " ";
|
||||||
|
}
|
||||||
stream().copyfmt(saved_fmt);
|
stream().copyfmt(saved_fmt);
|
||||||
}
|
}
|
||||||
data_->num_prefix_chars_ = data_->stream_.pcount();
|
data_->num_prefix_chars_ = data_->stream_.pcount();
|
||||||
@ -1905,9 +1872,9 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
|
if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
|
||||||
for (int i = 0; i < NUM_SEVERITIES; ++i) {
|
for (auto& log_destination : LogDestination::log_destinations_) {
|
||||||
if (LogDestination::log_destinations_[i]) {
|
if (log_destination) {
|
||||||
LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
|
log_destination->logger_->Write(true, 0, "", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1961,7 +1928,7 @@ void LogMessage::Fail() {
|
|||||||
|
|
||||||
// L >= log_mutex (callers must hold the log_mutex).
|
// L >= log_mutex (callers must hold the log_mutex).
|
||||||
void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
||||||
if (data_->sink_ != NULL) {
|
if (data_->sink_ != nullptr) {
|
||||||
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
||||||
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
||||||
data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
|
data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
|
||||||
@ -1980,7 +1947,7 @@ void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
|||||||
|
|
||||||
// L >= log_mutex (callers must hold the log_mutex).
|
// L >= log_mutex (callers must hold the log_mutex).
|
||||||
void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
||||||
if (data_->outvec_ != NULL) {
|
if (data_->outvec_ != nullptr) {
|
||||||
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
||||||
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
||||||
// Omit prefix of message and trailing newline when recording in outvec_.
|
// Omit prefix of message and trailing newline when recording in outvec_.
|
||||||
@ -1993,7 +1960,7 @@ void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
||||||
if (data_->message_ != NULL) {
|
if (data_->message_ != nullptr) {
|
||||||
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
|
||||||
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
|
||||||
// Omit prefix of message and trailing newline when writing to message_.
|
// Omit prefix of message and trailing newline when writing to message_.
|
||||||
@ -2018,8 +1985,8 @@ void LogMessage::SendToSyslogAndLog() {
|
|||||||
|
|
||||||
// This array maps Google severity levels to syslog levels
|
// This array maps Google severity levels to syslog levels
|
||||||
const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
|
const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
|
||||||
syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s",
|
syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)],
|
||||||
int(data_->num_chars_to_syslog_),
|
"%.*s", static_cast<int>(data_->num_chars_to_syslog_),
|
||||||
data_->message_text_ + data_->num_prefix_chars_);
|
data_->message_text_ + data_->num_prefix_chars_);
|
||||||
SendToLog();
|
SendToLog();
|
||||||
#else
|
#else
|
||||||
@ -2049,7 +2016,7 @@ ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
|
|||||||
#ifdef DISABLE_RTTI
|
#ifdef DISABLE_RTTI
|
||||||
LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
|
LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
|
||||||
#else
|
#else
|
||||||
LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
|
auto* log = dynamic_cast<LogMessage::LogStream*>(&os);
|
||||||
#endif
|
#endif
|
||||||
CHECK(log && log == log->self())
|
CHECK(log && log == log->self())
|
||||||
<< "You must not use COUNTER with non-glog ostream";
|
<< "You must not use COUNTER with non-glog ostream";
|
||||||
@ -2085,8 +2052,7 @@ void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
|
|||||||
LogDestination::SetLogSymlink(severity, symlink_basename);
|
LogDestination::SetLogSymlink(severity, symlink_basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSink::~LogSink() {
|
LogSink::~LogSink() = default;
|
||||||
}
|
|
||||||
|
|
||||||
void LogSink::send(LogSeverity severity, const char* full_filename,
|
void LogSink::send(LogSeverity severity, const char* full_filename,
|
||||||
const char* base_filename, int line,
|
const char* base_filename, int line,
|
||||||
@ -2268,9 +2234,9 @@ static bool SendEmailInternal(const char*dest, const char *subject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
FILE* pipe = popen(cmd.c_str(), "w");
|
FILE* pipe = popen(cmd.c_str(), "w");
|
||||||
if (pipe != NULL) {
|
if (pipe != nullptr) {
|
||||||
// Add the body if we have one
|
// Add the body if we have one
|
||||||
if (body) {
|
if (body) {
|
||||||
fwrite(body, sizeof(char), strlen(body), pipe);
|
fwrite(body, sizeof(char), strlen(body), pipe);
|
||||||
}
|
}
|
||||||
bool ok = pclose(pipe) != -1;
|
bool ok = pclose(pipe) != -1;
|
||||||
@ -2334,8 +2300,7 @@ static void GetTempDirectories(vector<string>* list) {
|
|||||||
"/tmp",
|
"/tmp",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAYSIZE(candidates); i++) {
|
for (auto d : candidates) {
|
||||||
const char *d = candidates[i];
|
|
||||||
if (!d) continue; // Empty env var
|
if (!d) continue; // Empty env var
|
||||||
|
|
||||||
// Make sure we don't surprise anyone who's expecting a '/'
|
// Make sure we don't surprise anyone who's expecting a '/'
|
||||||
@ -2359,7 +2324,7 @@ static vector<string>* logging_directories_list;
|
|||||||
|
|
||||||
const vector<string>& GetLoggingDirectories() {
|
const vector<string>& GetLoggingDirectories() {
|
||||||
// Not strictly thread-safe but we're called early in InitGoogle().
|
// Not strictly thread-safe but we're called early in InitGoogle().
|
||||||
if (logging_directories_list == NULL) {
|
if (logging_directories_list == nullptr) {
|
||||||
logging_directories_list = new vector<string>;
|
logging_directories_list = new vector<string>;
|
||||||
|
|
||||||
if ( !FLAGS_log_dir.empty() ) {
|
if ( !FLAGS_log_dir.empty() ) {
|
||||||
@ -2384,12 +2349,12 @@ void TestOnly_ClearLoggingDirectoriesList() {
|
|||||||
fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
|
fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
|
||||||
"called from test code.\n");
|
"called from test code.\n");
|
||||||
delete logging_directories_list;
|
delete logging_directories_list;
|
||||||
logging_directories_list = NULL;
|
logging_directories_list = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetExistingTempDirectories(vector<string>* list) {
|
void GetExistingTempDirectories(vector<string>* list) {
|
||||||
GetTempDirectories(list);
|
GetTempDirectories(list);
|
||||||
vector<string>::iterator i_dir = list->begin();
|
auto i_dir = list->begin();
|
||||||
while( i_dir != list->end() ) {
|
while( i_dir != list->end() ) {
|
||||||
// zero arg to access means test for existence; no constant
|
// zero arg to access means test for existence; no constant
|
||||||
// defined on windows
|
// defined on windows
|
||||||
@ -2492,18 +2457,19 @@ void TruncateStdoutStderr() {
|
|||||||
|
|
||||||
|
|
||||||
// Helper functions for string comparisons.
|
// Helper functions for string comparisons.
|
||||||
#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
|
#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
|
||||||
string* Check##func##expected##Impl(const char* s1, const char* s2, \
|
string* Check##func##expected##Impl(const char* s1, const char* s2, \
|
||||||
const char* names) { \
|
const char* names) { \
|
||||||
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
|
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
|
||||||
if (equal == expected) return NULL; \
|
if (equal == expected) \
|
||||||
else { \
|
return nullptr; \
|
||||||
ostringstream ss; \
|
else { \
|
||||||
if (!s1) s1 = ""; \
|
ostringstream ss; \
|
||||||
if (!s2) s2 = ""; \
|
if (!s1) s1 = ""; \
|
||||||
|
if (!s2) s2 = ""; \
|
||||||
ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
|
ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
|
||||||
return new string(ss.str()); \
|
return new string(ss.str()); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
|
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
|
||||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
|
DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
|
||||||
@ -2513,7 +2479,7 @@ DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
|
|||||||
|
|
||||||
int posix_strerror_r(int err, char *buf, size_t len) {
|
int posix_strerror_r(int err, char *buf, size_t len) {
|
||||||
// Sanity check input parameters
|
// Sanity check input parameters
|
||||||
if (buf == NULL || len <= 0) {
|
if (buf == nullptr || len <= 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2632,12 +2598,10 @@ void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L
|
|
||||||
template <>
|
template <>
|
||||||
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
|
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
|
||||||
(*os) << "nullptr";
|
(*os) << "nullptr";
|
||||||
}
|
}
|
||||||
#endif // defined(HAVE_CXX11_NULLPTR_T)
|
|
||||||
|
|
||||||
void InitGoogleLogging(const char* argv0) {
|
void InitGoogleLogging(const char* argv0) {
|
||||||
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
|
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
|
||||||
@ -2655,7 +2619,7 @@ void ShutdownGoogleLogging() {
|
|||||||
glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
|
glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
|
||||||
LogDestination::DeleteLogDestinations();
|
LogDestination::DeleteLogDestinations();
|
||||||
delete logging_directories_list;
|
delete logging_directories_list;
|
||||||
logging_directories_list = NULL;
|
logging_directories_list = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnableLogCleaner(unsigned int overdue_days) {
|
void EnableLogCleaner(unsigned int overdue_days) {
|
||||||
@ -2676,10 +2640,11 @@ LogMessageTime::LogMessageTime(std::tm t) {
|
|||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
||||||
std::tm t;
|
std::tm t;
|
||||||
if (FLAGS_log_utc_time)
|
if (FLAGS_log_utc_time) {
|
||||||
gmtime_r(×tamp, &t);
|
gmtime_r(×tamp, &t);
|
||||||
else
|
} else {
|
||||||
localtime_r(×tamp, &t);
|
localtime_r(×tamp, &t);
|
||||||
|
}
|
||||||
init(t, timestamp, now);
|
init(t, timestamp, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -187,7 +187,7 @@ BENCHMARK(BM_vlog)
|
|||||||
void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) {
|
void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) {
|
||||||
// Assert that `data` contains the expected contents before producing the
|
// Assert that `data` contains the expected contents before producing the
|
||||||
// prefix (otherwise causing the tests to fail):
|
// prefix (otherwise causing the tests to fail):
|
||||||
if (data == NULL || *static_cast<string*>(data) != "good data") {
|
if (data == nullptr || *static_cast<string*>(data) != "good data") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,13 +213,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Make sure stderr is not buffered as stderr seems to be buffered
|
// Make sure stderr is not buffered as stderr seems to be buffered
|
||||||
// on recent windows.
|
// on recent windows.
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, nullptr);
|
||||||
|
|
||||||
// Test some basics before InitGoogleLogging:
|
// Test some basics before InitGoogleLogging:
|
||||||
CaptureTestStderr();
|
CaptureTestStderr();
|
||||||
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
|
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
|
||||||
FLAGS_logtostderr, FLAGS_alsologtostderr);
|
FLAGS_logtostderr, FLAGS_alsologtostderr);
|
||||||
LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors"
|
LogWithLevels(0, 0, false, false); // simulate "before global c-tors"
|
||||||
const string early_stderr = GetCapturedTestStderr();
|
const string early_stderr = GetCapturedTestStderr();
|
||||||
|
|
||||||
EXPECT_FALSE(IsGoogleLoggingInitialized());
|
EXPECT_FALSE(IsGoogleLoggingInitialized());
|
||||||
@ -359,9 +359,7 @@ struct NewHook {
|
|||||||
NewHook() {
|
NewHook() {
|
||||||
g_new_hook = &NoAllocNewHook;
|
g_new_hook = &NoAllocNewHook;
|
||||||
}
|
}
|
||||||
~NewHook() {
|
~NewHook() { g_new_hook = nullptr; }
|
||||||
g_new_hook = NULL;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(DeathNoAllocNewHook, logging) {
|
TEST(DeathNoAllocNewHook, logging) {
|
||||||
@ -373,7 +371,7 @@ TEST(DeathNoAllocNewHook, logging) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestRawLogging() {
|
void TestRawLogging() {
|
||||||
string* foo = new string("foo ");
|
auto* foo = new string("foo ");
|
||||||
string huge_str(50000, 'a');
|
string huge_str(50000, 'a');
|
||||||
|
|
||||||
FlagSaver saver;
|
FlagSaver saver;
|
||||||
@ -388,7 +386,7 @@ void TestRawLogging() {
|
|||||||
RAW_LOG(INFO, "%s", const_s);
|
RAW_LOG(INFO, "%s", const_s);
|
||||||
void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
|
void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
|
||||||
RAW_LOG(INFO, "ptr %p", p);
|
RAW_LOG(INFO, "ptr %p", p);
|
||||||
p = NULL;
|
p = nullptr;
|
||||||
RAW_LOG(INFO, "ptr %p", p);
|
RAW_LOG(INFO, "ptr %p", p);
|
||||||
int j = 1000;
|
int j = 1000;
|
||||||
RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
|
RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
|
||||||
@ -531,7 +529,7 @@ TEST(DeathRawCHECK, logging) {
|
|||||||
|
|
||||||
void TestLogString() {
|
void TestLogString() {
|
||||||
vector<string> errors;
|
vector<string> errors;
|
||||||
vector<string> *no_errors = NULL;
|
vector<string>* no_errors = nullptr;
|
||||||
|
|
||||||
LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
|
LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
|
||||||
LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
|
LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
|
||||||
@ -539,16 +537,17 @@ void TestLogString() {
|
|||||||
|
|
||||||
LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
|
LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
|
||||||
LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
|
LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
|
||||||
LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
|
LOG_STRING(ERROR, nullptr) << "LOG_STRING: "
|
||||||
|
<< "reported error";
|
||||||
|
|
||||||
for (size_t i = 0; i < errors.size(); ++i) {
|
for (auto& error : errors) {
|
||||||
LOG(INFO) << "Captured by LOG_STRING: " << errors[i];
|
LOG(INFO) << "Captured by LOG_STRING: " << error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestLogToString() {
|
void TestLogToString() {
|
||||||
string error;
|
string error;
|
||||||
string* no_error = NULL;
|
string* no_error = nullptr;
|
||||||
|
|
||||||
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
|
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
|
||||||
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
|
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
|
||||||
@ -559,16 +558,17 @@ void TestLogToString() {
|
|||||||
|
|
||||||
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
|
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
|
||||||
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
|
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
|
||||||
LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
|
LOG_TO_STRING(ERROR, nullptr) << "LOG_TO_STRING: "
|
||||||
|
<< "reported error";
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestLogSinkImpl : public LogSink {
|
class TestLogSinkImpl : public LogSink {
|
||||||
public:
|
public:
|
||||||
vector<string> errors;
|
vector<string> errors;
|
||||||
virtual void send(LogSeverity severity, const char* /* full_filename */,
|
void send(LogSeverity severity, const char* /* full_filename */,
|
||||||
const char* base_filename, int line,
|
const char* base_filename, int line,
|
||||||
const LogMessageTime &logmsgtime,
|
const LogMessageTime& logmsgtime, const char* message,
|
||||||
const char* message, size_t message_len) {
|
size_t message_len) override {
|
||||||
errors.push_back(
|
errors.push_back(
|
||||||
ToString(severity, base_filename, line, logmsgtime, message, message_len));
|
ToString(severity, base_filename, line, logmsgtime, message, message_len));
|
||||||
}
|
}
|
||||||
@ -576,7 +576,7 @@ class TestLogSinkImpl : public LogSink {
|
|||||||
|
|
||||||
void TestLogSink() {
|
void TestLogSink() {
|
||||||
TestLogSinkImpl sink;
|
TestLogSinkImpl sink;
|
||||||
LogSink *no_sink = NULL;
|
LogSink* no_sink = nullptr;
|
||||||
|
|
||||||
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
|
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
|
||||||
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
|
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
|
||||||
@ -584,7 +584,8 @@ void TestLogSink() {
|
|||||||
|
|
||||||
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
|
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
|
||||||
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
|
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
|
||||||
LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
|
LOG_TO_SINK(nullptr, ERROR) << "LOG_TO_SINK: "
|
||||||
|
<< "reported error";
|
||||||
|
|
||||||
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
|
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
|
||||||
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
|
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
|
||||||
@ -597,13 +598,13 @@ void TestLogSink() {
|
|||||||
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
|
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
|
||||||
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
|
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
|
||||||
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
|
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
|
||||||
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
|
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(nullptr, ERROR)
|
||||||
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
|
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
|
||||||
|
<< "thrashed error";
|
||||||
|
|
||||||
LOG(INFO) << "Captured by LOG_TO_SINK:";
|
LOG(INFO) << "Captured by LOG_TO_SINK:";
|
||||||
for (size_t i = 0; i < sink.errors.size(); ++i) {
|
for (auto& error : sink.errors) {
|
||||||
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
|
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << error;
|
||||||
<< sink.errors[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +654,7 @@ void TestDCHECK() {
|
|||||||
DCHECK_GT(2, 1);
|
DCHECK_GT(2, 1);
|
||||||
DCHECK_LT(1, 2);
|
DCHECK_LT(1, 2);
|
||||||
|
|
||||||
int64* orig_ptr = new int64;
|
auto* orig_ptr = new int64;
|
||||||
int64* ptr = DCHECK_NOTNULL(orig_ptr);
|
int64* ptr = DCHECK_NOTNULL(orig_ptr);
|
||||||
CHECK_EQ(ptr, orig_ptr);
|
CHECK_EQ(ptr, orig_ptr);
|
||||||
delete orig_ptr;
|
delete orig_ptr;
|
||||||
@ -661,24 +662,24 @@ void TestDCHECK() {
|
|||||||
|
|
||||||
void TestSTREQ() {
|
void TestSTREQ() {
|
||||||
CHECK_STREQ("this", "this");
|
CHECK_STREQ("this", "this");
|
||||||
CHECK_STREQ(NULL, NULL);
|
CHECK_STREQ(nullptr, nullptr);
|
||||||
CHECK_STRCASEEQ("this", "tHiS");
|
CHECK_STRCASEEQ("this", "tHiS");
|
||||||
CHECK_STRCASEEQ(NULL, NULL);
|
CHECK_STRCASEEQ(nullptr, nullptr);
|
||||||
CHECK_STRNE("this", "tHiS");
|
CHECK_STRNE("this", "tHiS");
|
||||||
CHECK_STRNE("this", NULL);
|
CHECK_STRNE("this", nullptr);
|
||||||
CHECK_STRCASENE("this", "that");
|
CHECK_STRCASENE("this", "that");
|
||||||
CHECK_STRCASENE(NULL, "that");
|
CHECK_STRCASENE(nullptr, "that");
|
||||||
CHECK_STREQ((string("a")+"b").c_str(), "ab");
|
CHECK_STREQ((string("a")+"b").c_str(), "ab");
|
||||||
CHECK_STREQ(string("test").c_str(),
|
CHECK_STREQ(string("test").c_str(),
|
||||||
(string("te") + string("st")).c_str());
|
(string("te") + string("st")).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DeathSTREQ, logging) {
|
TEST(DeathSTREQ, logging) {
|
||||||
ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
|
ASSERT_DEATH(CHECK_STREQ(nullptr, "this"), "");
|
||||||
ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
|
ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
|
||||||
ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
|
ASSERT_DEATH(CHECK_STRCASEEQ(nullptr, "siht"), "");
|
||||||
ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
|
ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
|
||||||
ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
|
ASSERT_DEATH(CHECK_STRNE(nullptr, nullptr), "");
|
||||||
ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
|
ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
|
||||||
ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
|
ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
|
||||||
}
|
}
|
||||||
@ -695,7 +696,7 @@ TEST(CheckNOTNULL, Simple) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(DeathCheckNN, Simple) {
|
TEST(DeathCheckNN, Simple) {
|
||||||
ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
|
ASSERT_DEATH(CHECK_NOTNULL(static_cast<void*>(nullptr)), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of file names that match pattern
|
// Get list of file names that match pattern
|
||||||
@ -703,7 +704,7 @@ static void GetFiles(const string& pattern, vector<string>* files) {
|
|||||||
files->clear();
|
files->clear();
|
||||||
#if defined(HAVE_GLOB_H)
|
#if defined(HAVE_GLOB_H)
|
||||||
glob_t g;
|
glob_t g;
|
||||||
const int r = glob(pattern.c_str(), 0, NULL, &g);
|
const int r = glob(pattern.c_str(), 0, nullptr, &g);
|
||||||
CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
|
CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
|
||||||
for (size_t i = 0; i < g.gl_pathc; i++) {
|
for (size_t i = 0; i < g.gl_pathc; i++) {
|
||||||
files->push_back(string(g.gl_pathv[i]));
|
files->push_back(string(g.gl_pathv[i]));
|
||||||
@ -735,8 +736,8 @@ static void GetFiles(const string& pattern, vector<string>* files) {
|
|||||||
static void DeleteFiles(const string& pattern) {
|
static void DeleteFiles(const string& pattern) {
|
||||||
vector<string> files;
|
vector<string> files;
|
||||||
GetFiles(pattern, &files);
|
GetFiles(pattern, &files);
|
||||||
for (size_t i = 0; i < files.size(); i++) {
|
for (auto& file : files) {
|
||||||
CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
|
CHECK(unlink(file.c_str()) == 0) << ": " << strerror(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,13 +748,13 @@ static void CheckFile(const string& name, const string& expected_string, const b
|
|||||||
CHECK_EQ(files.size(), 1UL);
|
CHECK_EQ(files.size(), 1UL);
|
||||||
|
|
||||||
FILE* file = fopen(files[0].c_str(), "r");
|
FILE* file = fopen(files[0].c_str(), "r");
|
||||||
CHECK(file != NULL) << ": could not open " << files[0];
|
CHECK(file != nullptr) << ": could not open " << files[0];
|
||||||
char buf[1000];
|
char buf[1000];
|
||||||
while (fgets(buf, sizeof(buf), file) != NULL) {
|
while (fgets(buf, sizeof(buf), file) != nullptr) {
|
||||||
char* first = strstr(buf, expected_string.c_str());
|
char* first = strstr(buf, expected_string.c_str());
|
||||||
//if first == NULL, not found.
|
// if first == nullptr, not found.
|
||||||
//Terser than if (checkInFileOrNot && first != NULL || !check...
|
// Terser than if (checkInFileOrNot && first != nullptr || !check...
|
||||||
if (checkInFileOrNot != (first == NULL)) {
|
if (checkInFileOrNot != (first == nullptr)) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -824,7 +825,7 @@ static void TestTwoProcessesWrite() {
|
|||||||
ShutdownGoogleLogging(); //for children proc
|
ShutdownGoogleLogging(); //for children proc
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
wait(NULL);
|
wait(nullptr);
|
||||||
}
|
}
|
||||||
FLAGS_timestamp_in_logfile_name=true;
|
FLAGS_timestamp_in_logfile_name=true;
|
||||||
|
|
||||||
@ -871,7 +872,7 @@ static void TestExtension() {
|
|||||||
vector<string> filenames;
|
vector<string> filenames;
|
||||||
GetFiles(dest + "*", &filenames);
|
GetFiles(dest + "*", &filenames);
|
||||||
CHECK_EQ(filenames.size(), 1UL);
|
CHECK_EQ(filenames.size(), 1UL);
|
||||||
CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
|
CHECK(strstr(filenames[0].c_str(), "specialextension") != nullptr);
|
||||||
|
|
||||||
// Release file handle for the destination file to unlock the file in Windows.
|
// Release file handle for the destination file to unlock the file in Windows.
|
||||||
LogToStderr();
|
LogToStderr();
|
||||||
@ -884,18 +885,16 @@ struct MyLogger : public base::Logger {
|
|||||||
explicit MyLogger(bool* set_on_destruction)
|
explicit MyLogger(bool* set_on_destruction)
|
||||||
: set_on_destruction_(set_on_destruction) {}
|
: set_on_destruction_(set_on_destruction) {}
|
||||||
|
|
||||||
~MyLogger() { *set_on_destruction_ = true; }
|
~MyLogger() override { *set_on_destruction_ = true; }
|
||||||
|
|
||||||
virtual void Write(bool /* should_flush */,
|
void Write(bool /* should_flush */, time_t /* timestamp */,
|
||||||
time_t /* timestamp */,
|
const char* message, size_t length) override {
|
||||||
const char* message,
|
|
||||||
size_t length) {
|
|
||||||
data.append(message, length);
|
data.append(message, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Flush() { }
|
void Flush() override {}
|
||||||
|
|
||||||
virtual uint32 LogSize() { return data.length(); }
|
uint32 LogSize() override { return data.length(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool* set_on_destruction_;
|
bool* set_on_destruction_;
|
||||||
@ -905,11 +904,11 @@ static void TestWrapper() {
|
|||||||
fprintf(stderr, "==== Test log wrapper\n");
|
fprintf(stderr, "==== Test log wrapper\n");
|
||||||
|
|
||||||
bool custom_logger_deleted = false;
|
bool custom_logger_deleted = false;
|
||||||
MyLogger* my_logger = new MyLogger(&custom_logger_deleted);
|
auto* my_logger = new MyLogger(&custom_logger_deleted);
|
||||||
base::Logger* old_logger = base::GetLogger(GLOG_INFO);
|
base::Logger* old_logger = base::GetLogger(GLOG_INFO);
|
||||||
base::SetLogger(GLOG_INFO, my_logger);
|
base::SetLogger(GLOG_INFO, my_logger);
|
||||||
LOG(INFO) << "Send to wrapped logger";
|
LOG(INFO) << "Send to wrapped logger";
|
||||||
CHECK(strstr(my_logger->data.c_str(), "Send to wrapped logger") != NULL);
|
CHECK(strstr(my_logger->data.c_str(), "Send to wrapped logger") != nullptr);
|
||||||
FlushLogFiles(GLOG_INFO);
|
FlushLogFiles(GLOG_INFO);
|
||||||
|
|
||||||
EXPECT_FALSE(custom_logger_deleted);
|
EXPECT_FALSE(custom_logger_deleted);
|
||||||
@ -1022,17 +1021,14 @@ struct RecordDeletionLogger : public base::Logger {
|
|||||||
{
|
{
|
||||||
*set_on_destruction_ = false;
|
*set_on_destruction_ = false;
|
||||||
}
|
}
|
||||||
virtual ~RecordDeletionLogger() {
|
~RecordDeletionLogger() override { *set_on_destruction_ = true; }
|
||||||
*set_on_destruction_ = true;
|
void Write(bool force_flush, time_t timestamp, const char* message,
|
||||||
}
|
size_t length) override {
|
||||||
virtual void Write(bool force_flush,
|
|
||||||
time_t timestamp,
|
|
||||||
const char* message,
|
|
||||||
size_t length) {
|
|
||||||
wrapped_logger_->Write(force_flush, timestamp, message, length);
|
wrapped_logger_->Write(force_flush, timestamp, message, length);
|
||||||
}
|
}
|
||||||
virtual void Flush() { wrapped_logger_->Flush(); }
|
void Flush() override { wrapped_logger_->Flush(); }
|
||||||
virtual uint32 LogSize() { return wrapped_logger_->LogSize(); }
|
uint32 LogSize() override { return wrapped_logger_->LogSize(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool* set_on_destruction_;
|
bool* set_on_destruction_;
|
||||||
base::Logger* wrapped_logger_;
|
base::Logger* wrapped_logger_;
|
||||||
@ -1054,20 +1050,19 @@ namespace LogTimes {
|
|||||||
// between total running time of 100ms and the period of 10ms. The period is
|
// between total running time of 100ms and the period of 10ms. The period is
|
||||||
// large enough such that any CPU and OS scheduling variation shouldn't affect
|
// large enough such that any CPU and OS scheduling variation shouldn't affect
|
||||||
// the results from the ideal case by more than 5% (500us or 0.5ms)
|
// the results from the ideal case by more than 5% (500us or 0.5ms)
|
||||||
GLOG_CONSTEXPR int64_t LOG_PERIOD_NS = 10000000; // 10ms
|
constexpr int64_t LOG_PERIOD_NS = 10000000; // 10ms
|
||||||
GLOG_CONSTEXPR int64_t LOG_PERIOD_TOL_NS = 500000; // 500us
|
constexpr int64_t LOG_PERIOD_TOL_NS = 500000; // 500us
|
||||||
|
|
||||||
// Set an upper limit for the number of times the stream operator can be
|
// Set an upper limit for the number of times the stream operator can be
|
||||||
// called. Make sure not to exceed this number of times the stream operator is
|
// called. Make sure not to exceed this number of times the stream operator is
|
||||||
// called, since it is also the array size and will be indexed by the stream
|
// called, since it is also the array size and will be indexed by the stream
|
||||||
// operator.
|
// operator.
|
||||||
GLOG_CONSTEXPR size_t MAX_CALLS = 10;
|
constexpr size_t MAX_CALLS = 10;
|
||||||
} // namespace LogTimes
|
} // namespace LogTimes
|
||||||
|
|
||||||
#if defined(HAVE_CXX11_CHRONO) && __cplusplus >= 201103L
|
|
||||||
struct LogTimeRecorder {
|
struct LogTimeRecorder {
|
||||||
LogTimeRecorder() : m_streamTimes(0) {}
|
LogTimeRecorder() = default;
|
||||||
size_t m_streamTimes;
|
size_t m_streamTimes{0};
|
||||||
std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS];
|
std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS];
|
||||||
};
|
};
|
||||||
// The stream operator is called by LOG_EVERY_T every time a logging event
|
// The stream operator is called by LOG_EVERY_T every time a logging event
|
||||||
@ -1083,45 +1078,13 @@ int64 elapsedTime_ns(const std::chrono::steady_clock::time_point& begin,
|
|||||||
return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin))
|
return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin))
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
|
||||||
struct LogTimeRecorder {
|
|
||||||
LogTimeRecorder() : m_streamTimes(0) {}
|
|
||||||
size_t m_streamTimes;
|
|
||||||
LARGE_INTEGER m_callTimes[LogTimes::MAX_CALLS];
|
|
||||||
};
|
|
||||||
std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
|
|
||||||
QueryPerformanceCounter(&t.m_callTimes[t.m_streamTimes++]);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
// get elapsed time in nanoseconds
|
|
||||||
int64 elapsedTime_ns(const LARGE_INTEGER& begin, const LARGE_INTEGER& end) {
|
|
||||||
LARGE_INTEGER freq;
|
|
||||||
QueryPerformanceFrequency(&freq);
|
|
||||||
return (end.QuadPart - begin.QuadPart) * LONGLONG(1000000000) / freq.QuadPart;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct LogTimeRecorder {
|
|
||||||
LogTimeRecorder() : m_streamTimes(0) {}
|
|
||||||
size_t m_streamTimes;
|
|
||||||
timespec m_callTimes[LogTimes::MAX_CALLS];
|
|
||||||
};
|
|
||||||
std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &t.m_callTimes[t.m_streamTimes++]);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
// get elapsed time in nanoseconds
|
|
||||||
int64 elapsedTime_ns(const timespec& begin, const timespec& end) {
|
|
||||||
return (end.tv_sec - begin.tv_sec) * 1000000000 +
|
|
||||||
(end.tv_nsec - begin.tv_nsec);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void TestLogPeriodically() {
|
static void TestLogPeriodically() {
|
||||||
fprintf(stderr, "==== Test log periodically\n");
|
fprintf(stderr, "==== Test log periodically\n");
|
||||||
|
|
||||||
LogTimeRecorder timeLogger;
|
LogTimeRecorder timeLogger;
|
||||||
|
|
||||||
GLOG_CONSTEXPR double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9;
|
constexpr double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9;
|
||||||
|
|
||||||
while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) {
|
while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) {
|
||||||
LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
|
LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
|
||||||
@ -1136,8 +1099,7 @@ static void TestLogPeriodically() {
|
|||||||
timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]);
|
timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t idx = 0; idx < LogTimes::MAX_CALLS - 1; ++idx) {
|
for (long time_ns : nsBetweenCalls) {
|
||||||
int64 time_ns = nsBetweenCalls[idx];
|
|
||||||
EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS);
|
EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1188,8 +1150,7 @@ static vector<string> global_messages;
|
|||||||
// It's free to use LOG() itself.
|
// It's free to use LOG() itself.
|
||||||
class TestLogSinkWriter : public Thread {
|
class TestLogSinkWriter : public Thread {
|
||||||
public:
|
public:
|
||||||
|
TestLogSinkWriter() {
|
||||||
TestLogSinkWriter() : should_exit_(false) {
|
|
||||||
SetJoinable(true);
|
SetJoinable(true);
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
@ -1231,8 +1192,8 @@ class TestLogSinkWriter : public Thread {
|
|||||||
bool HaveWork() { return !messages_.empty() || should_exit_; }
|
bool HaveWork() { return !messages_.empty() || should_exit_; }
|
||||||
|
|
||||||
// Thread body; CAN use LOG() here!
|
// Thread body; CAN use LOG() here!
|
||||||
virtual void Run() {
|
void Run() override {
|
||||||
while (1) {
|
while (true) {
|
||||||
mutex_.Lock();
|
mutex_.Lock();
|
||||||
while (!HaveWork()) {
|
while (!HaveWork()) {
|
||||||
mutex_.Unlock();
|
mutex_.Unlock();
|
||||||
@ -1269,7 +1230,7 @@ class TestLogSinkWriter : public Thread {
|
|||||||
// data ---------------
|
// data ---------------
|
||||||
|
|
||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
bool should_exit_;
|
bool should_exit_{false};
|
||||||
queue<string> messages_; // messages to be logged
|
queue<string> messages_; // messages to be logged
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1283,7 +1244,7 @@ class TestWaitingLogSink : public LogSink {
|
|||||||
tid_ = pthread_self(); // for thread-specific behavior
|
tid_ = pthread_self(); // for thread-specific behavior
|
||||||
AddLogSink(this);
|
AddLogSink(this);
|
||||||
}
|
}
|
||||||
~TestWaitingLogSink() {
|
~TestWaitingLogSink() override {
|
||||||
RemoveLogSink(this);
|
RemoveLogSink(this);
|
||||||
writer_.Stop();
|
writer_.Stop();
|
||||||
writer_.Join();
|
writer_.Join();
|
||||||
@ -1291,10 +1252,10 @@ class TestWaitingLogSink : public LogSink {
|
|||||||
|
|
||||||
// (re)define LogSink interface
|
// (re)define LogSink interface
|
||||||
|
|
||||||
virtual void send(LogSeverity severity, const char* /* full_filename */,
|
void send(LogSeverity severity, const char* /* full_filename */,
|
||||||
const char* base_filename, int line,
|
const char* base_filename, int line,
|
||||||
const LogMessageTime &logmsgtime,
|
const LogMessageTime& logmsgtime, const char* message,
|
||||||
const char* message, size_t message_len) {
|
size_t message_len) override {
|
||||||
// Push it to Writer thread if we are the original logging thread.
|
// Push it to Writer thread if we are the original logging thread.
|
||||||
// Note: Something like ThreadLocalLogSink is a better choice
|
// Note: Something like ThreadLocalLogSink is a better choice
|
||||||
// to do thread-specific LogSink logic for real.
|
// to do thread-specific LogSink logic for real.
|
||||||
@ -1304,7 +1265,7 @@ class TestWaitingLogSink : public LogSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void WaitTillSent() {
|
void WaitTillSent() override {
|
||||||
// Wait for Writer thread if we are the original logging thread.
|
// Wait for Writer thread if we are the original logging thread.
|
||||||
if (pthread_equal(tid_, pthread_self())) writer_.Wait();
|
if (pthread_equal(tid_, pthread_self())) writer_.Wait();
|
||||||
}
|
}
|
||||||
@ -1331,8 +1292,8 @@ static void TestLogSinkWaitTillSent() {
|
|||||||
LOG(WARNING) << "Message 3";
|
LOG(WARNING) << "Message 3";
|
||||||
SleepForMilliseconds(60);
|
SleepForMilliseconds(60);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < global_messages.size(); ++i) {
|
for (auto& global_message : global_messages) {
|
||||||
LOG(INFO) << "Sink capture: " << global_messages[i];
|
LOG(INFO) << "Sink capture: " << global_message;
|
||||||
}
|
}
|
||||||
CHECK_EQ(global_messages.size(), 3UL);
|
CHECK_EQ(global_messages.size(), 3UL);
|
||||||
}
|
}
|
||||||
@ -1342,11 +1303,11 @@ TEST(Strerror, logging) {
|
|||||||
char *msg = strdup(strerror(errcode));
|
char *msg = strdup(strerror(errcode));
|
||||||
const size_t buf_size = strlen(msg) + 1;
|
const size_t buf_size = strlen(msg) + 1;
|
||||||
char *buf = new char[buf_size];
|
char *buf = new char[buf_size];
|
||||||
CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
|
CHECK_EQ(posix_strerror_r(errcode, nullptr, 0), -1);
|
||||||
buf[0] = 'A';
|
buf[0] = 'A';
|
||||||
CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
|
CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
|
||||||
CHECK_EQ(buf[0], 'A');
|
CHECK_EQ(buf[0], 'A');
|
||||||
CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
|
CHECK_EQ(posix_strerror_r(errcode, nullptr, buf_size), -1);
|
||||||
#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
|
#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
|
||||||
// MacOSX or FreeBSD considers this case is an error since there is
|
// MacOSX or FreeBSD considers this case is an error since there is
|
||||||
// no enough space.
|
// no enough space.
|
||||||
|
|||||||
@ -72,7 +72,7 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
|
|||||||
ScopedMockLog() { AddLogSink(this); }
|
ScopedMockLog() { AddLogSink(this); }
|
||||||
|
|
||||||
// When the object is destructed, it stops intercepting logs.
|
// When the object is destructed, it stops intercepting logs.
|
||||||
~ScopedMockLog() { RemoveLogSink(this); }
|
~ScopedMockLog() override { RemoveLogSink(this); }
|
||||||
|
|
||||||
// Implements the mock method:
|
// Implements the mock method:
|
||||||
//
|
//
|
||||||
@ -113,11 +113,10 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
|
|||||||
// be running simultaneously, we ensure thread-safety of the exchange between
|
// be running simultaneously, we ensure thread-safety of the exchange between
|
||||||
// send() and WaitTillSent(), and that for each message, LOG(), send(),
|
// send() and WaitTillSent(), and that for each message, LOG(), send(),
|
||||||
// WaitTillSent() and Log() are executed in the same thread.
|
// WaitTillSent() and Log() are executed in the same thread.
|
||||||
virtual void send(GOOGLE_NAMESPACE::LogSeverity severity,
|
void send(GOOGLE_NAMESPACE::LogSeverity severity, const char* full_filename,
|
||||||
const char* full_filename,
|
const char* /*base_filename*/, int /*line*/,
|
||||||
const char* /*base_filename*/, int /*line*/,
|
const LogMessageTime& /*logmsgtime*/, const char* message,
|
||||||
const LogMessageTime & /*logmsgtime*/,
|
size_t message_len) override {
|
||||||
const char* message, size_t message_len) {
|
|
||||||
// We are only interested in the log severity, full file name, and
|
// We are only interested in the log severity, full file name, and
|
||||||
// log message.
|
// log message.
|
||||||
message_info_.severity = severity;
|
message_info_.severity = severity;
|
||||||
@ -132,7 +131,7 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
|
|||||||
//
|
//
|
||||||
// LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
|
// LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
|
||||||
// a given log message.
|
// a given log message.
|
||||||
virtual void WaitTillSent() {
|
void WaitTillSent() override {
|
||||||
// First, and very importantly, we save a copy of the message being
|
// First, and very importantly, we save a copy of the message being
|
||||||
// processed before calling Log(), since Log() may indirectly call send()
|
// processed before calling Log(), since Log() may indirectly call send()
|
||||||
// and WaitTillSent() in the same thread again.
|
// and WaitTillSent() in the same thread again.
|
||||||
|
|||||||
@ -31,11 +31,11 @@
|
|||||||
//
|
//
|
||||||
// logging_unittest.cc covers the functionality herein
|
// logging_unittest.cc covers the functionality herein
|
||||||
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h> // for close() and write()
|
# include <unistd.h> // for close() and write()
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -72,17 +72,17 @@ const struct {
|
|||||||
static bool kFailureSignalHandlerInstalled = false;
|
static bool kFailureSignalHandlerInstalled = false;
|
||||||
|
|
||||||
#if !defined(GLOG_OS_WINDOWS)
|
#if !defined(GLOG_OS_WINDOWS)
|
||||||
// Returns the program counter from signal context, NULL if unknown.
|
// Returns the program counter from signal context, nullptr if unknown.
|
||||||
void* GetPC(void* ucontext_in_void) {
|
void* GetPC(void* ucontext_in_void) {
|
||||||
#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
|
#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
|
||||||
if (ucontext_in_void != NULL) {
|
if (ucontext_in_void != nullptr) {
|
||||||
ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
|
ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
|
||||||
return (void*)context->PC_FROM_UCONTEXT;
|
return (void*)context->PC_FROM_UCONTEXT;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)ucontext_in_void;
|
(void)ucontext_in_void;
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ void (*g_failure_writer)(const char* data, size_t size) = WriteToStderr;
|
|||||||
// Dumps time information. We don't dump human-readable time information
|
// Dumps time information. We don't dump human-readable time information
|
||||||
// as localtime() is not guaranteed to be async signal safe.
|
// as localtime() is not guaranteed to be async signal safe.
|
||||||
void DumpTimeInfo() {
|
void DumpTimeInfo() {
|
||||||
time_t time_in_sec = time(NULL);
|
time_t time_in_sec = time(nullptr);
|
||||||
char buf[256]; // Big enough for time info.
|
char buf[256]; // Big enough for time info.
|
||||||
MinimalFormatter formatter(buf, sizeof(buf));
|
MinimalFormatter formatter(buf, sizeof(buf));
|
||||||
formatter.AppendString("*** Aborted at ");
|
formatter.AppendString("*** Aborted at ");
|
||||||
@ -179,10 +179,10 @@ void DumpTimeInfo() {
|
|||||||
// Dumps information about the signal to STDERR.
|
// Dumps information about the signal to STDERR.
|
||||||
void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
|
void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
|
||||||
// Get the signal name.
|
// Get the signal name.
|
||||||
const char* signal_name = NULL;
|
const char* signal_name = nullptr;
|
||||||
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
|
for (auto kFailureSignal : kFailureSignals) {
|
||||||
if (signal_number == kFailureSignals[i].number) {
|
if (signal_number == kFailureSignal.number) {
|
||||||
signal_name = kFailureSignals[i].name;
|
signal_name = kFailureSignal.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ void InvokeDefaultSignalHandler(int signal_number) {
|
|||||||
memset(&sig_action, 0, sizeof(sig_action));
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
sigemptyset(&sig_action.sa_mask);
|
sigemptyset(&sig_action.sa_mask);
|
||||||
sig_action.sa_handler = SIG_DFL;
|
sig_action.sa_handler = SIG_DFL;
|
||||||
sigaction(signal_number, &sig_action, NULL);
|
sigaction(signal_number, &sig_action, nullptr);
|
||||||
kill(getpid(), signal_number);
|
kill(getpid(), signal_number);
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
#elif defined(GLOG_OS_WINDOWS)
|
||||||
signal(signal_number, SIG_DFL);
|
signal(signal_number, SIG_DFL);
|
||||||
@ -268,7 +268,7 @@ void InvokeDefaultSignalHandler(int signal_number) {
|
|||||||
// dumping stuff while another thread is doing it. Our policy is to let
|
// dumping stuff while another thread is doing it. Our policy is to let
|
||||||
// the first thread dump stuff and let other threads wait.
|
// the first thread dump stuff and let other threads wait.
|
||||||
// See also comments in FailureSignalHandler().
|
// See also comments in FailureSignalHandler().
|
||||||
static pthread_t* g_entered_thread_id_pointer = NULL;
|
static pthread_t* g_entered_thread_id_pointer = nullptr;
|
||||||
|
|
||||||
// Dumps signal and stack frame information, and invokes the default
|
// Dumps signal and stack frame information, and invokes the default
|
||||||
// signal handler once our job is done.
|
// signal handler once our job is done.
|
||||||
@ -291,13 +291,12 @@ void FailureSignalHandler(int signal_number,
|
|||||||
// if pthread_self() is guaranteed to return non-zero value for thread
|
// 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
|
// ids, but there is no such guarantee. We need to distinguish if the
|
||||||
// old value (value returned from __sync_val_compare_and_swap) is
|
// old value (value returned from __sync_val_compare_and_swap) is
|
||||||
// different from the original value (in this case NULL).
|
// different from the original value (in this case nullptr).
|
||||||
pthread_t* old_thread_id_pointer =
|
pthread_t* old_thread_id_pointer =
|
||||||
glog_internal_namespace_::sync_val_compare_and_swap(
|
glog_internal_namespace_::sync_val_compare_and_swap(
|
||||||
&g_entered_thread_id_pointer,
|
&g_entered_thread_id_pointer, static_cast<pthread_t*>(nullptr),
|
||||||
static_cast<pthread_t*>(NULL),
|
|
||||||
&my_thread_id);
|
&my_thread_id);
|
||||||
if (old_thread_id_pointer != NULL) {
|
if (old_thread_id_pointer != nullptr) {
|
||||||
// We've already entered the signal handler. What should we do?
|
// We've already entered the signal handler. What should we do?
|
||||||
if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
|
if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
|
||||||
// It looks the current thread is reentering the signal handler.
|
// It looks the current thread is reentering the signal handler.
|
||||||
@ -370,7 +369,7 @@ bool IsFailureSignalHandlerInstalled() {
|
|||||||
struct sigaction sig_action;
|
struct sigaction sig_action;
|
||||||
memset(&sig_action, 0, sizeof(sig_action));
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
sigemptyset(&sig_action.sa_mask);
|
sigemptyset(&sig_action.sa_mask);
|
||||||
sigaction(SIGABRT, NULL, &sig_action);
|
sigaction(SIGABRT, nullptr, &sig_action);
|
||||||
if (sig_action.sa_sigaction == &FailureSignalHandler) {
|
if (sig_action.sa_sigaction == &FailureSignalHandler) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -391,8 +390,8 @@ void InstallFailureSignalHandler() {
|
|||||||
sig_action.sa_flags |= SA_SIGINFO;
|
sig_action.sa_flags |= SA_SIGINFO;
|
||||||
sig_action.sa_sigaction = &FailureSignalHandler;
|
sig_action.sa_sigaction = &FailureSignalHandler;
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
|
for (auto kFailureSignal : kFailureSignals) {
|
||||||
CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
|
CHECK_ERR(sigaction(kFailureSignal.number, &sig_action, nullptr));
|
||||||
}
|
}
|
||||||
kFailureSignalHandlerInstalled = true;
|
kFailureSignalHandlerInstalled = true;
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
#elif defined(GLOG_OS_WINDOWS)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ static void* DieInThread(void*) {
|
|||||||
volatile int a = 0;
|
volatile int a = 0;
|
||||||
volatile int b = 1 / a;
|
volatile int b = 1 / a;
|
||||||
fprintf(stderr, "We should have died: b=%d\n", b);
|
fprintf(stderr, "We should have died: b=%d\n", b);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteToStdout(const char* data, size_t size) {
|
static void WriteToStdout(const char* data, size_t size) {
|
||||||
@ -92,8 +92,8 @@ int main(int argc, char **argv) {
|
|||||||
} else if (command == "die_in_thread") {
|
} else if (command == "die_in_thread") {
|
||||||
#if defined(HAVE_PTHREAD)
|
#if defined(HAVE_PTHREAD)
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
pthread_create(&thread, NULL, &DieInThread, NULL);
|
pthread_create(&thread, nullptr, &DieInThread, nullptr);
|
||||||
pthread_join(thread, NULL);
|
pthread_join(thread, nullptr);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "no pthread\n");
|
fprintf(stderr, "no pthread\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ _START_GOOGLE_NAMESPACE_
|
|||||||
// result[1] main
|
// result[1] main
|
||||||
// .... ...
|
// .... ...
|
||||||
//
|
//
|
||||||
// "result" must not be NULL.
|
// "result" must not be nullptr.
|
||||||
GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
|
GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
|
||||||
|
|
||||||
_END_GOOGLE_NAMESPACE_
|
_END_GOOGLE_NAMESPACE_
|
||||||
|
|||||||
@ -32,7 +32,9 @@
|
|||||||
// Note: The glibc implementation may cause a call to malloc.
|
// Note: The glibc implementation may cause a call to malloc.
|
||||||
// This can cause a deadlock in HeapProfiler.
|
// This can cause a deadlock in HeapProfiler.
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#include <string.h>
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|||||||
@ -35,14 +35,15 @@
|
|||||||
// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
|
// 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
|
// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
|
||||||
|
|
||||||
|
#include <cstdint> // for uintptr_t
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <stdint.h> // for uintptr_t
|
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
// Given a pointer to a stack frame, locate and return the calling
|
// Given a pointer to a stack frame, locate and return the calling
|
||||||
// stackframe, or return NULL if no stackframe can be found. Perform sanity
|
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
|
||||||
// checks (the strictness of which is controlled by the boolean parameter
|
// checks (the strictness of which is controlled by the boolean parameter
|
||||||
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
|
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
|
||||||
template<bool STRICT_UNWINDING>
|
template<bool STRICT_UNWINDING>
|
||||||
@ -54,18 +55,20 @@ static void **NextStackFrame(void **old_sp) {
|
|||||||
if (STRICT_UNWINDING) {
|
if (STRICT_UNWINDING) {
|
||||||
// With the stack growing downwards, older stack frame must be
|
// With the stack growing downwards, older stack frame must be
|
||||||
// at a greater address that the current one.
|
// at a greater address that the current one.
|
||||||
if (new_sp <= old_sp) return NULL;
|
if (new_sp <= old_sp) return nullptr;
|
||||||
// Assume stack frames larger than 100,000 bytes are bogus.
|
// Assume stack frames larger than 100,000 bytes are bogus.
|
||||||
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
|
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return nullptr;
|
||||||
} else {
|
} else {
|
||||||
// In the non-strict mode, allow discontiguous stack frames.
|
// In the non-strict mode, allow discontiguous stack frames.
|
||||||
// (alternate-signal-stacks for example).
|
// (alternate-signal-stacks for example).
|
||||||
if (new_sp == old_sp) return NULL;
|
if (new_sp == old_sp) return nullptr;
|
||||||
// And allow frames upto about 1MB.
|
// And allow frames upto about 1MB.
|
||||||
if ((new_sp > old_sp)
|
if ((new_sp > old_sp) &&
|
||||||
&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
|
((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
|
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return nullptr;
|
||||||
return new_sp;
|
return new_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,7 @@ static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ATTRIBUTE_NOINLINE CheckStackTrace(int);
|
void ATTRIBUTE_NOINLINE CheckStackTrace(int);
|
||||||
static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
|
static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
|
||||||
const int STACK_LEN = 10;
|
const int STACK_LEN = 10;
|
||||||
void *stack[STACK_LEN];
|
void *stack[STACK_LEN];
|
||||||
int size;
|
int size;
|
||||||
@ -130,7 +130,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
|
|||||||
CHECK_GE(size, 1);
|
CHECK_GE(size, 1);
|
||||||
CHECK_LE(size, STACK_LEN);
|
CHECK_LE(size, STACK_LEN);
|
||||||
|
|
||||||
if (1) {
|
if (true) {
|
||||||
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
|
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
|
||||||
char **strings = backtrace_symbols(stack, size);
|
char **strings = backtrace_symbols(stack, size);
|
||||||
printf("Obtained %d stack frames.\n", size);
|
printf("Obtained %d stack frames.\n", size);
|
||||||
|
|||||||
@ -31,8 +31,9 @@
|
|||||||
//
|
//
|
||||||
// Produce stack trace using libgcc
|
// Produce stack trace using libgcc
|
||||||
|
|
||||||
#include <cstdlib> // for NULL
|
#include <unwind.h> // ABI defined unwinder
|
||||||
#include <unwind.h> // ABI defined unwinder
|
|
||||||
|
#include <cstdlib> // for nullptr
|
||||||
|
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ class StackTraceInit {
|
|||||||
public:
|
public:
|
||||||
StackTraceInit() {
|
StackTraceInit() {
|
||||||
// Extra call to force initialization
|
// Extra call to force initialization
|
||||||
_Unwind_Backtrace(nop_backtrace, NULL);
|
_Unwind_Backtrace(nop_backtrace, nullptr);
|
||||||
ready_to_run = true;
|
ready_to_run = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -67,13 +68,13 @@ class StackTraceInit {
|
|||||||
static StackTraceInit module_initializer; // Force initialization
|
static StackTraceInit module_initializer; // Force initialization
|
||||||
|
|
||||||
static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
|
static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
|
||||||
trace_arg_t *targ = static_cast<trace_arg_t *>(opq);
|
auto *targ = static_cast<trace_arg_t *>(opq);
|
||||||
|
|
||||||
if (targ->skip_count > 0) {
|
if (targ->skip_count > 0) {
|
||||||
targ->skip_count--;
|
targ->skip_count--;
|
||||||
} else {
|
} else {
|
||||||
targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc));
|
targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targ->count == targ->max_depth) {
|
if (targ->count == targ->max_depth) {
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
|
|||||||
@ -44,7 +44,8 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
}
|
}
|
||||||
skip_count++; // we want to skip the current frame as well
|
skip_count++; // we want to skip the current frame as well
|
||||||
// This API is thread-safe (moreover it walks only the current thread).
|
// 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);
|
return CaptureStackBackTrace(static_cast<DWORD>(skip_count),
|
||||||
|
static_cast<DWORD>(max_depth), result, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
_END_GOOGLE_NAMESPACE_
|
_END_GOOGLE_NAMESPACE_
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
//
|
//
|
||||||
// Produce stack trace
|
// Produce stack trace
|
||||||
|
|
||||||
#include <stdint.h> // for uintptr_t
|
#include <cstdint> // for uintptr_t
|
||||||
|
|
||||||
#include "utilities.h" // for OS_* macros
|
#include "utilities.h" // for OS_* macros
|
||||||
|
|
||||||
@ -38,13 +38,14 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdio> // for NULL
|
#include <cstdio> // for nullptr
|
||||||
|
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
// Given a pointer to a stack frame, locate and return the calling
|
// Given a pointer to a stack frame, locate and return the calling
|
||||||
// stackframe, or return NULL if no stackframe can be found. Perform sanity
|
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
|
||||||
// checks (the strictness of which is controlled by the boolean parameter
|
// checks (the strictness of which is controlled by the boolean parameter
|
||||||
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
|
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
|
||||||
template<bool STRICT_UNWINDING>
|
template<bool STRICT_UNWINDING>
|
||||||
@ -56,28 +57,32 @@ static void **NextStackFrame(void **old_sp) {
|
|||||||
if (STRICT_UNWINDING) {
|
if (STRICT_UNWINDING) {
|
||||||
// With the stack growing downwards, older stack frame must be
|
// With the stack growing downwards, older stack frame must be
|
||||||
// at a greater address that the current one.
|
// at a greater address that the current one.
|
||||||
if (new_sp <= old_sp) return NULL;
|
if (new_sp <= old_sp) return nullptr;
|
||||||
// Assume stack frames larger than 100,000 bytes are bogus.
|
// Assume stack frames larger than 100,000 bytes are bogus.
|
||||||
if (reinterpret_cast<uintptr_t>(new_sp) -
|
if (reinterpret_cast<uintptr_t>(new_sp) -
|
||||||
reinterpret_cast<uintptr_t>(old_sp) >
|
reinterpret_cast<uintptr_t>(old_sp) >
|
||||||
100000)
|
100000) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// In the non-strict mode, allow discontiguous stack frames.
|
// In the non-strict mode, allow discontiguous stack frames.
|
||||||
// (alternate-signal-stacks for example).
|
// (alternate-signal-stacks for example).
|
||||||
if (new_sp == old_sp) return NULL;
|
if (new_sp == old_sp) return nullptr;
|
||||||
// And allow frames upto about 1MB.
|
// And allow frames upto about 1MB.
|
||||||
if ((new_sp > old_sp) && (reinterpret_cast<uintptr_t>(new_sp) -
|
if ((new_sp > old_sp) && (reinterpret_cast<uintptr_t>(new_sp) -
|
||||||
reinterpret_cast<uintptr_t>(old_sp) >
|
reinterpret_cast<uintptr_t>(old_sp) >
|
||||||
1000000))
|
1000000)) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) return NULL;
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
// On 64-bit machines, the stack pointer can be very close to
|
// On 64-bit machines, the stack pointer can be very close to
|
||||||
// 0xffffffff, so we explicitly check for a pointer into the
|
// 0xffffffff, so we explicitly check for a pointer into the
|
||||||
// last two pages in the address space
|
// last two pages in the address space
|
||||||
if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
|
if ((uintptr_t)new_sp >= 0xffffe000) return nullptr;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(GLOG_OS_WINDOWS)
|
#if !defined(GLOG_OS_WINDOWS)
|
||||||
if (!STRICT_UNWINDING) {
|
if (!STRICT_UNWINDING) {
|
||||||
@ -91,7 +96,7 @@ static void **NextStackFrame(void **old_sp) {
|
|||||||
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
|
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
|
||||||
static_cast<uintptr_t>(~(page_size - 1)));
|
static_cast<uintptr_t>(~(page_size - 1)));
|
||||||
if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
|
if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -135,7 +140,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (sp && n < max_depth) {
|
while (sp && n < max_depth) {
|
||||||
if (*(sp + 1) == NULL) {
|
if (*(sp + 1) == nullptr) {
|
||||||
// In 64-bit code, we often see a frame that
|
// In 64-bit code, we often see a frame that
|
||||||
// points to itself and has a return address of 0.
|
// points to itself and has a return address of 0.
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -27,9 +27,8 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "config.h"
|
#include <glog/logging.h>
|
||||||
|
#include <glog/stl_logging.h>
|
||||||
#ifdef HAVE_USING_OPERATOR
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -38,34 +37,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#include "config.h"
|
||||||
// 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"
|
#include "googletest.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
|
|
||||||
using namespace __gnu_cxx;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct user_hash {
|
struct user_hash {
|
||||||
size_t operator()(int x) const { return static_cast<size_t>(x); }
|
size_t operator()(int x) const { return static_cast<size_t>(x); }
|
||||||
@ -98,42 +73,6 @@ static void TestSTLLogging() {
|
|||||||
CHECK_EQ(m, copied_m); // This must compile.
|
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.
|
// Test a long sequence.
|
||||||
vector<int> v;
|
vector<int> v;
|
||||||
@ -156,35 +95,16 @@ static void TestSTLLogging() {
|
|||||||
{
|
{
|
||||||
// Test a sorted pair associative container.
|
// Test a sorted pair associative container.
|
||||||
// Use a non-default comparison functor.
|
// Use a non-default comparison functor.
|
||||||
map< int, string, greater<int> > m;
|
map<int, string, greater<> > m;
|
||||||
m[20] = "twenty";
|
m[20] = "twenty";
|
||||||
m[10] = "ten";
|
m[10] = "ten";
|
||||||
m[30] = "thirty";
|
m[30] = "thirty";
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << m;
|
ss << m;
|
||||||
EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
|
EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
|
||||||
map< int, string, greater<int> > copied_m(m);
|
map<int, string, greater<> > copied_m(m);
|
||||||
CHECK_EQ(m, copied_m); // This must compile.
|
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**) {
|
int main(int, char**) {
|
||||||
@ -192,16 +112,3 @@ int main(int, char**) {
|
|||||||
std::cout << "PASS\n";
|
std::cout << "PASS\n";
|
||||||
return 0;
|
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
|
|
||||||
|
|||||||
@ -78,13 +78,13 @@ static int AssertFail() {
|
|||||||
|
|
||||||
#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
|
#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
|
||||||
|
|
||||||
static SymbolizeCallback g_symbolize_callback = NULL;
|
static SymbolizeCallback g_symbolize_callback = nullptr;
|
||||||
void InstallSymbolizeCallback(SymbolizeCallback callback) {
|
void InstallSymbolizeCallback(SymbolizeCallback callback) {
|
||||||
g_symbolize_callback = callback;
|
g_symbolize_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
|
static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
|
||||||
NULL;
|
nullptr;
|
||||||
void InstallSymbolizeOpenObjectFileCallback(
|
void InstallSymbolizeOpenObjectFileCallback(
|
||||||
SymbolizeOpenObjectFileCallback callback) {
|
SymbolizeOpenObjectFileCallback callback) {
|
||||||
g_symbolize_open_object_file_callback = callback;
|
g_symbolize_open_object_file_callback = callback;
|
||||||
@ -118,21 +118,22 @@ _END_GOOGLE_NAMESPACE_
|
|||||||
#else
|
#else
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cerrno>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdint.h>
|
#include <glog/raw_logging.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "symbolize.h"
|
#include <cerrno>
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <glog/raw_logging.h>
|
#include "symbolize.h"
|
||||||
|
|
||||||
// Re-runs fn until it doesn't cause EINTR.
|
// Re-runs fn until it doesn't cause EINTR.
|
||||||
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
|
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
|
||||||
@ -278,7 +279,7 @@ static ATTRIBUTE_NOINLINE bool
|
|||||||
FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
|
FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
|
||||||
uint64_t symbol_offset, const ElfW(Shdr) *strtab,
|
uint64_t symbol_offset, const ElfW(Shdr) *strtab,
|
||||||
const ElfW(Shdr) *symtab) {
|
const ElfW(Shdr) *symtab) {
|
||||||
if (symtab == NULL) {
|
if (symtab == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const size_t num_symbols = symtab->sh_size / symtab->sh_entsize;
|
const size_t num_symbols = symtab->sh_size / symtab->sh_entsize;
|
||||||
@ -312,7 +313,7 @@ FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
|
|||||||
start_address <= pc && pc < end_address) {
|
start_address <= pc && pc < end_address) {
|
||||||
ssize_t len1 = ReadFromOffset(fd, out, out_size,
|
ssize_t len1 = ReadFromOffset(fd, out, out_size,
|
||||||
strtab->sh_offset + symbol.st_name);
|
strtab->sh_offset + symbol.st_name);
|
||||||
if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) {
|
if (len1 <= 0 || memchr(out, '\0', out_size) == nullptr) {
|
||||||
memset(out, 0, out_size);
|
memset(out, 0, out_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -382,8 +383,8 @@ struct FileDescriptor {
|
|||||||
int get() { return fd_; }
|
int get() { return fd_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileDescriptor(const FileDescriptor &);
|
FileDescriptor(const FileDescriptor &) = delete;
|
||||||
void operator=(const FileDescriptor&);
|
void operator=(const FileDescriptor &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper class for reading lines from file.
|
// Helper class for reading lines from file.
|
||||||
@ -420,7 +421,7 @@ class LineReader {
|
|||||||
bol_ = eol_ + 1; // Advance to the next line in the buffer.
|
bol_ = eol_ + 1; // Advance to the next line in the buffer.
|
||||||
SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
|
SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
|
||||||
if (!HasCompleteLine()) {
|
if (!HasCompleteLine()) {
|
||||||
const size_t incomplete_line_length = static_cast<size_t>(eod_ - bol_);
|
const auto incomplete_line_length = static_cast<size_t>(eod_ - bol_);
|
||||||
// Move the trailing incomplete line to the beginning.
|
// Move the trailing incomplete line to the beginning.
|
||||||
memmove(buf_, bol_, incomplete_line_length);
|
memmove(buf_, bol_, incomplete_line_length);
|
||||||
// Read text from file and append it.
|
// Read text from file and append it.
|
||||||
@ -437,7 +438,7 @@ class LineReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
eol_ = FindLineFeed();
|
eol_ = FindLineFeed();
|
||||||
if (eol_ == NULL) { // '\n' not found. Malformed line.
|
if (eol_ == nullptr) { // '\n' not found. Malformed line.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*eol_ = '\0'; // Replace '\n' with '\0'.
|
*eol_ = '\0'; // Replace '\n' with '\0'.
|
||||||
@ -458,8 +459,8 @@ class LineReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LineReader(const LineReader &);
|
LineReader(const LineReader &) = delete;
|
||||||
void operator=(const LineReader&);
|
void operator=(const LineReader &) = delete;
|
||||||
|
|
||||||
char *FindLineFeed() {
|
char *FindLineFeed() {
|
||||||
return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
|
return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
|
||||||
@ -470,7 +471,7 @@ class LineReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool HasCompleteLine() {
|
bool HasCompleteLine() {
|
||||||
return !BufferIsEmpty() && FindLineFeed() != NULL;
|
return !BufferIsEmpty() && FindLineFeed() != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int fd_;
|
const int fd_;
|
||||||
@ -667,20 +668,20 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
|
|||||||
// POSIX doesn't define any async-signal safe function for converting
|
// POSIX doesn't define any async-signal safe function for converting
|
||||||
// an integer to ASCII. We'll have to define our own version.
|
// 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
|
// 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"
|
// conversion was successful or nullptr otherwise. It never writes more than
|
||||||
// bytes. Output will be truncated as needed, and a NUL character is always
|
// "sz" bytes. Output will be truncated as needed, and a NUL character is always
|
||||||
// appended.
|
// appended.
|
||||||
// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
|
// 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) {
|
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.
|
// Make sure we can write at least one NUL byte.
|
||||||
size_t n = 1;
|
size_t n = 1;
|
||||||
if (n > sz) {
|
if (n > sz) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base < 2 || base > 16) {
|
if (base < 2 || base > 16) {
|
||||||
buf[0] = '\000';
|
buf[0] = '\000';
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *start = buf;
|
char *start = buf;
|
||||||
@ -692,7 +693,7 @@ static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t pad
|
|||||||
// Make sure there is still enough space left in our output buffer.
|
// Make sure there is still enough space left in our output buffer.
|
||||||
if (++n > sz) {
|
if (++n > sz) {
|
||||||
buf[0] = '\000';
|
buf[0] = '\000';
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the next digit.
|
// Output the next digit.
|
||||||
@ -750,7 +751,7 @@ static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) {
|
|||||||
// get inlined.
|
// get inlined.
|
||||||
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
|
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
|
||||||
size_t out_size) {
|
size_t out_size) {
|
||||||
uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
|
auto pc0 = reinterpret_cast<uintptr_t>(pc);
|
||||||
uint64_t start_address = 0;
|
uint64_t start_address = 0;
|
||||||
uint64_t base_address = 0;
|
uint64_t base_address = 0;
|
||||||
int object_fd = -1;
|
int object_fd = -1;
|
||||||
@ -874,7 +875,7 @@ class SymInitializer {
|
|||||||
public:
|
public:
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
bool ready;
|
bool ready;
|
||||||
SymInitializer() : process(NULL), ready(false) {
|
SymInitializer() : process(nullptr), ready(false) {
|
||||||
// Initialize the symbol handler.
|
// Initialize the symbol handler.
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
|
||||||
process = GetCurrentProcess();
|
process = GetCurrentProcess();
|
||||||
@ -882,7 +883,7 @@ public:
|
|||||||
// We do not request undecorated symbols with SYMOPT_UNDNAME
|
// We do not request undecorated symbols with SYMOPT_UNDNAME
|
||||||
// because the mangling library calls UnDecorateSymbolName.
|
// because the mangling library calls UnDecorateSymbolName.
|
||||||
SymSetOptions(SYMOPT_DEFERRED_LOADS);
|
SymSetOptions(SYMOPT_DEFERRED_LOADS);
|
||||||
if (SymInitialize(process, NULL, true)) {
|
if (SymInitialize(process, nullptr, true)) {
|
||||||
ready = true;
|
ready = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,11 +116,7 @@ _START_GOOGLE_NAMESPACE_
|
|||||||
// counter "pc". The callback function should write output to "out"
|
// counter "pc". The callback function should write output to "out"
|
||||||
// and return the size of the output written. On error, the callback
|
// and return the size of the output written. On error, the callback
|
||||||
// function should return -1.
|
// function should return -1.
|
||||||
typedef int (*SymbolizeCallback)(int fd,
|
using SymbolizeCallback = int (*)(int, void *, char *, size_t, uint64_t);
|
||||||
void* pc,
|
|
||||||
char* out,
|
|
||||||
size_t out_size,
|
|
||||||
uint64_t relocation);
|
|
||||||
GLOG_EXPORT
|
GLOG_EXPORT
|
||||||
void InstallSymbolizeCallback(SymbolizeCallback callback);
|
void InstallSymbolizeCallback(SymbolizeCallback callback);
|
||||||
|
|
||||||
@ -134,11 +130,8 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
|
|||||||
// file is opened successfully, returns the file descriptor. Otherwise,
|
// file is opened successfully, returns the file descriptor. Otherwise,
|
||||||
// returns -1. |out_file_name_size| is the size of the file name buffer
|
// returns -1. |out_file_name_size| is the size of the file name buffer
|
||||||
// (including the null-terminator).
|
// (including the null-terminator).
|
||||||
typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
|
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t &,
|
||||||
uint64_t& start_address,
|
uint64_t &, char *, size_t);
|
||||||
uint64_t& base_address,
|
|
||||||
char* out_file_name,
|
|
||||||
size_t out_file_name_size);
|
|
||||||
void InstallSymbolizeOpenObjectFileCallback(
|
void InstallSymbolizeOpenObjectFileCallback(
|
||||||
SymbolizeOpenObjectFileCallback callback);
|
SymbolizeOpenObjectFileCallback callback);
|
||||||
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@ static const char *TrySymbolize(void *pc) {
|
|||||||
if (Symbolize(pc, symbol, sizeof(symbol))) {
|
if (Symbolize(pc, symbol, sizeof(symbol))) {
|
||||||
return symbol;
|
return symbol;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -123,12 +123,12 @@ TEST(Symbolize, Symbolize) {
|
|||||||
TrySymbolize(reinterpret_cast<void *>(&static_func));
|
TrySymbolize(reinterpret_cast<void *>(&static_func));
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
||||||
CHECK(NULL != static_func_symbol);
|
CHECK(nullptr != static_func_symbol);
|
||||||
EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
|
EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
|
||||||
strcmp("static_func()", static_func_symbol) == 0);
|
strcmp("static_func()", static_func_symbol) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPECT_TRUE(NULL == TrySymbolize(NULL));
|
EXPECT_TRUE(nullptr == TrySymbolize(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
@ -181,7 +181,7 @@ static void SymbolizeSignalHandler(int /*signo*/) {
|
|||||||
sizeof(g_symbolize_buffer))) {
|
sizeof(g_symbolize_buffer))) {
|
||||||
g_symbolize_result = g_symbolize_buffer;
|
g_symbolize_result = g_symbolize_buffer;
|
||||||
} else {
|
} else {
|
||||||
g_symbolize_result = NULL;
|
g_symbolize_result = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +278,9 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
|
|||||||
LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed;
|
LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed;
|
||||||
|
|
||||||
// Now restore the old alt-signal-stack and signal handlers.
|
// Now restore the old alt-signal-stack and signal handlers.
|
||||||
CHECK_ERR(sigaltstack(&old_sigstk, NULL));
|
CHECK_ERR(sigaltstack(&old_sigstk, nullptr));
|
||||||
CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL));
|
CHECK_ERR(sigaction(SIGUSR1, &old_sa1, nullptr));
|
||||||
CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL));
|
CHECK_ERR(sigaction(SIGUSR2, &old_sa2, nullptr));
|
||||||
|
|
||||||
return g_symbolize_result;
|
return g_symbolize_result;
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ TEST(Symbolize, SymbolizeStackConsumption) {
|
|||||||
// mangled or an unmangled name here.
|
// mangled or an unmangled name here.
|
||||||
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func),
|
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func),
|
||||||
&stack_consumed);
|
&stack_consumed);
|
||||||
CHECK(NULL != symbol);
|
CHECK(nullptr != symbol);
|
||||||
EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
|
EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
|
||||||
strcmp("static_func()", symbol) == 0);
|
strcmp("static_func()", symbol) == 0);
|
||||||
EXPECT_GT(stack_consumed, 0);
|
EXPECT_GT(stack_consumed, 0);
|
||||||
@ -334,7 +334,7 @@ TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
|
|||||||
// x86 specific tests. Uses some inline assembler.
|
// x86 specific tests. Uses some inline assembler.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
inline void* always_inline inline_func() {
|
inline void* always_inline inline_func() {
|
||||||
void *pc = NULL;
|
void *pc = nullptr;
|
||||||
#ifdef TEST_X86_32_AND_64
|
#ifdef TEST_X86_32_AND_64
|
||||||
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
|
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
|
||||||
#endif
|
#endif
|
||||||
@ -343,7 +343,7 @@ inline void* always_inline inline_func() {
|
|||||||
|
|
||||||
void* ATTRIBUTE_NOINLINE non_inline_func();
|
void* ATTRIBUTE_NOINLINE non_inline_func();
|
||||||
void* ATTRIBUTE_NOINLINE non_inline_func() {
|
void* ATTRIBUTE_NOINLINE non_inline_func() {
|
||||||
void *pc = NULL;
|
void *pc = nullptr;
|
||||||
#ifdef TEST_X86_32_AND_64
|
#ifdef TEST_X86_32_AND_64
|
||||||
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
|
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
|
||||||
#endif
|
#endif
|
||||||
@ -356,7 +356,7 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
|
|||||||
const char *symbol = TrySymbolize(pc);
|
const char *symbol = TrySymbolize(pc);
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
||||||
CHECK(symbol != NULL);
|
CHECK(symbol != nullptr);
|
||||||
CHECK_STREQ(symbol, "non_inline_func");
|
CHECK_STREQ(symbol, "non_inline_func");
|
||||||
#endif
|
#endif
|
||||||
cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
|
cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
|
||||||
@ -369,7 +369,7 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
|
|||||||
const char *symbol = TrySymbolize(pc);
|
const char *symbol = TrySymbolize(pc);
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
||||||
CHECK(symbol != NULL);
|
CHECK(symbol != nullptr);
|
||||||
CHECK_STREQ(symbol, __FUNCTION__);
|
CHECK_STREQ(symbol, __FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
|
cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
|
||||||
@ -384,7 +384,7 @@ static void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
|
|||||||
const char *symbol = TrySymbolize(return_address);
|
const char *symbol = TrySymbolize(return_address);
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
||||||
CHECK(symbol != NULL);
|
CHECK(symbol != nullptr);
|
||||||
CHECK_STREQ(symbol, "main");
|
CHECK_STREQ(symbol, "main");
|
||||||
#endif
|
#endif
|
||||||
cout << "Test case TestWithReturnAddress passed." << endl;
|
cout << "Test case TestWithReturnAddress passed." << endl;
|
||||||
@ -428,7 +428,7 @@ __declspec(noinline) void TestWithReturnAddress() {
|
|||||||
;
|
;
|
||||||
const char *symbol = TrySymbolize(return_address);
|
const char *symbol = TrySymbolize(return_address);
|
||||||
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
#if !defined(_MSC_VER) || !defined(NDEBUG)
|
||||||
CHECK(symbol != NULL);
|
CHECK(symbol != nullptr);
|
||||||
CHECK_STREQ(symbol, "main");
|
CHECK_STREQ(symbol, "main");
|
||||||
#endif
|
#endif
|
||||||
cout << "Test case TestWithReturnAddress passed." << endl;
|
cout << "Test case TestWithReturnAddress passed." << endl;
|
||||||
@ -444,7 +444,7 @@ int main(int argc, char **argv) {
|
|||||||
# if defined(__ELF__)
|
# if defined(__ELF__)
|
||||||
// We don't want to get affected by the callback interface, that may be
|
// We don't want to get affected by the callback interface, that may be
|
||||||
// used to install some callback function at InitGoogle() time.
|
// used to install some callback function at InitGoogle() time.
|
||||||
InstallSymbolizeCallback(NULL);
|
InstallSymbolizeCallback(nullptr);
|
||||||
|
|
||||||
TestWithPCInsideInlineFunction();
|
TestWithPCInsideInlineFunction();
|
||||||
TestWithPCInsideNonInlineFunction();
|
TestWithPCInsideNonInlineFunction();
|
||||||
|
|||||||
@ -64,10 +64,10 @@ using std::string;
|
|||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
static const char* g_program_invocation_short_name = NULL;
|
static const char* g_program_invocation_short_name = nullptr;
|
||||||
|
|
||||||
bool IsGoogleLoggingInitialized() {
|
bool IsGoogleLoggingInitialized() {
|
||||||
return g_program_invocation_short_name != NULL;
|
return g_program_invocation_short_name != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_END_GOOGLE_NAMESPACE_
|
_END_GOOGLE_NAMESPACE_
|
||||||
@ -84,7 +84,7 @@ GLOG_DEFINE_bool(symbolize_stacktrace, true,
|
|||||||
|
|
||||||
_START_GOOGLE_NAMESPACE_
|
_START_GOOGLE_NAMESPACE_
|
||||||
|
|
||||||
typedef void DebugWriter(const char*, void*);
|
using DebugWriter = void(const char*, void*);
|
||||||
|
|
||||||
// The %p field width for printf() functions is two characters per byte.
|
// The %p field width for printf() functions is two characters per byte.
|
||||||
// For some environments, add two extra bytes for the leading "0x".
|
// For some environments, add two extra bytes for the leading "0x".
|
||||||
@ -152,13 +152,12 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#ifdef __GNUC__
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
__declspec(noreturn)
|
|
||||||
#endif
|
#endif
|
||||||
static void DumpStackTraceAndExit() {
|
static void
|
||||||
DumpStackTrace(1, DebugWriteToStderr, NULL);
|
DumpStackTraceAndExit() {
|
||||||
|
DumpStackTrace(1, DebugWriteToStderr, nullptr);
|
||||||
|
|
||||||
// TODO(hamaji): Use signal instead of sigaction?
|
// TODO(hamaji): Use signal instead of sigaction?
|
||||||
if (IsFailureSignalHandlerInstalled()) {
|
if (IsFailureSignalHandlerInstalled()) {
|
||||||
@ -169,7 +168,7 @@ static void DumpStackTraceAndExit() {
|
|||||||
memset(&sig_action, 0, sizeof(sig_action));
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
sigemptyset(&sig_action.sa_mask);
|
sigemptyset(&sig_action.sa_mask);
|
||||||
sig_action.sa_handler = SIG_DFL;
|
sig_action.sa_handler = SIG_DFL;
|
||||||
sigaction(SIGABRT, &sig_action, NULL);
|
sigaction(SIGABRT, &sig_action, nullptr);
|
||||||
#elif defined(GLOG_OS_WINDOWS)
|
#elif defined(GLOG_OS_WINDOWS)
|
||||||
signal(SIGABRT, SIG_DFL);
|
signal(SIGABRT, SIG_DFL);
|
||||||
#endif // HAVE_SIGACTION
|
#endif // HAVE_SIGACTION
|
||||||
@ -187,7 +186,7 @@ _START_GOOGLE_NAMESPACE_
|
|||||||
namespace glog_internal_namespace_ {
|
namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
const char* ProgramInvocationShortName() {
|
const char* ProgramInvocationShortName() {
|
||||||
if (g_program_invocation_short_name != NULL) {
|
if (g_program_invocation_short_name != nullptr) {
|
||||||
return g_program_invocation_short_name;
|
return g_program_invocation_short_name;
|
||||||
} else {
|
} else {
|
||||||
// TODO(hamaji): Use /proc/self/cmdline and so?
|
// TODO(hamaji): Use /proc/self/cmdline and so?
|
||||||
@ -229,7 +228,7 @@ static int gettimeofday(struct timeval *tv, void* /*tz*/) {
|
|||||||
int64 CycleClock_Now() {
|
int64 CycleClock_Now() {
|
||||||
// TODO(hamaji): temporary impementation - it might be too slow.
|
// TODO(hamaji): temporary impementation - it might be too slow.
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, nullptr);
|
||||||
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,10 +271,10 @@ pid_t GetTID() {
|
|||||||
if (!lacks_gettid) {
|
if (!lacks_gettid) {
|
||||||
#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
|
#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
|
||||||
uint64_t tid64;
|
uint64_t tid64;
|
||||||
const int error = pthread_threadid_np(NULL, &tid64);
|
const int error = pthread_threadid_np(nullptr, &tid64);
|
||||||
pid_t tid = error ? -1 : static_cast<pid_t>(tid64);
|
pid_t tid = error ? -1 : static_cast<pid_t>(tid64);
|
||||||
#else
|
#else
|
||||||
pid_t tid = static_cast<pid_t>(syscall(__NR_gettid));
|
auto tid = static_cast<pid_t>(syscall(__NR_gettid));
|
||||||
#endif
|
#endif
|
||||||
if (tid != -1) {
|
if (tid != -1) {
|
||||||
return tid;
|
return tid;
|
||||||
@ -321,12 +320,12 @@ static void MyUserNameInitializer() {
|
|||||||
#else
|
#else
|
||||||
const char* user = getenv("USER");
|
const char* user = getenv("USER");
|
||||||
#endif
|
#endif
|
||||||
if (user != NULL) {
|
if (user != nullptr) {
|
||||||
g_my_user_name = user;
|
g_my_user_name = user;
|
||||||
} else {
|
} else {
|
||||||
#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H)
|
#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H)
|
||||||
struct passwd pwd;
|
struct passwd pwd;
|
||||||
struct passwd* result = NULL;
|
struct passwd* result = nullptr;
|
||||||
char buffer[1024] = {'\0'};
|
char buffer[1024] = {'\0'};
|
||||||
uid_t uid = geteuid();
|
uid_t uid = geteuid();
|
||||||
int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result);
|
int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result);
|
||||||
@ -341,7 +340,6 @@ static void MyUserNameInitializer() {
|
|||||||
g_my_user_name = "invalid-user";
|
g_my_user_name = "invalid-user";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer())
|
REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer())
|
||||||
|
|
||||||
@ -353,7 +351,7 @@ void DumpStackTraceToString(string* stacktrace) {
|
|||||||
|
|
||||||
// We use an atomic operation to prevent problems with calling CrashReason
|
// We use an atomic operation to prevent problems with calling CrashReason
|
||||||
// from inside the Mutex implementation (potentially through RAW_CHECK).
|
// from inside the Mutex implementation (potentially through RAW_CHECK).
|
||||||
static const CrashReason* g_reason = 0;
|
static const CrashReason* g_reason = nullptr;
|
||||||
|
|
||||||
void SetCrashReason(const CrashReason* r) {
|
void SetCrashReason(const CrashReason* r) {
|
||||||
sync_val_compare_and_swap(&g_reason,
|
sync_val_compare_and_swap(&g_reason,
|
||||||
@ -378,7 +376,7 @@ void InitGoogleLoggingUtilities(const char* argv0) {
|
|||||||
void ShutdownGoogleLoggingUtilities() {
|
void ShutdownGoogleLoggingUtilities() {
|
||||||
CHECK(IsGoogleLoggingInitialized())
|
CHECK(IsGoogleLoggingInitialized())
|
||||||
<< "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
|
<< "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
|
||||||
g_program_invocation_short_name = NULL;
|
g_program_invocation_short_name = nullptr;
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
closelog();
|
closelog();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -191,16 +191,16 @@ inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
|
|||||||
void DumpStackTraceToString(std::string* stacktrace);
|
void DumpStackTraceToString(std::string* stacktrace);
|
||||||
|
|
||||||
struct CrashReason {
|
struct CrashReason {
|
||||||
CrashReason() : filename(0), line_number(0), message(0), depth(0) {}
|
CrashReason() = default;
|
||||||
|
|
||||||
const char* filename;
|
const char* filename{nullptr};
|
||||||
int line_number;
|
int line_number{0};
|
||||||
const char* message;
|
const char* message{nullptr};
|
||||||
|
|
||||||
// We'll also store a bit of stack trace context at the time of crash as
|
// We'll also store a bit of stack trace context at the time of crash as
|
||||||
// it may not be available later on.
|
// it may not be available later on.
|
||||||
void* stack[32];
|
void* stack[32];
|
||||||
int depth;
|
int depth{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetCrashReason(const CrashReason* r);
|
void SetCrashReason(const CrashReason* r);
|
||||||
|
|||||||
@ -74,7 +74,7 @@ GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len,
|
|||||||
const char* str, size_t str_len) {
|
const char* str, size_t str_len) {
|
||||||
size_t p = 0;
|
size_t p = 0;
|
||||||
size_t s = 0;
|
size_t s = 0;
|
||||||
while (1) {
|
while (true) {
|
||||||
if (p == patt_len && s == str_len) return true;
|
if (p == patt_len && s == str_len) return true;
|
||||||
if (p == patt_len) return false;
|
if (p == patt_len) return false;
|
||||||
if (s == str_len) return p+1 == patt_len && pattern[p] == '*';
|
if (s == str_len) return p+1 == patt_len && pattern[p] == '*';
|
||||||
@ -120,8 +120,8 @@ struct VModuleInfo {
|
|||||||
static Mutex vmodule_lock;
|
static Mutex vmodule_lock;
|
||||||
// Pointer to head of the VModuleInfo list.
|
// Pointer to head of the VModuleInfo list.
|
||||||
// It's a map from module pattern to logging level for those module(s).
|
// It's a map from module pattern to logging level for those module(s).
|
||||||
static VModuleInfo* vmodule_list = 0;
|
static VModuleInfo* vmodule_list = nullptr;
|
||||||
static SiteFlag* cached_site_list = 0;
|
static SiteFlag* cached_site_list = nullptr;
|
||||||
|
|
||||||
// Boolean initialization flag.
|
// Boolean initialization flag.
|
||||||
static bool inited_vmodule = false;
|
static bool inited_vmodule = false;
|
||||||
@ -134,13 +134,13 @@ static void VLOG2Initializer() {
|
|||||||
inited_vmodule = false;
|
inited_vmodule = false;
|
||||||
const char* vmodule = FLAGS_vmodule.c_str();
|
const char* vmodule = FLAGS_vmodule.c_str();
|
||||||
const char* sep;
|
const char* sep;
|
||||||
VModuleInfo* head = NULL;
|
VModuleInfo* head = nullptr;
|
||||||
VModuleInfo* tail = NULL;
|
VModuleInfo* tail = nullptr;
|
||||||
while ((sep = strchr(vmodule, '=')) != NULL) {
|
while ((sep = strchr(vmodule, '=')) != nullptr) {
|
||||||
string pattern(vmodule, static_cast<size_t>(sep - vmodule));
|
string pattern(vmodule, static_cast<size_t>(sep - vmodule));
|
||||||
int module_level;
|
int module_level;
|
||||||
if (sscanf(sep, "=%d", &module_level) == 1) {
|
if (sscanf(sep, "=%d", &module_level) == 1) {
|
||||||
VModuleInfo* info = new VModuleInfo;
|
auto* info = new VModuleInfo;
|
||||||
info->module_pattern = pattern;
|
info->module_pattern = pattern;
|
||||||
info->vlog_level = module_level;
|
info->vlog_level = module_level;
|
||||||
if (head) {
|
if (head) {
|
||||||
@ -152,7 +152,7 @@ static void VLOG2Initializer() {
|
|||||||
}
|
}
|
||||||
// Skip past this entry
|
// Skip past this entry
|
||||||
vmodule = strchr(sep, ',');
|
vmodule = strchr(sep, ',');
|
||||||
if (vmodule == NULL) break;
|
if (vmodule == nullptr) break;
|
||||||
vmodule++; // Skip past ","
|
vmodule++; // Skip past ","
|
||||||
}
|
}
|
||||||
if (head) { // Put them into the list at the head:
|
if (head) { // Put them into the list at the head:
|
||||||
@ -169,8 +169,8 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
{
|
{
|
||||||
MutexLock l(&vmodule_lock); // protect whole read-modify-write
|
MutexLock l(&vmodule_lock); // protect whole read-modify-write
|
||||||
for (const VModuleInfo* info = vmodule_list;
|
for (const VModuleInfo* info = vmodule_list; info != nullptr;
|
||||||
info != NULL; info = info->next) {
|
info = info->next) {
|
||||||
if (info->module_pattern == module_pattern) {
|
if (info->module_pattern == module_pattern) {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
result = info->vlog_level;
|
result = info->vlog_level;
|
||||||
@ -186,7 +186,7 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
VModuleInfo* info = new VModuleInfo;
|
auto* info = new VModuleInfo;
|
||||||
info->module_pattern = module_pattern;
|
info->module_pattern = module_pattern;
|
||||||
info->vlog_level = log_level;
|
info->vlog_level = log_level;
|
||||||
info->next = vmodule_list;
|
info->next = vmodule_list;
|
||||||
@ -242,7 +242,8 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
|
|||||||
|
|
||||||
base = base ? (base+1) : fname;
|
base = base ? (base+1) : fname;
|
||||||
const char* base_end = strchr(base, '.');
|
const char* base_end = strchr(base, '.');
|
||||||
size_t base_length = base_end ? size_t(base_end - base) : strlen(base);
|
size_t base_length =
|
||||||
|
base_end ? static_cast<size_t>(base_end - base) : strlen(base);
|
||||||
|
|
||||||
// Trim out trailing "-inl" if any
|
// Trim out trailing "-inl" if any
|
||||||
if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
|
if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
|
||||||
@ -254,8 +255,8 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
|
|||||||
|
|
||||||
// find target in vector of modules, replace site_flag_value with
|
// find target in vector of modules, replace site_flag_value with
|
||||||
// a module-specific verbose level, if any.
|
// a module-specific verbose level, if any.
|
||||||
for (const VModuleInfo* info = vmodule_list;
|
for (const VModuleInfo* info = vmodule_list; info != nullptr;
|
||||||
info != NULL; info = info->next) {
|
info = info->next) {
|
||||||
if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
|
if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
|
||||||
base, base_length)) {
|
base, base_length)) {
|
||||||
site_flag_value = &info->vlog_level;
|
site_flag_value = &info->vlog_level;
|
||||||
|
|||||||
@ -352,20 +352,20 @@ _wopendir(
|
|||||||
wchar_t *p;
|
wchar_t *p;
|
||||||
|
|
||||||
/* Must have directory name */
|
/* Must have directory name */
|
||||||
if (dirname == NULL || dirname[0] == '\0') {
|
if (dirname == nullptr || dirname[0] == '\0') {
|
||||||
dirent_set_errno (ENOENT);
|
dirent_set_errno(ENOENT);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new _WDIR structure */
|
/* Allocate new _WDIR structure */
|
||||||
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
|
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset _WDIR structure */
|
/* Reset _WDIR structure */
|
||||||
dirp->handle = INVALID_HANDLE_VALUE;
|
dirp->handle = INVALID_HANDLE_VALUE;
|
||||||
dirp->patt = NULL;
|
dirp->patt = nullptr;
|
||||||
dirp->cached = 0;
|
dirp->cached = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -376,7 +376,7 @@ _wopendir(
|
|||||||
*/
|
*/
|
||||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
/* Desktop */
|
/* Desktop */
|
||||||
n = GetFullPathNameW (dirname, 0, NULL, NULL);
|
n = GetFullPathNameW(dirname, 0, nullptr, nullptr);
|
||||||
#else
|
#else
|
||||||
/* WinRT */
|
/* WinRT */
|
||||||
n = wcslen (dirname);
|
n = wcslen (dirname);
|
||||||
@ -384,8 +384,8 @@ _wopendir(
|
|||||||
|
|
||||||
/* Allocate room for absolute directory name and search pattern */
|
/* Allocate room for absolute directory name and search pattern */
|
||||||
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
|
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
|
||||||
if (dirp->patt == NULL) {
|
if (dirp->patt == nullptr) {
|
||||||
goto exit_closedir;
|
goto exit_closedir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -398,7 +398,7 @@ _wopendir(
|
|||||||
*/
|
*/
|
||||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
/* Desktop */
|
/* Desktop */
|
||||||
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
|
n = GetFullPathNameW(dirname, n, dirp->patt, nullptr);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
goto exit_closedir;
|
goto exit_closedir;
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ _wopendir(
|
|||||||
/* Failure */
|
/* Failure */
|
||||||
exit_closedir:
|
exit_closedir:
|
||||||
_wclosedir (dirp);
|
_wclosedir (dirp);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -452,7 +452,7 @@ _wreaddir(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Read directory entry to buffer. We can safely ignore the return value
|
* Read directory entry to buffer. We can safely ignore the return value
|
||||||
* as entry will be set to NULL in case of error.
|
* as entry will be set to nullptr in case of error.
|
||||||
*/
|
*/
|
||||||
(void) _wreaddir_r (dirp, &dirp->ent, &entry);
|
(void) _wreaddir_r (dirp, &dirp->ent, &entry);
|
||||||
|
|
||||||
@ -464,7 +464,7 @@ _wreaddir(
|
|||||||
* Read next directory entry.
|
* Read next directory entry.
|
||||||
*
|
*
|
||||||
* Returns zero on success. If end of directory stream is reached, then sets
|
* Returns zero on success. If end of directory stream is reached, then sets
|
||||||
* result to NULL and returns zero.
|
* result to nullptr and returns zero.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_wreaddir_r(
|
_wreaddir_r(
|
||||||
@ -514,10 +514,8 @@ _wreaddir_r(
|
|||||||
*result = entry;
|
*result = entry;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/* Return nullptr to indicate end of directory */
|
||||||
/* Return NULL to indicate end of directory */
|
*result = nullptr;
|
||||||
*result = NULL;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return /*OK*/0;
|
return /*OK*/0;
|
||||||
@ -585,9 +583,8 @@ dirent_first(
|
|||||||
DWORD error;
|
DWORD error;
|
||||||
|
|
||||||
/* Open directory and retrieve the first entry */
|
/* Open directory and retrieve the first entry */
|
||||||
dirp->handle = FindFirstFileExW(
|
dirp->handle = FindFirstFileExW(dirp->patt, FindExInfoStandard, &dirp->data,
|
||||||
dirp->patt, FindExInfoStandard, &dirp->data,
|
FindExSearchNameMatch, nullptr, 0);
|
||||||
FindExSearchNameMatch, NULL, 0);
|
|
||||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||||
|
|
||||||
/* a directory entry is now waiting in memory */
|
/* a directory entry is now waiting in memory */
|
||||||
@ -598,7 +595,7 @@ dirent_first(
|
|||||||
|
|
||||||
/* Failed to open directory: no directory entry in memory */
|
/* Failed to open directory: no directory entry in memory */
|
||||||
dirp->cached = 0;
|
dirp->cached = 0;
|
||||||
datap = NULL;
|
datap = nullptr;
|
||||||
|
|
||||||
/* Set error code */
|
/* Set error code */
|
||||||
error = GetLastError ();
|
error = GetLastError ();
|
||||||
@ -651,14 +648,13 @@ dirent_next(
|
|||||||
/* The very last entry has been processed or an error occurred */
|
/* The very last entry has been processed or an error occurred */
|
||||||
FindClose (dirp->handle);
|
FindClose (dirp->handle);
|
||||||
dirp->handle = INVALID_HANDLE_VALUE;
|
dirp->handle = INVALID_HANDLE_VALUE;
|
||||||
p = NULL;
|
p = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* End of directory stream reached */
|
/* End of directory stream reached */
|
||||||
p = NULL;
|
p = nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -674,15 +670,15 @@ opendir(
|
|||||||
struct DIR *dirp;
|
struct DIR *dirp;
|
||||||
|
|
||||||
/* Must have directory name */
|
/* Must have directory name */
|
||||||
if (dirname == NULL || dirname[0] == '\0') {
|
if (dirname == nullptr || dirname[0] == '\0') {
|
||||||
dirent_set_errno (ENOENT);
|
dirent_set_errno (ENOENT);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for DIR structure */
|
/* Allocate memory for DIR structure */
|
||||||
dirp = (DIR*) malloc (sizeof (struct DIR));
|
dirp = (DIR*) malloc (sizeof (struct DIR));
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -717,7 +713,7 @@ opendir(
|
|||||||
/* Failure */
|
/* Failure */
|
||||||
exit_free:
|
exit_free:
|
||||||
free (dirp);
|
free (dirp);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -731,7 +727,7 @@ readdir(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Read directory entry to buffer. We can safely ignore the return value
|
* Read directory entry to buffer. We can safely ignore the return value
|
||||||
* as entry will be set to NULL in case of error.
|
* as entry will be set to nullptr in case of error.
|
||||||
*/
|
*/
|
||||||
(void) readdir_r (dirp, &dirp->ent, &entry);
|
(void) readdir_r (dirp, &dirp->ent, &entry);
|
||||||
|
|
||||||
@ -743,7 +739,7 @@ readdir(
|
|||||||
* Read next directory entry into called-allocated buffer.
|
* Read next directory entry into called-allocated buffer.
|
||||||
*
|
*
|
||||||
* Returns zero on success. If the end of directory stream is reached, then
|
* Returns zero on success. If the end of directory stream is reached, then
|
||||||
* sets result to NULL and returns zero.
|
* sets result to nullptr and returns zero.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
readdir_r(
|
readdir_r(
|
||||||
@ -801,11 +797,10 @@ readdir_r(
|
|||||||
entry->d_reclen = sizeof (struct dirent);
|
entry->d_reclen = sizeof (struct dirent);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cannot convert file name to multi-byte string so construct
|
* Cannot convert file name to multi-byte string so construct
|
||||||
* an erroneous directory entry and return that. Note that
|
* an erroneous directory entry and return that. Note that
|
||||||
* we cannot return NULL as that would stop the processing
|
* we cannot return nullptr as that would stop the processing
|
||||||
* of directory entries completely.
|
* of directory entries completely.
|
||||||
*/
|
*/
|
||||||
entry->d_name[0] = '?';
|
entry->d_name[0] = '?';
|
||||||
@ -824,8 +819,7 @@ readdir_r(
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* No more directory entries */
|
/* No more directory entries */
|
||||||
*result = NULL;
|
*result = nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return /*OK*/0;
|
return /*OK*/0;
|
||||||
@ -843,7 +837,7 @@ closedir(
|
|||||||
|
|
||||||
/* Close wide-character directory stream */
|
/* Close wide-character directory stream */
|
||||||
ok = _wclosedir (dirp->wdirp);
|
ok = _wclosedir (dirp->wdirp);
|
||||||
dirp->wdirp = NULL;
|
dirp->wdirp = nullptr;
|
||||||
|
|
||||||
/* Release multi-byte character version */
|
/* Release multi-byte character version */
|
||||||
free (dirp);
|
free (dirp);
|
||||||
@ -879,13 +873,13 @@ scandir(
|
|||||||
int (*filter)(const struct dirent*),
|
int (*filter)(const struct dirent*),
|
||||||
int (*compare)(const struct dirent**, const struct dirent**))
|
int (*compare)(const struct dirent**, const struct dirent**))
|
||||||
{
|
{
|
||||||
struct dirent **files = NULL;
|
struct dirent **files = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
size_t allocated = 0;
|
size_t allocated = 0;
|
||||||
const size_t init_size = 1;
|
const size_t init_size = 1;
|
||||||
DIR *dir = NULL;
|
DIR *dir = nullptr;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
struct dirent *tmp = NULL;
|
struct dirent *tmp = nullptr;
|
||||||
size_t i;
|
size_t i;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
@ -912,7 +906,7 @@ scandir(
|
|||||||
|
|
||||||
/* Allocate first pointer table or enlarge existing table */
|
/* Allocate first pointer table or enlarge existing table */
|
||||||
p = realloc (files, sizeof (void*) * num_entries);
|
p = realloc (files, sizeof (void*) * num_entries);
|
||||||
if (p != NULL) {
|
if (p != nullptr) {
|
||||||
/* Got the memory */
|
/* Got the memory */
|
||||||
files = (dirent**) p;
|
files = (dirent**) p;
|
||||||
allocated = num_entries;
|
allocated = num_entries;
|
||||||
@ -921,13 +915,12 @@ scandir(
|
|||||||
result = -1;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate room for temporary directory entry */
|
/* Allocate room for temporary directory entry */
|
||||||
if (tmp == NULL) {
|
if (tmp == nullptr) {
|
||||||
tmp = (struct dirent*) malloc (sizeof (struct dirent));
|
tmp = (struct dirent*) malloc (sizeof (struct dirent));
|
||||||
if (tmp == NULL) {
|
if (tmp == nullptr) {
|
||||||
/* Cannot allocate temporary directory entry */
|
/* Cannot allocate temporary directory entry */
|
||||||
result = -1;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
@ -938,7 +931,7 @@ scandir(
|
|||||||
if (readdir_r (dir, tmp, &entry) == /*OK*/0) {
|
if (readdir_r (dir, tmp, &entry) == /*OK*/0) {
|
||||||
|
|
||||||
/* Did we get an entry? */
|
/* Did we get an entry? */
|
||||||
if (entry != NULL) {
|
if (entry != nullptr) {
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
/* Determine whether to include the entry in result */
|
/* Determine whether to include the entry in result */
|
||||||
@ -953,14 +946,13 @@ scandir(
|
|||||||
if (pass) {
|
if (pass) {
|
||||||
/* Store the temporary entry to pointer table */
|
/* Store the temporary entry to pointer table */
|
||||||
files[size++] = tmp;
|
files[size++] = tmp;
|
||||||
tmp = NULL;
|
tmp = nullptr;
|
||||||
|
|
||||||
/* Keep up with the number of files */
|
/* Keep up with the number of files */
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of directory stream reached => sort entries and
|
* End of directory stream reached => sort entries and
|
||||||
* exit.
|
* exit.
|
||||||
@ -968,7 +960,6 @@ scandir(
|
|||||||
qsort (files, size, sizeof (void*),
|
qsort (files, size, sizeof (void*),
|
||||||
(int (*) (const void*, const void*)) compare);
|
(int (*) (const void*, const void*)) compare);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -993,7 +984,7 @@ scandir(
|
|||||||
free (files[i]);
|
free (files[i]);
|
||||||
}
|
}
|
||||||
free (files);
|
free (files);
|
||||||
files = NULL;
|
files = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close directory stream */
|
/* Close directory stream */
|
||||||
|
|||||||
@ -36,12 +36,16 @@
|
|||||||
# error You should only be including windows/port.cc in a windows environment!
|
# error You should only be including windows/port.cc in a windows environment!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include <cstdarg> // for va_list, va_start, va_end
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
|
#include <cstdarg> // for va_list, va_start, va_end
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
// These call the windows _vsnprintf, but always NUL-terminate.
|
// These call the windows _vsnprintf, but always NUL-terminate.
|
||||||
int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
int safe_vsnprintf(char* str, std::size_t size, const char* format,
|
||||||
|
va_list ap) {
|
||||||
if (size == 0) // not even room for a \0?
|
if (size == 0) // not even room for a \0?
|
||||||
return -1; // not what C99 says to do, but what windows does
|
return -1; // not what C99 says to do, but what windows does
|
||||||
str[size-1] = '\0';
|
str[size-1] = '\0';
|
||||||
@ -49,15 +53,15 @@ int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifndef HAVE_LOCALTIME_R
|
||||||
struct tm* localtime_r(const time_t* timep, struct tm* result) {
|
struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
|
||||||
localtime_s(result, timep);
|
localtime_s(result, timep);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // not HAVE_LOCALTIME_R
|
#endif // not HAVE_LOCALTIME_R
|
||||||
#ifndef HAVE_GMTIME_R
|
#ifndef HAVE_GMTIME_R
|
||||||
struct tm* gmtime_r(const time_t* timep, struct tm* result) {
|
struct tm* gmtime_r(const std::time_t* timep, std::tm* result) {
|
||||||
gmtime_s(result, timep);
|
gmtime_s(result, timep);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // not HAVE_GMTIME_R
|
#endif // not HAVE_GMTIME_R
|
||||||
#ifndef HAVE_SNPRINTF
|
#ifndef HAVE_SNPRINTF
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Google Inc.
|
/* Copyright (c) 2023, Google Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -158,15 +158,15 @@ enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
|
|||||||
#endif // HAVE_PTHREAD
|
#endif // HAVE_PTHREAD
|
||||||
|
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifndef HAVE_LOCALTIME_R
|
||||||
extern GLOG_EXPORT struct tm* localtime_r(const time_t* timep,
|
extern GLOG_EXPORT std::tm* localtime_r(const std::time_t* timep,
|
||||||
struct tm* result);
|
std::tm* result);
|
||||||
#endif // not HAVE_LOCALTIME_R
|
#endif // not HAVE_LOCALTIME_R
|
||||||
|
|
||||||
#ifndef HAVE_GMTIME_R
|
#ifndef HAVE_GMTIME_R
|
||||||
extern GLOG_EXPORT struct tm* gmtime_r(const time_t* timep, struct tm* result);
|
extern GLOG_EXPORT std::tm* gmtime_r(const std::time_t* timep, std::tm* result);
|
||||||
#endif // not HAVE_GMTIME_R
|
#endif // not HAVE_GMTIME_R
|
||||||
|
|
||||||
inline char* strerror_r(int errnum, char* buf, size_t buflen) {
|
inline char* strerror_r(int errnum, char* buf, std::size_t buflen) {
|
||||||
strerror_s(buf, buflen, errnum);
|
strerror_s(buf, buflen, errnum);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user