fix: better encapsulate internals (#1055)
This commit is contained in:
parent
2b5a53c880
commit
ec455f2cc1
@ -142,6 +142,7 @@ check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
|
|||||||
|
|
||||||
check_cxx_symbol_exists (dladdr dlfcn.h HAVE_DLADDR)
|
check_cxx_symbol_exists (dladdr dlfcn.h HAVE_DLADDR)
|
||||||
check_cxx_symbol_exists (fcntl fcntl.h HAVE_FCNTL)
|
check_cxx_symbol_exists (fcntl fcntl.h HAVE_FCNTL)
|
||||||
|
check_cxx_symbol_exists (posix_fadvise fcntl.h HAVE_POSIX_FADVISE)
|
||||||
check_cxx_symbol_exists (pread unistd.h HAVE_PREAD)
|
check_cxx_symbol_exists (pread unistd.h HAVE_PREAD)
|
||||||
check_cxx_symbol_exists (pwrite unistd.h HAVE_PWRITE)
|
check_cxx_symbol_exists (pwrite unistd.h HAVE_PWRITE)
|
||||||
check_cxx_symbol_exists (sigaction csignal HAVE_SIGACTION)
|
check_cxx_symbol_exists (sigaction csignal HAVE_SIGACTION)
|
||||||
@ -364,6 +365,8 @@ set (GLOG_SRCS
|
|||||||
src/logging.cc
|
src/logging.cc
|
||||||
src/raw_logging.cc
|
src/raw_logging.cc
|
||||||
src/signalhandler.cc
|
src/signalhandler.cc
|
||||||
|
src/stacktrace.cc
|
||||||
|
src/stacktrace.h
|
||||||
src/symbolize.cc
|
src/symbolize.cc
|
||||||
src/symbolize.h
|
src/symbolize.h
|
||||||
src/utilities.cc
|
src/utilities.cc
|
||||||
|
|||||||
@ -48,8 +48,6 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
|
|
||||||
common_copts = [
|
common_copts = [
|
||||||
"-std=c++14",
|
"-std=c++14",
|
||||||
"-DGLOG_BAZEL_BUILD",
|
|
||||||
"-DHAVE_STRING_H",
|
|
||||||
"-I%s/glog_internal" % gendir,
|
"-I%s/glog_internal" % gendir,
|
||||||
] + (["-DGLOG_USE_GFLAGS"] if with_gflags else [])
|
] + (["-DGLOG_USE_GFLAGS"] if with_gflags else [])
|
||||||
|
|
||||||
@ -74,6 +72,7 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
"-DGLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
"-DGLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||||
"-DGLOG_NO_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
"-DGLOG_NO_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||||
"-DHAVE_MODE_T",
|
"-DHAVE_MODE_T",
|
||||||
|
"-DHAVE_POSIX_FADVISE",
|
||||||
"-DHAVE_SSIZE_T",
|
"-DHAVE_SSIZE_T",
|
||||||
"-DHAVE_SYS_TYPES_H",
|
"-DHAVE_SYS_TYPES_H",
|
||||||
# For src/utilities.cc.
|
# For src/utilities.cc.
|
||||||
@ -102,10 +101,11 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
windows_only_copts = [
|
windows_only_copts = [
|
||||||
# Override -DGLOG_EXPORT= from the cc_library's defines.
|
# Override -DGLOG_EXPORT= from the cc_library's defines.
|
||||||
"-DGLOG_EXPORT=__declspec(dllexport)",
|
"-DGLOG_EXPORT=__declspec(dllexport)",
|
||||||
"-DGLOG_NO_EXPORT=",
|
|
||||||
"-DGLOG_NO_ABBREVIATED_SEVERITIES",
|
"-DGLOG_NO_ABBREVIATED_SEVERITIES",
|
||||||
|
"-DGLOG_NO_EXPORT=",
|
||||||
"-DGLOG_USE_WINDOWS_PORT",
|
"-DGLOG_USE_WINDOWS_PORT",
|
||||||
"-DHAVE__CHSIZE_S",
|
"-DHAVE__CHSIZE_S",
|
||||||
|
"-DHAVE_DBGHELP",
|
||||||
"-I" + src_windows,
|
"-I" + src_windows,
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -115,7 +115,6 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
]
|
]
|
||||||
|
|
||||||
windows_only_srcs = [
|
windows_only_srcs = [
|
||||||
"src/glog/log_severity.h",
|
|
||||||
"src/windows/dirent.h",
|
"src/windows/dirent.h",
|
||||||
"src/windows/port.cc",
|
"src/windows/port.cc",
|
||||||
"src/windows/port.h",
|
"src/windows/port.h",
|
||||||
@ -127,13 +126,15 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
# GLOG_EXPORT is normally set by export.h, but that's not
|
# GLOG_EXPORT is normally set by export.h, but that's not
|
||||||
# generated for Bazel.
|
# generated for Bazel.
|
||||||
"@bazel_tools//src/conditions:windows": [
|
"@bazel_tools//src/conditions:windows": [
|
||||||
"GLOG_EXPORT=",
|
|
||||||
"GLOG_DEPRECATED=__declspec(deprecated)",
|
"GLOG_DEPRECATED=__declspec(deprecated)",
|
||||||
|
"GLOG_EXPORT=",
|
||||||
"GLOG_NO_ABBREVIATED_SEVERITIES",
|
"GLOG_NO_ABBREVIATED_SEVERITIES",
|
||||||
|
"GLOG_NO_EXPORT=",
|
||||||
],
|
],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"GLOG_DEPRECATED=__attribute__((deprecated))",
|
"GLOG_DEPRECATED=__attribute__((deprecated))",
|
||||||
"GLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
"GLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||||
|
"GLOG_NO_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -171,6 +172,8 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
"src/logging.cc",
|
"src/logging.cc",
|
||||||
"src/raw_logging.cc",
|
"src/raw_logging.cc",
|
||||||
"src/signalhandler.cc",
|
"src/signalhandler.cc",
|
||||||
|
"src/stacktrace.cc",
|
||||||
|
"src/stacktrace.h",
|
||||||
"src/stacktrace_generic-inl.h",
|
"src/stacktrace_generic-inl.h",
|
||||||
"src/stacktrace_libunwind-inl.h",
|
"src/stacktrace_libunwind-inl.h",
|
||||||
"src/stacktrace_powerpc-inl.h",
|
"src/stacktrace_powerpc-inl.h",
|
||||||
@ -180,6 +183,7 @@ def glog_library(with_gflags = 1, **kwargs):
|
|||||||
"src/symbolize.cc",
|
"src/symbolize.cc",
|
||||||
"src/symbolize.h",
|
"src/symbolize.h",
|
||||||
"src/utilities.cc",
|
"src/utilities.cc",
|
||||||
|
"src/utilities.h",
|
||||||
"src/vlog_is_on.cc",
|
"src/vlog_is_on.cc",
|
||||||
] + select({
|
] + select({
|
||||||
"@bazel_tools//src/conditions:windows": windows_only_srcs,
|
"@bazel_tools//src/conditions:windows": windows_only_srcs,
|
||||||
|
|||||||
@ -31,6 +31,9 @@
|
|||||||
/* Define if you have the 'pread' function */
|
/* Define if you have the 'pread' function */
|
||||||
#cmakedefine HAVE_PREAD
|
#cmakedefine HAVE_PREAD
|
||||||
|
|
||||||
|
/* Define if you have the 'posix_fadvise' function in <fcntl.h> */
|
||||||
|
#cmakedefine HAVE_POSIX_FADVISE
|
||||||
|
|
||||||
/* Define to 1 if you have the <pwd.h> header file. */
|
/* Define to 1 if you have the <pwd.h> header file. */
|
||||||
#cmakedefine HAVE_PWD_H
|
#cmakedefine HAVE_PWD_H
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,6 @@
|
|||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
@ -52,6 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
#if !defined(GLOG_OS_WINDOWS) && !defined(HAVE___CXA_DEMANGLE)
|
#if !defined(GLOG_OS_WINDOWS) && !defined(HAVE___CXA_DEMANGLE)
|
||||||
namespace {
|
namespace {
|
||||||
@ -1359,4 +1359,5 @@ bool Demangle(const char* mangled, char* out, size_t out_size) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -67,19 +67,28 @@
|
|||||||
// C++ ABI in the future.
|
// C++ ABI in the future.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BASE_DEMANGLE_H_
|
#ifndef GLOG_INTERNAL_DEMANGLE_H
|
||||||
#define BASE_DEMANGLE_H_
|
#define GLOG_INTERNAL_DEMANGLE_H
|
||||||
|
|
||||||
#include "config.h"
|
#include <cstddef>
|
||||||
#include "glog/logging.h"
|
|
||||||
|
#if defined(GLOG_USE_GLOG_EXPORT)
|
||||||
|
# include "glog/export.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GLOG_NO_EXPORT)
|
||||||
|
# error "demangle.h" was not included correctly.
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
// Demangle "mangled". On success, return true and write the
|
// Demangle "mangled". On success, return true and write the
|
||||||
// demangled symbol name to "out". Otherwise, return false.
|
// demangled symbol name to "out". Otherwise, return false.
|
||||||
// "out" is modified even if demangling is unsuccessful.
|
// "out" is modified even if demangling is unsuccessful.
|
||||||
bool GLOG_EXPORT Demangle(const char* mangled, char* out, size_t out_size);
|
bool GLOG_NO_EXPORT Demangle(const char* mangled, char* out, size_t out_size);
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
#endif // BASE_DEMANGLE_H_
|
#endif // GLOG_INTERNAL_DEMANGLE_H
|
||||||
|
|||||||
@ -95,8 +95,6 @@ constexpr int NUM_SEVERITIES = 4;
|
|||||||
# define DFATAL_LEVEL FATAL
|
# define DFATAL_LEVEL FATAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern GLOG_EXPORT const char* const LogSeverityNames[NUM_SEVERITIES];
|
|
||||||
|
|
||||||
// NDEBUG usage helpers related to (RAW_)DCHECK:
|
// NDEBUG usage helpers related to (RAW_)DCHECK:
|
||||||
//
|
//
|
||||||
// DEBUG_MODE is for small !NDEBUG uses like
|
// DEBUG_MODE is for small !NDEBUG uses like
|
||||||
|
|||||||
@ -56,7 +56,7 @@
|
|||||||
# include "glog/export.h"
|
# include "glog/export.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(GLOG_EXPORT)
|
#if !defined(GLOG_EXPORT) || !defined(GLOG_NO_EXPORT)
|
||||||
# error <glog/logging.h> was not included correctly. See the documention for how to consume the library.
|
# error <glog/logging.h> was not included correctly. See the documention for how to consume the library.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -580,13 +580,16 @@ class LogSink; // defined below
|
|||||||
LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
|
LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
|
||||||
<< "Check failed: " #condition " "
|
<< "Check failed: " #condition " "
|
||||||
|
|
||||||
|
namespace logging {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
// A container for a string pointer which can be evaluated to a bool -
|
// A container for a string pointer which can be evaluated to a bool -
|
||||||
// true iff the pointer is nullptr.
|
// true iff the pointer is nullptr.
|
||||||
struct CheckOpString {
|
struct CheckOpString {
|
||||||
CheckOpString(std::string* str) : str_(str) {}
|
CheckOpString(std::string* str) : str_(str) {}
|
||||||
// No destructor: if str_ is non-nullptr, we're about to LOG(FATAL),
|
// No destructor: if str_ is non-nullptr, we're about to LOG(FATAL),
|
||||||
// so there's no point in cleaning up str_.
|
// so there's no point in cleaning up str_.
|
||||||
operator bool() const {
|
explicit operator bool() const noexcept {
|
||||||
return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != nullptr);
|
return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != nullptr);
|
||||||
}
|
}
|
||||||
std::string* str_;
|
std::string* str_;
|
||||||
@ -616,18 +619,14 @@ inline unsigned long long GetReferenceableValue(unsigned long long t) {
|
|||||||
// This is a dummy class to define the following operator.
|
// This is a dummy class to define the following operator.
|
||||||
struct DummyClassToDefineOperator {};
|
struct DummyClassToDefineOperator {};
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
|
|
||||||
// Define global operator<< to declare using ::operator<<.
|
// Define global operator<< to declare using ::operator<<.
|
||||||
// This declaration will allow use to use CHECK macros for user
|
// This declaration will allow use to use CHECK macros for user
|
||||||
// defined classes which have operator<< (e.g., stl_logging.h).
|
// defined classes which have operator<< (e.g., stl_logging.h).
|
||||||
inline std::ostream& operator<<(std::ostream& out,
|
inline std::ostream& operator<<(std::ostream& out,
|
||||||
const google::DummyClassToDefineOperator&) {
|
const DummyClassToDefineOperator&) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace google {
|
|
||||||
|
|
||||||
// This formats a value for a failing CHECK_XX statement. Ordinarily,
|
// This formats a value for a failing CHECK_XX statement. Ordinarily,
|
||||||
// it uses the definition for operator<<, with a few special cases below.
|
// it uses the definition for operator<<, with a few special cases below.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -660,8 +659,6 @@ std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
namespace base {
|
|
||||||
|
|
||||||
// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
|
// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
|
||||||
// statement. See MakeCheckOpString for sample usage. Other
|
// statement. See MakeCheckOpString for sample usage. Other
|
||||||
// approaches were considered: use of a template method (e.g.,
|
// approaches were considered: use of a template method (e.g.,
|
||||||
@ -685,12 +682,10 @@ class GLOG_EXPORT CheckOpMessageBuilder {
|
|||||||
std::ostringstream* stream_;
|
std::ostringstream* stream_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace base
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
std::string* MakeCheckOpString(const T1& v1, const T2& v2,
|
std::string* MakeCheckOpString(const T1& v1, const T2& v2,
|
||||||
const char* exprtext) {
|
const char* exprtext) {
|
||||||
base::CheckOpMessageBuilder comb(exprtext);
|
CheckOpMessageBuilder comb(exprtext);
|
||||||
MakeCheckOpValueString(comb.ForVar1(), v1);
|
MakeCheckOpValueString(comb.ForVar1(), v1);
|
||||||
MakeCheckOpValueString(comb.ForVar2(), v2);
|
MakeCheckOpValueString(comb.ForVar2(), v2);
|
||||||
return comb.NewString();
|
return comb.NewString();
|
||||||
@ -717,13 +712,13 @@ std::string* MakeCheckOpString(const T1& v1, const T2& v2,
|
|||||||
// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
|
// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
|
||||||
// This happens if, for example, those are used as token names in a
|
// This happens if, for example, those are used as token names in a
|
||||||
// yacc grammar.
|
// yacc grammar.
|
||||||
DEFINE_CHECK_OP_IMPL(Check_EQ,
|
DEFINE_CHECK_OP_IMPL(Check_EQ, ==)
|
||||||
==) // Compilation error with CHECK_EQ(nullptr, x)?
|
DEFINE_CHECK_OP_IMPL(Check_NE, !=)
|
||||||
DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == nullptr) instead.
|
|
||||||
DEFINE_CHECK_OP_IMPL(Check_LE, <=)
|
DEFINE_CHECK_OP_IMPL(Check_LE, <=)
|
||||||
DEFINE_CHECK_OP_IMPL(Check_LT, <)
|
DEFINE_CHECK_OP_IMPL(Check_LT, <)
|
||||||
DEFINE_CHECK_OP_IMPL(Check_GE, >=)
|
DEFINE_CHECK_OP_IMPL(Check_GE, >=)
|
||||||
DEFINE_CHECK_OP_IMPL(Check_GT, >)
|
DEFINE_CHECK_OP_IMPL(Check_GT, >)
|
||||||
|
|
||||||
#undef DEFINE_CHECK_OP_IMPL
|
#undef DEFINE_CHECK_OP_IMPL
|
||||||
|
|
||||||
// Helper macro for binary operators.
|
// Helper macro for binary operators.
|
||||||
@ -744,17 +739,22 @@ DEFINE_CHECK_OP_IMPL(Check_GT, >)
|
|||||||
// in the macro.
|
// in the macro.
|
||||||
typedef std::string _Check_string;
|
typedef std::string _Check_string;
|
||||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||||
while (google::_Check_string* _result = google::Check##name##Impl( \
|
while (google::logging::internal::_Check_string* _result = \
|
||||||
google::GetReferenceableValue(val1), \
|
google::logging::internal::Check##name##Impl( \
|
||||||
google::GetReferenceableValue(val2), #val1 " " #op " " #val2)) \
|
google::logging::internal::GetReferenceableValue(val1), \
|
||||||
log(__FILE__, __LINE__, google::CheckOpString(_result)).stream()
|
google::logging::internal::GetReferenceableValue(val2), \
|
||||||
|
#val1 " " #op " " #val2)) \
|
||||||
|
log(__FILE__, __LINE__, google::logging::internal::CheckOpString(_result)) \
|
||||||
|
.stream()
|
||||||
#else
|
#else
|
||||||
// In optimized mode, use CheckOpString to hint to compiler that
|
// In optimized mode, use CheckOpString to hint to compiler that
|
||||||
// the while condition is unlikely.
|
// the while condition is unlikely.
|
||||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||||
while (google::CheckOpString _result = google::Check##name##Impl( \
|
while (google::logging::internal::CheckOpString _result = \
|
||||||
google::GetReferenceableValue(val1), \
|
google::logging::internal::Check##name##Impl( \
|
||||||
google::GetReferenceableValue(val2), #val1 " " #op " " #val2)) \
|
google::logging::internal::GetReferenceableValue(val1), \
|
||||||
|
google::logging::internal::GetReferenceableValue(val2), \
|
||||||
|
#val1 " " #op " " #val2)) \
|
||||||
log(__FILE__, __LINE__, _result).stream()
|
log(__FILE__, __LINE__, _result).stream()
|
||||||
#endif // STATIC_ANALYSIS, DCHECK_IS_ON()
|
#endif // STATIC_ANALYSIS, DCHECK_IS_ON()
|
||||||
|
|
||||||
@ -795,24 +795,30 @@ typedef std::string _Check_string;
|
|||||||
// initializer lists.
|
// initializer lists.
|
||||||
|
|
||||||
#define CHECK_NOTNULL(val) \
|
#define CHECK_NOTNULL(val) \
|
||||||
google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non nullptr", \
|
google::logging::internal::CheckNotNull( \
|
||||||
(val))
|
__FILE__, __LINE__, "'" #val "' Must be non nullptr", (val))
|
||||||
|
|
||||||
// Helper functions for string comparisons.
|
// Helper functions for string comparisons.
|
||||||
// To avoid bloat, the definitions are in logging.cc.
|
// To avoid bloat, the definitions are in logging.cc.
|
||||||
#define DECLARE_CHECK_STROP_IMPL(func, expected) \
|
#define DECLARE_CHECK_STROP_IMPL(func, expected) \
|
||||||
GLOG_EXPORT std::string* Check##func##expected##Impl( \
|
GLOG_EXPORT std::string* Check##func##expected##Impl( \
|
||||||
const char* s1, const char* s2, const char* names);
|
const char* s1, const char* s2, const char* names);
|
||||||
|
|
||||||
DECLARE_CHECK_STROP_IMPL(strcmp, true)
|
DECLARE_CHECK_STROP_IMPL(strcmp, true)
|
||||||
DECLARE_CHECK_STROP_IMPL(strcmp, false)
|
DECLARE_CHECK_STROP_IMPL(strcmp, false)
|
||||||
DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
|
DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
|
||||||
DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
|
DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace logging
|
||||||
|
|
||||||
#undef DECLARE_CHECK_STROP_IMPL
|
#undef DECLARE_CHECK_STROP_IMPL
|
||||||
|
|
||||||
// Helper macro for string comparisons.
|
// Helper macro for string comparisons.
|
||||||
// Don't use this macro directly in your code, use CHECK_STREQ et al below.
|
// Don't use this macro directly in your code, use CHECK_STREQ et al below.
|
||||||
#define CHECK_STROP(func, op, expected, s1, s2) \
|
#define CHECK_STROP(func, op, expected, s1, s2) \
|
||||||
while (google::CheckOpString _result = google::Check##func##expected##Impl( \
|
while (google::logging::internal::CheckOpString _result = \
|
||||||
|
google::logging::internal::Check##func##expected##Impl( \
|
||||||
(s1), (s2), #s1 " " #op " " #s2)) \
|
(s1), (s2), #s1 " " #op " " #s2)) \
|
||||||
LOG(FATAL) << *_result.str_
|
LOG(FATAL) << *_result.str_
|
||||||
|
|
||||||
@ -1181,6 +1187,12 @@ class GLOG_EXPORT LogStreamBuf : public std::streambuf {
|
|||||||
|
|
||||||
} // namespace base_logging
|
} // namespace base_logging
|
||||||
|
|
||||||
|
namespace logging {
|
||||||
|
namespace internal {
|
||||||
|
struct GLOG_NO_EXPORT LogMessageData;
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace logging
|
||||||
|
|
||||||
//
|
//
|
||||||
// This class more or less represents a particular log message. You
|
// This class more or less represents a particular log message. You
|
||||||
// create an instance of LogMessage and then stream stuff to it.
|
// create an instance of LogMessage and then stream stuff to it.
|
||||||
@ -1297,7 +1309,8 @@ class GLOG_EXPORT LogMessage {
|
|||||||
std::string* message);
|
std::string* message);
|
||||||
|
|
||||||
// A special constructor used for check failures
|
// A special constructor used for check failures
|
||||||
LogMessage(const char* file, int line, const CheckOpString& result);
|
LogMessage(const char* file, int line,
|
||||||
|
const logging::internal::CheckOpString& result);
|
||||||
|
|
||||||
~LogMessage();
|
~LogMessage();
|
||||||
|
|
||||||
@ -1355,8 +1368,8 @@ class GLOG_EXPORT LogMessage {
|
|||||||
|
|
||||||
// We keep the data in a separate struct so that each instance of
|
// We keep the data in a separate struct so that each instance of
|
||||||
// LogMessage uses less stack space.
|
// LogMessage uses less stack space.
|
||||||
LogMessageData* allocated_;
|
logging::internal::LogMessageData* allocated_;
|
||||||
LogMessageData* data_;
|
logging::internal::LogMessageData* data_;
|
||||||
LogMessageTime time_;
|
LogMessageTime time_;
|
||||||
|
|
||||||
friend class LogDestination;
|
friend class LogDestination;
|
||||||
@ -1371,7 +1384,8 @@ class GLOG_EXPORT LogMessage {
|
|||||||
class GLOG_EXPORT LogMessageFatal : public LogMessage {
|
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 logging::internal::CheckOpString& result);
|
||||||
[[noreturn]] ~LogMessageFatal();
|
[[noreturn]] ~LogMessageFatal();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1388,22 +1402,6 @@ inline void LogAtLevel(LogSeverity severity, std::string const& msg) {
|
|||||||
#define LOG_AT_LEVEL(severity) \
|
#define LOG_AT_LEVEL(severity) \
|
||||||
google::LogMessage(__FILE__, __LINE__, severity).stream()
|
google::LogMessage(__FILE__, __LINE__, severity).stream()
|
||||||
|
|
||||||
// Helper for CHECK_NOTNULL().
|
|
||||||
//
|
|
||||||
// In C++11, all cases can be handled by a single function. Since the value
|
|
||||||
// category of the argument is preserved (also for rvalue references),
|
|
||||||
// member initializer lists like the one below will compile correctly:
|
|
||||||
//
|
|
||||||
// Foo()
|
|
||||||
// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {}
|
|
||||||
template <typename T>
|
|
||||||
T CheckNotNull(const char* file, int line, const char* names, T&& t) {
|
|
||||||
if (t == nullptr) {
|
|
||||||
LogMessageFatal(file, line, new std::string(names));
|
|
||||||
}
|
|
||||||
return std::forward<T>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
||||||
@ -1429,13 +1427,29 @@ class GLOG_EXPORT ErrnoLogMessage : public LogMessage {
|
|||||||
|
|
||||||
namespace logging {
|
namespace logging {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
class LogMessageVoidify {
|
|
||||||
public:
|
// Helper for CHECK_NOTNULL().
|
||||||
LogMessageVoidify() {}
|
//
|
||||||
|
// In C++11, all cases can be handled by a single function. Since the value
|
||||||
|
// category of the argument is preserved (also for rvalue references),
|
||||||
|
// member initializer lists like the one below will compile correctly:
|
||||||
|
//
|
||||||
|
// Foo()
|
||||||
|
// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {}
|
||||||
|
template <typename T>
|
||||||
|
T CheckNotNull(const char* file, int line, const char* names, T&& t) {
|
||||||
|
if (t == nullptr) {
|
||||||
|
LogMessageFatal(file, line, new std::string(names));
|
||||||
|
}
|
||||||
|
return std::forward<T>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LogMessageVoidify {
|
||||||
// This has to be an operator with a precedence lower than << but
|
// This has to be an operator with a precedence lower than << but
|
||||||
// higher than ?:
|
// higher than ?:
|
||||||
void operator&(std::ostream&) {}
|
void operator&(std::ostream&) noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace logging
|
} // namespace logging
|
||||||
|
|
||||||
@ -1637,7 +1651,7 @@ class GLOG_EXPORT NullStream : public LogMessage::LogStream {
|
|||||||
// the overloaded NullStream::operator<< will not be invoked.
|
// the overloaded NullStream::operator<< will not be invoked.
|
||||||
NullStream();
|
NullStream();
|
||||||
NullStream(const char* /*file*/, int /*line*/,
|
NullStream(const char* /*file*/, int /*line*/,
|
||||||
const CheckOpString& /*result*/);
|
const logging::internal::CheckOpString& /*result*/);
|
||||||
NullStream& stream();
|
NullStream& stream();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -52,6 +52,8 @@
|
|||||||
# define GLOG_OS_OPENBSD
|
# define GLOG_OS_OPENBSD
|
||||||
#elif defined(__EMSCRIPTEN__)
|
#elif defined(__EMSCRIPTEN__)
|
||||||
# define GLOG_OS_EMSCRIPTEN
|
# define GLOG_OS_EMSCRIPTEN
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define GLOG_OS_ANDROID
|
||||||
#else
|
#else
|
||||||
// TODO(hamaji): Add other platforms.
|
// TODO(hamaji): Add other platforms.
|
||||||
#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
|
#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
|
||||||
|
|||||||
@ -51,12 +51,16 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "config.h"
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLOG_USE_WINDOWS_PORT)
|
||||||
|
# include "port.h"
|
||||||
|
#endif // defined(GLOG_USE_WINDOWS_PORT)
|
||||||
#include "base/commandlineflags.h"
|
#include "base/commandlineflags.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
#if __cplusplus < 201103L && !defined(_MSC_VER)
|
#if __cplusplus < 201103L && !defined(_MSC_VER)
|
||||||
# define GOOGLE_GLOG_THROW_BAD_ALLOC throw(std::bad_alloc)
|
# define GOOGLE_GLOG_THROW_BAD_ALLOC throw(std::bad_alloc)
|
||||||
@ -339,20 +343,20 @@ class CapturedStream {
|
|||||||
uncaptured_fd_; // where the stream was originally being sent to
|
uncaptured_fd_; // 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 std::unique_ptr<CapturedStream> s_captured_streams[STDERR_FILENO + 1];
|
static std::map<int, std::unique_ptr<CapturedStream>> s_captured_streams;
|
||||||
// Redirect a file descriptor to a file.
|
// Redirect a file descriptor to a file.
|
||||||
// fd - Should be STDOUT_FILENO or STDERR_FILENO
|
// fd - Should be stdout or stderr
|
||||||
// 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 == fileno(stdout)) || (fd == fileno(stderr)));
|
||||||
CHECK(s_captured_streams[fd] == nullptr);
|
CHECK(s_captured_streams.find(fd) == s_captured_streams.end());
|
||||||
s_captured_streams[fd] = std::make_unique<CapturedStream>(fd, filename);
|
s_captured_streams[fd] = std::make_unique<CapturedStream>(fd, filename);
|
||||||
}
|
}
|
||||||
static inline void CaptureTestStdout() {
|
static inline void CaptureTestStdout() {
|
||||||
CaptureTestOutput(STDOUT_FILENO, FLAGS_test_tmpdir + "/captured.out");
|
CaptureTestOutput(fileno(stdout), FLAGS_test_tmpdir + "/captured.out");
|
||||||
}
|
}
|
||||||
static inline void CaptureTestStderr() {
|
static inline void CaptureTestStderr() {
|
||||||
CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
|
CaptureTestOutput(fileno(stderr), FLAGS_test_tmpdir + "/captured.err");
|
||||||
}
|
}
|
||||||
// Return the size (in bytes) of a file
|
// Return the size (in bytes) of a file
|
||||||
static inline size_t GetFileSize(FILE* file) {
|
static inline size_t GetFileSize(FILE* file) {
|
||||||
@ -379,11 +383,11 @@ static inline string ReadEntireFile(FILE* file) {
|
|||||||
|
|
||||||
return std::string(content.data(), bytes_read);
|
return std::string(content.data(), bytes_read);
|
||||||
}
|
}
|
||||||
// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
|
// Get the captured stdout or stderr as a string
|
||||||
// fd is STDERR_FILENO) as a string
|
|
||||||
static inline string GetCapturedTestOutput(int fd) {
|
static inline string GetCapturedTestOutput(int fd) {
|
||||||
CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
|
CHECK((fd == fileno(stdout)) || (fd == fileno(stderr)));
|
||||||
std::unique_ptr<CapturedStream> cap = std::move(s_captured_streams[fd]);
|
std::unique_ptr<CapturedStream> cap = std::move(s_captured_streams.at(fd));
|
||||||
|
s_captured_streams.erase(fd);
|
||||||
CHECK(cap) << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
|
CHECK(cap) << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
|
||||||
|
|
||||||
// Make sure everything is flushed.
|
// Make sure everything is flushed.
|
||||||
@ -398,7 +402,7 @@ static inline string GetCapturedTestOutput(int fd) {
|
|||||||
}
|
}
|
||||||
// Get the captured stderr of a test as a string.
|
// Get the captured stderr of a test as a string.
|
||||||
static inline string GetCapturedTestStderr() {
|
static inline string GetCapturedTestStderr() {
|
||||||
return GetCapturedTestOutput(STDERR_FILENO);
|
return GetCapturedTestOutput(fileno(stderr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::size_t kLoggingPrefixLength = 9;
|
static const std::size_t kLoggingPrefixLength = 9;
|
||||||
@ -499,7 +503,9 @@ static inline void WriteToFile(const string& body, const string& file) {
|
|||||||
|
|
||||||
static inline bool MungeAndDiffTest(const string& golden_filename,
|
static inline bool MungeAndDiffTest(const string& golden_filename,
|
||||||
CapturedStream* cap) {
|
CapturedStream* cap) {
|
||||||
if (cap == s_captured_streams[STDOUT_FILENO].get()) {
|
auto pos = s_captured_streams.find(fileno(stdout));
|
||||||
|
|
||||||
|
if (pos != s_captured_streams.end() && cap == pos->second.get()) {
|
||||||
CHECK(cap) << ": did you forget CaptureTestStdout()?";
|
CHECK(cap) << ": did you forget CaptureTestStdout()?";
|
||||||
} else {
|
} else {
|
||||||
CHECK(cap) << ": did you forget CaptureTestStderr()?";
|
CHECK(cap) << ": did you forget CaptureTestStderr()?";
|
||||||
@ -535,12 +541,12 @@ static inline bool MungeAndDiffTest(const string& golden_filename,
|
|||||||
|
|
||||||
static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
|
static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
|
||||||
return MungeAndDiffTest(golden_filename,
|
return MungeAndDiffTest(golden_filename,
|
||||||
s_captured_streams[STDERR_FILENO].get());
|
s_captured_streams.at(fileno(stderr)).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool MungeAndDiffTestStdout(const string& golden_filename) {
|
static inline bool MungeAndDiffTestStdout(const string& golden_filename) {
|
||||||
return MungeAndDiffTest(golden_filename,
|
return MungeAndDiffTest(golden_filename,
|
||||||
s_captured_streams[STDOUT_FILENO].get());
|
s_captured_streams.at(fileno(stdout)).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save flags used from logging_unittest.cc.
|
// Save flags used from logging_unittest.cc.
|
||||||
|
|||||||
@ -48,12 +48,10 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "glog/platform.h"
|
||||||
#include "glog/raw_logging.h"
|
#include "glog/raw_logging.h"
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_STACKTRACE
|
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
#endif
|
#include "utilities.h"
|
||||||
|
|
||||||
#ifdef GLOG_OS_WINDOWS
|
#ifdef GLOG_OS_WINDOWS
|
||||||
# include "windows/dirent.h"
|
# include "windows/dirent.h"
|
||||||
@ -217,6 +215,7 @@ static bool TerminalSupportsColor() {
|
|||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
|
||||||
|
GLOG_NO_EXPORT
|
||||||
std::string StrError(int err);
|
std::string StrError(int err);
|
||||||
|
|
||||||
enum GLogColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
|
enum GLogColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
|
||||||
@ -283,13 +282,15 @@ static uint32 MaxLogSize() {
|
|||||||
// is so that streaming can be done more efficiently.
|
// is so that streaming can be done more efficiently.
|
||||||
const size_t LogMessage::kMaxLogMessageLen = 30000;
|
const size_t LogMessage::kMaxLogMessageLen = 30000;
|
||||||
|
|
||||||
struct LogMessage::LogMessageData {
|
namespace logging {
|
||||||
|
namespace internal {
|
||||||
|
struct LogMessageData {
|
||||||
LogMessageData();
|
LogMessageData();
|
||||||
|
|
||||||
int preserved_errno_; // preserved errno
|
int preserved_errno_; // preserved errno
|
||||||
// Buffer space; contains complete message text.
|
// Buffer space; contains complete message text.
|
||||||
char message_text_[LogMessage::kMaxLogMessageLen + 1];
|
char message_text_[LogMessage::kMaxLogMessageLen + 1];
|
||||||
LogStream stream_;
|
LogMessage::LogStream stream_;
|
||||||
LogSeverity severity_; // What level is this LogMessage logged at?
|
LogSeverity severity_; // What level is this LogMessage logged at?
|
||||||
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
|
||||||
@ -311,6 +312,8 @@ struct LogMessage::LogMessageData {
|
|||||||
LogMessageData(const LogMessageData&) = delete;
|
LogMessageData(const LogMessageData&) = delete;
|
||||||
void operator=(const LogMessageData&) = delete;
|
void operator=(const LogMessageData&) = delete;
|
||||||
};
|
};
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace logging
|
||||||
|
|
||||||
// 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
|
||||||
// getting jumbled. Some other very uncommon logging operations (like
|
// getting jumbled. Some other very uncommon logging operations (like
|
||||||
@ -325,8 +328,7 @@ int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0};
|
|||||||
// Globally disable log writing (if disk is full)
|
// Globally disable log writing (if disk is full)
|
||||||
static bool stop_writing = false;
|
static bool stop_writing = false;
|
||||||
|
|
||||||
const char* const LogSeverityNames[NUM_SEVERITIES] = {"INFO", "WARNING",
|
const char* const LogSeverityNames[] = {"INFO", "WARNING", "ERROR", "FATAL"};
|
||||||
"ERROR", "FATAL"};
|
|
||||||
|
|
||||||
// Has the user called SetExitOnDFatal(true)?
|
// Has the user called SetExitOnDFatal(true)?
|
||||||
static bool exit_on_dfatal = true;
|
static bool exit_on_dfatal = true;
|
||||||
@ -547,7 +549,7 @@ class LogDestination {
|
|||||||
|
|
||||||
// Wait for all registered sinks via WaitTillSent
|
// Wait for all registered sinks via WaitTillSent
|
||||||
// including the optional one in "data".
|
// including the optional one in "data".
|
||||||
static void WaitForSinks(LogMessage::LogMessageData* data);
|
static void WaitForSinks(logging::internal::LogMessageData* data);
|
||||||
|
|
||||||
static LogDestination* log_destination(LogSeverity severity);
|
static LogDestination* log_destination(LogSeverity severity);
|
||||||
|
|
||||||
@ -854,7 +856,8 @@ inline void LogDestination::LogToSinks(LogSeverity severity,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
|
inline void LogDestination::WaitForSinks(
|
||||||
|
logging::internal::LogMessageData* data) {
|
||||||
std::shared_lock<SinkMutex> l{sink_mutex_};
|
std::shared_lock<SinkMutex> l{sink_mutex_};
|
||||||
if (sinks_) {
|
if (sinks_) {
|
||||||
for (size_t i = sinks_->size(); i-- > 0;) {
|
for (size_t i = sinks_->size(); i-- > 0;) {
|
||||||
@ -1266,10 +1269,7 @@ void LogFileObject::Write(
|
|||||||
uint32 this_drop_length = total_drop_length - dropped_mem_length_;
|
uint32 this_drop_length = total_drop_length - dropped_mem_length_;
|
||||||
if (this_drop_length >= (2U << 20U)) {
|
if (this_drop_length >= (2U << 20U)) {
|
||||||
// Only advise when >= 2MiB to drop
|
// Only advise when >= 2MiB to drop
|
||||||
# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
|
# if defined(HAVE_POSIX_FADVISE)
|
||||||
// 'posix_fadvise' introduced in API 21:
|
|
||||||
// * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732
|
|
||||||
# else
|
|
||||||
posix_fadvise(
|
posix_fadvise(
|
||||||
fileno(file_.get()), static_cast<off_t>(dropped_mem_length_),
|
fileno(file_.get()), static_cast<off_t>(dropped_mem_length_),
|
||||||
static_cast<off_t>(this_drop_length), POSIX_FADV_DONTNEED);
|
static_cast<off_t>(this_drop_length), POSIX_FADV_DONTNEED);
|
||||||
@ -1488,8 +1488,8 @@ bool LogCleaner::IsLogLastModifiedOver(
|
|||||||
static std::mutex fatal_msg_lock;
|
static std::mutex fatal_msg_lock;
|
||||||
static logging::internal::CrashReason crash_reason;
|
static logging::internal::CrashReason crash_reason;
|
||||||
static bool fatal_msg_exclusive = true;
|
static bool fatal_msg_exclusive = true;
|
||||||
static LogMessage::LogMessageData fatal_msg_data_exclusive;
|
static logging::internal::LogMessageData fatal_msg_data_exclusive;
|
||||||
static LogMessage::LogMessageData fatal_msg_data_shared;
|
static logging::internal::LogMessageData fatal_msg_data_shared;
|
||||||
|
|
||||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||||
// 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
|
||||||
@ -1499,16 +1499,16 @@ static thread_local bool thread_data_available = true;
|
|||||||
|
|
||||||
# if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
# if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||||
// std::aligned_storage is deprecated in C++23
|
// std::aligned_storage is deprecated in C++23
|
||||||
alignas(LogMessage::LogMessageData) static thread_local std::byte
|
alignas(logging::internal::LogMessageData) static thread_local std::byte
|
||||||
thread_msg_data[sizeof(LogMessage::LogMessageData)];
|
thread_msg_data[sizeof(logging::internal::LogMessageData)];
|
||||||
# else // !(defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L)
|
# else // !(defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L)
|
||||||
static thread_local std::aligned_storage<
|
static thread_local std::aligned_storage<
|
||||||
sizeof(LogMessage::LogMessageData),
|
sizeof(logging::internal::LogMessageData),
|
||||||
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
|
alignof(logging::internal::LogMessageData)>::type thread_msg_data;
|
||||||
# endif // defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
# endif // defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||||
|
|
||||||
LogMessage::LogMessageData::LogMessageData()
|
logging::internal::LogMessageData::LogMessageData()
|
||||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {}
|
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||||
@ -1518,7 +1518,8 @@ LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
|||||||
data_->stream_.set_ctr(ctr);
|
data_->stream_.set_ctr(ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
|
LogMessage::LogMessage(const char* file, int line,
|
||||||
|
const logging::internal::CheckOpString& result)
|
||||||
: allocated_(nullptr) {
|
: allocated_(nullptr) {
|
||||||
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
|
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
|
||||||
stream() << "Check failed: " << (*result.str_) << " ";
|
stream() << "Check failed: " << (*result.str_) << " ";
|
||||||
@ -1564,13 +1565,13 @@ void LogMessage::Init(const char* file, int line, LogSeverity severity,
|
|||||||
// 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;
|
||||||
data_ = new (&thread_msg_data) LogMessageData;
|
data_ = new (&thread_msg_data) logging::internal::LogMessageData;
|
||||||
} else {
|
} else {
|
||||||
allocated_ = new LogMessageData();
|
allocated_ = new logging::internal::LogMessageData();
|
||||||
data_ = allocated_;
|
data_ = allocated_;
|
||||||
}
|
}
|
||||||
#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
|
#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||||
allocated_ = new LogMessageData();
|
allocated_ = new logging::internal::LogMessageData();
|
||||||
data_ = allocated_;
|
data_ = allocated_;
|
||||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||||
data_->first_fatal_ = false;
|
data_->first_fatal_ = false;
|
||||||
@ -1828,7 +1829,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
|||||||
LogDestination::WaitForSinks(data_);
|
LogDestination::WaitForSinks(data_);
|
||||||
|
|
||||||
const char* message = "*** Check failure stack trace: ***\n";
|
const char* message = "*** Check failure stack trace: ***\n";
|
||||||
if (write(STDERR_FILENO, message, strlen(message)) < 0) {
|
if (write(fileno(stderr), message, strlen(message)) < 0) {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
AlsoErrorWrite(GLOG_FATAL,
|
AlsoErrorWrite(GLOG_FATAL,
|
||||||
@ -1856,7 +1857,7 @@ GLOG_NO_EXPORT logging_fail_func_t g_logging_fail_func =
|
|||||||
|
|
||||||
NullStream::NullStream() : LogMessage::LogStream(message_buffer_, 2, 0) {}
|
NullStream::NullStream() : LogMessage::LogStream(message_buffer_, 2, 0) {}
|
||||||
NullStream::NullStream(const char* /*file*/, int /*line*/,
|
NullStream::NullStream(const char* /*file*/, int /*line*/,
|
||||||
const CheckOpString& /*result*/)
|
const logging::internal::CheckOpString& /*result*/)
|
||||||
: LogMessage::LogStream(message_buffer_, 2, 0) {}
|
: LogMessage::LogStream(message_buffer_, 2, 0) {}
|
||||||
NullStream& NullStream::stream() { return *this; }
|
NullStream& NullStream::stream() { return *this; }
|
||||||
|
|
||||||
@ -2455,6 +2456,8 @@ void TruncateStdoutStderr() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace logging {
|
||||||
|
namespace internal {
|
||||||
// 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, \
|
||||||
@ -2475,6 +2478,8 @@ DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
|
|||||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
|
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
|
||||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
|
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
|
||||||
#undef DEFINE_CHECK_STROP_IMPL
|
#undef DEFINE_CHECK_STROP_IMPL
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace logging
|
||||||
|
|
||||||
// glibc has traditionally implemented two incompatible versions of
|
// glibc has traditionally implemented two incompatible versions of
|
||||||
// strerror_r(). There is a poorly defined convention for picking the
|
// strerror_r(). There is a poorly defined convention for picking the
|
||||||
@ -2541,7 +2546,6 @@ int posix_strerror_r(int err, char* buf, size_t len) {
|
|||||||
|
|
||||||
// A thread-safe replacement for strerror(). Returns a string describing the
|
// A thread-safe replacement for strerror(). Returns a string describing the
|
||||||
// given POSIX error code.
|
// given POSIX error code.
|
||||||
GLOG_NO_EXPORT
|
|
||||||
string StrError(int err) {
|
string StrError(int err) {
|
||||||
char buf[100];
|
char buf[100];
|
||||||
int rc = posix_strerror_r(err, buf, sizeof(buf));
|
int rc = posix_strerror_r(err, buf, sizeof(buf));
|
||||||
@ -2555,7 +2559,7 @@ LogMessageFatal::LogMessageFatal(const char* file, int line)
|
|||||||
: LogMessage(file, line, GLOG_FATAL) {}
|
: LogMessage(file, line, GLOG_FATAL) {}
|
||||||
|
|
||||||
LogMessageFatal::LogMessageFatal(const char* file, int line,
|
LogMessageFatal::LogMessageFatal(const char* file, int line,
|
||||||
const CheckOpString& result)
|
const logging::internal::CheckOpString& result)
|
||||||
: LogMessage(file, line, result) {}
|
: LogMessage(file, line, result) {}
|
||||||
|
|
||||||
LogMessageFatal::~LogMessageFatal() {
|
LogMessageFatal::~LogMessageFatal() {
|
||||||
@ -2563,7 +2567,8 @@ LogMessageFatal::~LogMessageFatal() {
|
|||||||
LogMessage::Fail();
|
LogMessage::Fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace base {
|
namespace logging {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext)
|
CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext)
|
||||||
: stream_(new ostringstream) {
|
: stream_(new ostringstream) {
|
||||||
@ -2582,8 +2587,6 @@ string* CheckOpMessageBuilder::NewString() {
|
|||||||
return new string(stream_->str());
|
return new string(stream_->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void MakeCheckOpValueString(std::ostream* os, const char& v) {
|
void MakeCheckOpValueString(std::ostream* os, const char& v) {
|
||||||
if (v >= 32 && v <= 126) {
|
if (v >= 32 && v <= 126) {
|
||||||
@ -2616,9 +2619,10 @@ void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
|
|||||||
(*os) << "nullptr";
|
(*os) << "nullptr";
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitGoogleLogging(const char* argv0) {
|
} // namespace internal
|
||||||
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
|
} // namespace logging
|
||||||
}
|
|
||||||
|
void InitGoogleLogging(const char* argv0) { InitGoogleLoggingUtilities(argv0); }
|
||||||
|
|
||||||
void InitGoogleLogging(const char* argv0, CustomPrefixCallback prefix_callback,
|
void InitGoogleLogging(const char* argv0, CustomPrefixCallback prefix_callback,
|
||||||
void* prefix_callback_data) {
|
void* prefix_callback_data) {
|
||||||
@ -2628,7 +2632,7 @@ void InitGoogleLogging(const char* argv0, CustomPrefixCallback prefix_callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownGoogleLogging() {
|
void ShutdownGoogleLogging() {
|
||||||
glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
|
ShutdownGoogleLoggingUtilities();
|
||||||
LogDestination::DeleteLogDestinations();
|
LogDestination::DeleteLogDestinations();
|
||||||
logging_directories_list = nullptr;
|
logging_directories_list = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@
|
|||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
#include "glog/raw_logging.h"
|
#include "glog/raw_logging.h"
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
#include "stacktrace.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
#ifdef GLOG_USE_GFLAGS
|
#ifdef GLOG_USE_GFLAGS
|
||||||
|
|||||||
@ -33,29 +33,18 @@
|
|||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "config.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
|
||||||
#include <fcntl.h> // for open()
|
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include "base/commandlineflags.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "glog/logging.h" // To pick up flag settings etc.
|
|
||||||
#include "glog/raw_logging.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_STACKTRACE
|
|
||||||
# include "stacktrace.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_SYSCALL_H)
|
#if defined(HAVE_SYSCALL_H)
|
||||||
# include <syscall.h> // for syscall()
|
# include <syscall.h> // for syscall()
|
||||||
#elif defined(HAVE_SYS_SYSCALL_H)
|
#elif defined(HAVE_SYS_SYSCALL_H)
|
||||||
@ -64,6 +53,12 @@
|
|||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <fcntl.h> // for open()
|
||||||
|
|
||||||
|
#include "glog/logging.h"
|
||||||
|
#include "glog/raw_logging.h"
|
||||||
|
#include "stacktrace.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
#if (defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)) && \
|
#if (defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)) && \
|
||||||
(!(defined(GLOG_OS_MACOSX)) && !(defined(GLOG_OS_OPENBSD))) && \
|
(!(defined(GLOG_OS_MACOSX)) && !(defined(GLOG_OS_OPENBSD))) && \
|
||||||
@ -173,7 +168,7 @@ void RawLog__(LogSeverity severity, const char* file, int line,
|
|||||||
|
|
||||||
// NOTE: this format should match the specification in base/logging.h
|
// NOTE: this format should match the specification in base/logging.h
|
||||||
DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %s %s:%d] RAW: ",
|
DoRawLog(&buf, &size, "%c00000000 00:00:00.000000 %s %s:%d] RAW: ",
|
||||||
LogSeverityNames[severity][0], sbuf.data(),
|
GetLogSeverityName(severity)[0], sbuf.data(),
|
||||||
const_basename(const_cast<char*>(file)), line);
|
const_basename(const_cast<char*>(file)), line);
|
||||||
|
|
||||||
// Record the position and size of the buffer after the prefix
|
// Record the position and size of the buffer after the prefix
|
||||||
@ -193,7 +188,7 @@ void RawLog__(LogSeverity severity, const char* file, int line,
|
|||||||
// avoiding FILE buffering (to avoid invoking malloc()), and bypassing
|
// avoiding FILE buffering (to avoid invoking malloc()), and bypassing
|
||||||
// libc (to side-step any libc interception).
|
// libc (to side-step any libc interception).
|
||||||
// We write just once to avoid races with other invocations of RawLog__.
|
// We write just once to avoid races with other invocations of RawLog__.
|
||||||
safe_write(STDERR_FILENO, buffer, strlen(buffer));
|
safe_write(fileno(stderr), buffer, strlen(buffer));
|
||||||
if (severity == GLOG_FATAL) {
|
if (severity == GLOG_FATAL) {
|
||||||
std::call_once(crashed, [file, line, msg_start, msg_size] {
|
std::call_once(crashed, [file, line, msg_start, msg_size] {
|
||||||
crash_reason.filename = file;
|
crash_reason.filename = file;
|
||||||
|
|||||||
@ -33,12 +33,15 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
|
#include "glog/platform.h"
|
||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
#include "symbolize.h"
|
#include "symbolize.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
@ -155,7 +158,7 @@ class MinimalFormatter {
|
|||||||
|
|
||||||
// Writes the given data with the size to the standard error.
|
// Writes the given data with the size to the standard error.
|
||||||
void WriteToStderr(const char* data, size_t size) {
|
void WriteToStderr(const char* data, size_t size) {
|
||||||
if (write(STDERR_FILENO, data, size) < 0) {
|
if (write(fileno(stderr), data, size) < 0) {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,6 +234,7 @@ void DumpSignalInfo(int signal_number, siginfo_t* siginfo) {
|
|||||||
void DumpStackFrameInfo(const char* prefix, void* pc) {
|
void DumpStackFrameInfo(const char* prefix, void* pc) {
|
||||||
// Get the symbol name.
|
// Get the symbol name.
|
||||||
const char* symbol = "(unknown)";
|
const char* symbol = "(unknown)";
|
||||||
|
#if defined(HAVE_SYMBOLIZE)
|
||||||
char symbolized[1024]; // Big enough for a sane symbol.
|
char symbolized[1024]; // Big enough for a sane symbol.
|
||||||
// Symbolizes the previous address of pc because pc may be in the
|
// Symbolizes the previous address of pc because pc may be in the
|
||||||
// next function.
|
// next function.
|
||||||
@ -238,6 +242,10 @@ void DumpStackFrameInfo(const char* prefix, void* pc) {
|
|||||||
sizeof(symbolized))) {
|
sizeof(symbolized))) {
|
||||||
symbol = symbolized;
|
symbol = symbolized;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# pragma message( \
|
||||||
|
"Symbolize functionality is not available for target platform: stack dump will contain empty frames.")
|
||||||
|
#endif // defined(HAVE_SYMBOLIZE)
|
||||||
|
|
||||||
char buf[1024]; // Big enough for stack frame info.
|
char buf[1024]; // Big enough for stack frame info.
|
||||||
MinimalFormatter formatter(buf, sizeof(buf));
|
MinimalFormatter formatter(buf, sizeof(buf));
|
||||||
|
|||||||
@ -39,13 +39,21 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "glog/logging.h"
|
#include "glog/logging.h"
|
||||||
#include "utilities.h"
|
#include "stacktrace.h"
|
||||||
|
#include "symbolize.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_UNISTD_H)
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
#ifdef GLOG_USE_GFLAGS
|
#ifdef GLOG_USE_GFLAGS
|
||||||
# include <gflags/gflags.h>
|
# include <gflags/gflags.h>
|
||||||
using namespace GFLAGS_NAMESPACE;
|
using namespace GFLAGS_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# include <io.h> // write
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace google;
|
using namespace google;
|
||||||
|
|
||||||
@ -59,7 +67,7 @@ static void DieInThread(int* a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void WriteToStdout(const char* data, size_t size) {
|
static void WriteToStdout(const char* data, size_t size) {
|
||||||
if (write(STDOUT_FILENO, data, size) < 0) {
|
if (write(fileno(stdout), data, size) < 0) {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/stacktrace.cc
Normal file
38
src/stacktrace.cc
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2024, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Routines to extract the current stack trace. These functions are
|
||||||
|
// thread-safe.
|
||||||
|
|
||||||
|
#include "stacktrace.h"
|
||||||
|
|
||||||
|
// Make an implementation of stacktrace compiled.
|
||||||
|
#if defined(STACKTRACE_H)
|
||||||
|
# include STACKTRACE_H
|
||||||
|
#endif
|
||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2000 - 2007, Google Inc.
|
// Copyright (c) 2024, 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
|
||||||
@ -30,13 +30,46 @@
|
|||||||
// Routines to extract the current stack trace. These functions are
|
// Routines to extract the current stack trace. These functions are
|
||||||
// thread-safe.
|
// thread-safe.
|
||||||
|
|
||||||
#ifndef BASE_STACKTRACE_H_
|
#ifndef GLOG_INTERNAL_STACKTRACE_H
|
||||||
#define BASE_STACKTRACE_H_
|
#define GLOG_INTERNAL_STACKTRACE_H
|
||||||
|
|
||||||
|
#include "glog/platform.h"
|
||||||
|
|
||||||
|
#if defined(GLOG_USE_GLOG_EXPORT)
|
||||||
|
# include "glog/export.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GLOG_NO_EXPORT)
|
||||||
|
# error "stacktrace.h" was not included correctly.
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "glog/logging.h"
|
#if defined(HAVE_LIBUNWIND)
|
||||||
|
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
|
||||||
|
#elif defined(HAVE_UNWIND)
|
||||||
|
# define STACKTRACE_H "stacktrace_unwind-inl.h"
|
||||||
|
#elif !defined(NO_FRAME_POINTER)
|
||||||
|
# if defined(__i386__) && __GNUC__ >= 2
|
||||||
|
# define STACKTRACE_H "stacktrace_x86-inl.h"
|
||||||
|
# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
|
||||||
|
# define STACKTRACE_H "stacktrace_powerpc-inl.h"
|
||||||
|
# elif defined(GLOG_OS_WINDOWS)
|
||||||
|
# define STACKTRACE_H "stacktrace_windows-inl.h"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_BACKTRACE)
|
||||||
|
# define STACKTRACE_H "stacktrace_generic-inl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STACKTRACE_H)
|
||||||
|
# define HAVE_STACKTRACE
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
|
#if defined(HAVE_STACKTRACE)
|
||||||
|
|
||||||
// This is similar to the GetStackFrames routine, except that it returns
|
// This is similar to the GetStackFrames routine, except that it returns
|
||||||
// the stack trace only, and not the stack frame sizes as well.
|
// the stack trace only, and not the stack frame sizes as well.
|
||||||
@ -54,8 +87,11 @@ namespace google {
|
|||||||
// .... ...
|
// .... ...
|
||||||
//
|
//
|
||||||
// "result" must not be nullptr.
|
// "result" must not be nullptr.
|
||||||
GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
|
GLOG_NO_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
|
||||||
|
|
||||||
|
#endif // defined(HAVE_STACKTRACE)
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
#endif // BASE_STACKTRACE_H_
|
#endif // GLOG_INTERNAL_STACKTRACE_H
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
// If you change this function, also change GetStackFrames below.
|
// If you change this function, also change GetStackFrames below.
|
||||||
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||||
@ -61,4 +62,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
return result_count;
|
return result_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -41,6 +41,7 @@ extern "C" {
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
// Sometimes, we can try to get a stack trace from within a stack
|
// Sometimes, we can try to get a stack trace from within a stack
|
||||||
// trace, because libunwind can call mmap (maybe indirectly via an
|
// trace, because libunwind can call mmap (maybe indirectly via an
|
||||||
@ -90,4 +91,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -41,6 +41,7 @@
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_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 nullptr if no stackframe can be found. Perform sanity
|
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
|
||||||
@ -131,4 +132,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -41,8 +41,6 @@
|
|||||||
# include <execinfo.h>
|
# include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace google;
|
|
||||||
|
|
||||||
#ifdef HAVE_STACKTRACE
|
#ifdef HAVE_STACKTRACE
|
||||||
|
|
||||||
// Obtain a backtrace, verify that the expected callers are present in the
|
// Obtain a backtrace, verify that the expected callers are present in the
|
||||||
@ -132,7 +130,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
|
|||||||
ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
|
ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
|
||||||
INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
|
INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
|
||||||
DECLARE_ADDRESS_LABEL(start);
|
DECLARE_ADDRESS_LABEL(start);
|
||||||
size = GetStackTrace(stack, STACK_LEN, 0);
|
size = google::GetStackTrace(stack, STACK_LEN, 0);
|
||||||
printf("Obtained %d stack frames.\n", size);
|
printf("Obtained %d stack frames.\n", size);
|
||||||
CHECK_GE(size, 1);
|
CHECK_GE(size, 1);
|
||||||
CHECK_LE(size, STACK_LEN);
|
CHECK_LE(size, STACK_LEN);
|
||||||
@ -231,7 +229,7 @@ static
|
|||||||
|
|
||||||
int main(int, char** argv) {
|
int main(int, char** argv) {
|
||||||
FLAGS_logtostderr = true;
|
FLAGS_logtostderr = true;
|
||||||
InitGoogleLogging(argv[0]);
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
CheckStackTrace(0);
|
CheckStackTrace(0);
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
struct trace_arg_t {
|
struct trace_arg_t {
|
||||||
void** result;
|
void** result;
|
||||||
@ -101,4 +102,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
return targ.count;
|
return targ.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -31,15 +31,13 @@
|
|||||||
//
|
//
|
||||||
// Windows implementation - just use CaptureStackBackTrace
|
// Windows implementation - just use CaptureStackBackTrace
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#include <windows.h> // Must come before <dbghelp.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
|
// clang-format on
|
||||||
#include "config.h"
|
|
||||||
#if defined(GLOG_USE_WINDOWS_PORT)
|
|
||||||
# include "port.h"
|
|
||||||
#endif
|
|
||||||
#include "stacktrace.h"
|
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||||
if (max_depth > 64) {
|
if (max_depth > 64) {
|
||||||
@ -51,4 +49,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
static_cast<DWORD>(max_depth), result, nullptr);
|
static_cast<DWORD>(max_depth), result, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -43,6 +43,7 @@
|
|||||||
#include "stacktrace.h"
|
#include "stacktrace.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_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 nullptr if no stackframe can be found. Perform sanity
|
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
|
||||||
@ -155,5 +156,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
|||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|||||||
@ -71,6 +71,7 @@
|
|||||||
# define GLOG_SAFE_ASSERT(expr) ((expr) ? 0 : (std::abort(), 0))
|
# define GLOG_SAFE_ASSERT(expr) ((expr) ? 0 : (std::abort(), 0))
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -105,6 +106,7 @@ void InstallSymbolizeOpenObjectFileCallback(
|
|||||||
g_symbolize_open_object_file_callback = callback;
|
g_symbolize_open_object_file_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
# if defined(__ELF__)
|
# if defined(__ELF__)
|
||||||
@ -135,6 +137,7 @@ void InstallSymbolizeOpenObjectFileCallback(
|
|||||||
# include "symbolize.h"
|
# include "symbolize.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -822,6 +825,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
|
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
|
||||||
@ -831,6 +835,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
|||||||
# include <cstring>
|
# include <cstring>
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||||
void* pc, char* out, size_t out_size, SymbolizeOptions /*options*/) {
|
void* pc, char* out, size_t out_size, SymbolizeOptions /*options*/) {
|
||||||
@ -848,6 +853,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
|
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
|
||||||
@ -856,6 +862,9 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
|||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class SymInitializer final {
|
class SymInitializer final {
|
||||||
public:
|
public:
|
||||||
@ -883,6 +892,8 @@ class SymInitializer final {
|
|||||||
SymInitializer& operator=(SymInitializer&&) = delete;
|
SymInitializer& operator=(SymInitializer&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
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,
|
||||||
SymbolizeOptions options) {
|
SymbolizeOptions options) {
|
||||||
@ -942,6 +953,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
# else
|
# else
|
||||||
@ -949,28 +961,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
bool Symbolize(void* pc, char* out, size_t out_size, SymbolizeOptions options) {
|
bool Symbolize(void* pc, char* out, size_t out_size, SymbolizeOptions options) {
|
||||||
return SymbolizeAndDemangle(pc, out, out_size, options);
|
return SymbolizeAndDemangle(pc, out, out_size, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace google
|
} // namespace glog_internal_namespace_
|
||||||
|
|
||||||
#else /* HAVE_SYMBOLIZE */
|
|
||||||
|
|
||||||
# include <cassert>
|
|
||||||
|
|
||||||
# include "config.h"
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
|
|
||||||
// TODO: Support other environments.
|
|
||||||
bool Symbolize(void* /*pc*/, char* /*out*/, size_t /*out_size*/,
|
|
||||||
SymbolizeOptions /*options*/) {
|
|
||||||
assert(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -51,14 +51,38 @@
|
|||||||
// malloc() and other unsafe operations. It should be both
|
// malloc() and other unsafe operations. It should be both
|
||||||
// thread-safe and async-signal-safe.
|
// thread-safe and async-signal-safe.
|
||||||
|
|
||||||
#ifndef BASE_SYMBOLIZE_H_
|
#ifndef GLOG_INTERNAL_SYMBOLIZE_H
|
||||||
#define BASE_SYMBOLIZE_H_
|
#define GLOG_INTERNAL_SYMBOLIZE_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "glog/logging.h"
|
#include "glog/platform.h"
|
||||||
#include "utilities.h"
|
|
||||||
|
#if defined(GLOG_USE_GLOG_EXPORT)
|
||||||
|
# include "glog/export.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GLOG_NO_EXPORT)
|
||||||
|
# error "symbolize.h" was not included correctly.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GLOG_NO_SYMBOLIZE_DETECTION
|
||||||
|
# ifndef HAVE_SYMBOLIZE
|
||||||
|
// defined by gcc
|
||||||
|
# if defined(__ELF__) && defined(GLOG_OS_LINUX)
|
||||||
|
# define HAVE_SYMBOLIZE
|
||||||
|
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
|
||||||
|
// Use dladdr to symbolize.
|
||||||
|
# define HAVE_SYMBOLIZE
|
||||||
|
# elif defined(GLOG_OS_WINDOWS)
|
||||||
|
// Use DbgHelp to symbolize
|
||||||
|
# define HAVE_SYMBOLIZE
|
||||||
|
# endif
|
||||||
|
# endif // !defined(HAVE_SYMBOLIZE)
|
||||||
|
#endif // !defined(GLOG_NO_SYMBOLIZE_DETECTION)
|
||||||
|
|
||||||
#ifdef HAVE_SYMBOLIZE
|
#ifdef HAVE_SYMBOLIZE
|
||||||
|
|
||||||
@ -69,7 +93,7 @@
|
|||||||
# include <elf.h>
|
# include <elf.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if !defined(ANDROID)
|
# if !defined(GLOG_OS_ANDROID)
|
||||||
# include <link.h> // For ElfW() macro.
|
# include <link.h> // For ElfW() macro.
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -95,17 +119,21 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
// Gets the section header for the given name, if it exists. Returns true on
|
// Gets the section header for the given name, if it exists. Returns true on
|
||||||
// success. Otherwise, returns false.
|
// success. Otherwise, returns false.
|
||||||
|
GLOG_NO_EXPORT
|
||||||
bool GetSectionHeaderByName(int fd, const char* name, size_t name_len,
|
bool GetSectionHeaderByName(int fd, const char* name, size_t name_len,
|
||||||
ElfW(Shdr) * out);
|
ElfW(Shdr) * out);
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
# endif /* __ELF__ */
|
# endif /* __ELF__ */
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
// Restrictions on the callbacks that follow:
|
// Restrictions on the callbacks that follow:
|
||||||
// - The callbacks must not use heaps but only use stacks.
|
// - The callbacks must not use heaps but only use stacks.
|
||||||
@ -119,7 +147,7 @@ namespace google {
|
|||||||
// 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.
|
||||||
using SymbolizeCallback = int (*)(int, void*, char*, size_t, uint64_t);
|
using SymbolizeCallback = int (*)(int, void*, char*, size_t, uint64_t);
|
||||||
GLOG_EXPORT
|
GLOG_NO_EXPORT
|
||||||
void InstallSymbolizeCallback(SymbolizeCallback callback);
|
void InstallSymbolizeCallback(SymbolizeCallback callback);
|
||||||
|
|
||||||
// Installs a callback function, which will be called instead of
|
// Installs a callback function, which will be called instead of
|
||||||
@ -134,15 +162,19 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
|
|||||||
// (including the null-terminator).
|
// (including the null-terminator).
|
||||||
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&,
|
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&,
|
||||||
char*, size_t);
|
char*, size_t);
|
||||||
GLOG_EXPORT
|
GLOG_NO_EXPORT
|
||||||
void InstallSymbolizeOpenObjectFileCallback(
|
void InstallSymbolizeOpenObjectFileCallback(
|
||||||
SymbolizeOpenObjectFileCallback callback);
|
SymbolizeOpenObjectFileCallback callback);
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
|
#if defined(HAVE_SYMBOLIZE)
|
||||||
|
|
||||||
enum class SymbolizeOptions {
|
enum class SymbolizeOptions {
|
||||||
// No additional options.
|
// No additional options.
|
||||||
@ -169,9 +201,13 @@ constexpr SymbolizeOptions operator|(SymbolizeOptions lhs,
|
|||||||
// symbol name to "out". The symbol name is demangled if possible
|
// symbol name to "out". The symbol name is demangled if possible
|
||||||
// (supports symbols generated by GCC 3.x or newer). Otherwise,
|
// (supports symbols generated by GCC 3.x or newer). Otherwise,
|
||||||
// returns false.
|
// returns false.
|
||||||
GLOG_EXPORT bool Symbolize(void* pc, char* out, size_t out_size,
|
GLOG_NO_EXPORT bool Symbolize(
|
||||||
|
void* pc, char* out, size_t out_size,
|
||||||
SymbolizeOptions options = SymbolizeOptions::kNone);
|
SymbolizeOptions options = SymbolizeOptions::kNone);
|
||||||
|
|
||||||
|
#endif // defined(HAVE_SYMBOLIZE)
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
#endif // BASE_SYMBOLIZE_H_
|
#endif // GLOG_INTERNAL_SYMBOLIZE_H
|
||||||
|
|||||||
@ -41,8 +41,12 @@
|
|||||||
|
|
||||||
#include "base/googleinit.h"
|
#include "base/googleinit.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "glog/flags.h"
|
||||||
|
#include "glog/logging.h"
|
||||||
|
#include "stacktrace.h"
|
||||||
|
#include "symbolize.h"
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef GLOG_OS_ANDROID
|
||||||
# include <android/log.h>
|
# include <android/log.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
@ -88,7 +92,7 @@ void AlsoErrorWrite(LogSeverity severity, const char* tag,
|
|||||||
(void)tag;
|
(void)tag;
|
||||||
// On Windows, also output to the debugger
|
// On Windows, also output to the debugger
|
||||||
::OutputDebugStringA(message);
|
::OutputDebugStringA(message);
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(GLOG_OS_ANDROID)
|
||||||
constexpr int android_log_levels[] = {
|
constexpr int android_log_levels[] = {
|
||||||
ANDROID_LOG_INFO,
|
ANDROID_LOG_INFO,
|
||||||
ANDROID_LOG_WARN,
|
ANDROID_LOG_WARN,
|
||||||
@ -125,7 +129,7 @@ static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
|
|||||||
|
|
||||||
static void DebugWriteToStderr(const char* data, void*) {
|
static void DebugWriteToStderr(const char* data, void*) {
|
||||||
// This one is signal-safe.
|
// This one is signal-safe.
|
||||||
if (write(STDERR_FILENO, data, strlen(data)) < 0) {
|
if (write(fileno(stderr), data, strlen(data)) < 0) {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
AlsoErrorWrite(GLOG_FATAL,
|
AlsoErrorWrite(GLOG_FATAL,
|
||||||
@ -319,18 +323,4 @@ void ShutdownGoogleLoggingUtilities() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace glog_internal_namespace_
|
} // namespace glog_internal_namespace_
|
||||||
|
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
|
||||||
// Make an implementation of stacktrace compiled.
|
|
||||||
#ifdef STACKTRACE_H
|
|
||||||
# include STACKTRACE_H
|
|
||||||
# if 0
|
|
||||||
// For include scanners which can't handle macro expansions.
|
|
||||||
# include "stacktrace_generic-inl.h"
|
|
||||||
# include "stacktrace_libunwind-inl.h"
|
|
||||||
# include "stacktrace_powerpc-inl.h"
|
|
||||||
# include "stacktrace_x86-inl.h"
|
|
||||||
# include "stacktrace_x86_64-inl.h"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -32,8 +32,8 @@
|
|||||||
//
|
//
|
||||||
// Define utilities for glog internal usage.
|
// Define utilities for glog internal usage.
|
||||||
|
|
||||||
#ifndef UTILITIES_H__
|
#ifndef GLOG_INTERNAL_UTILITIES_H
|
||||||
#define UTILITIES_H__
|
#define GLOG_INTERNAL_UTILITIES_H
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -60,18 +60,14 @@
|
|||||||
#define PRIXS __PRIS_PREFIX "X"
|
#define PRIXS __PRIS_PREFIX "X"
|
||||||
#define PRIoS __PRIS_PREFIX "o"
|
#define PRIoS __PRIS_PREFIX "o"
|
||||||
|
|
||||||
#include "glog/logging.h"
|
#include "config.h"
|
||||||
|
#include "glog/platform.h"
|
||||||
#if defined(GLOG_USE_WINDOWS_PORT)
|
#if defined(GLOG_USE_WINDOWS_PORT)
|
||||||
# include "port.h"
|
# include "port.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_UNISTD_H)
|
#if defined(HAVE_UNISTD_H)
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_SSIZE_T)
|
#if !defined(HAVE_SSIZE_T)
|
||||||
# if defined(GLOG_OS_WINDOWS)
|
# if defined(GLOG_OS_WINDOWS)
|
||||||
# include <basetsd.h>
|
# include <basetsd.h>
|
||||||
@ -81,6 +77,9 @@ using ssize_t = std::ptrdiff_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "glog/log_severity.h"
|
||||||
|
#include "glog/types.h"
|
||||||
|
|
||||||
// There are three different ways we can try to get the stack trace:
|
// There are three different ways we can try to get the stack trace:
|
||||||
//
|
//
|
||||||
// 1) The libunwind library. This is still in development, and as a
|
// 1) The libunwind library. This is still in development, and as a
|
||||||
@ -103,43 +102,6 @@ using ssize_t = std::ptrdiff_t;
|
|||||||
// correctly when GetStackTrace() is called with max_depth == 0.
|
// correctly when GetStackTrace() is called with max_depth == 0.
|
||||||
// Some code may do that.
|
// Some code may do that.
|
||||||
|
|
||||||
#if defined(HAVE_LIBUNWIND)
|
|
||||||
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
|
|
||||||
#elif defined(HAVE_UNWIND)
|
|
||||||
# define STACKTRACE_H "stacktrace_unwind-inl.h"
|
|
||||||
#elif !defined(NO_FRAME_POINTER)
|
|
||||||
# if defined(__i386__) && __GNUC__ >= 2
|
|
||||||
# define STACKTRACE_H "stacktrace_x86-inl.h"
|
|
||||||
# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
|
|
||||||
# define STACKTRACE_H "stacktrace_powerpc-inl.h"
|
|
||||||
# elif defined(GLOG_OS_WINDOWS)
|
|
||||||
# define STACKTRACE_H "stacktrace_windows-inl.h"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_BACKTRACE)
|
|
||||||
# define STACKTRACE_H "stacktrace_generic-inl.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(STACKTRACE_H)
|
|
||||||
# define HAVE_STACKTRACE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GLOG_NO_SYMBOLIZE_DETECTION
|
|
||||||
# ifndef HAVE_SYMBOLIZE
|
|
||||||
// defined by gcc
|
|
||||||
# if defined(__ELF__) && defined(GLOG_OS_LINUX)
|
|
||||||
# define HAVE_SYMBOLIZE
|
|
||||||
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
|
|
||||||
// Use dladdr to symbolize.
|
|
||||||
# define HAVE_SYMBOLIZE
|
|
||||||
# elif defined(GLOG_OS_WINDOWS)
|
|
||||||
// Use DbgHelp to symbolize
|
|
||||||
# define HAVE_SYMBOLIZE
|
|
||||||
# endif
|
|
||||||
# endif // !defined(HAVE_SYMBOLIZE)
|
|
||||||
#endif // !defined(GLOG_NO_SYMBOLIZE_DETECTION)
|
|
||||||
|
|
||||||
#ifndef ARRAYSIZE
|
#ifndef ARRAYSIZE
|
||||||
// There is a better way, but this is good enough for our purpose.
|
// There is a better way, but this is good enough for our purpose.
|
||||||
# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
|
# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
|
||||||
@ -320,4 +282,4 @@ struct std::default_delete<std::FILE> {
|
|||||||
void operator()(FILE* p) const noexcept { fclose(p); }
|
void operator()(FILE* p) const noexcept { fclose(p); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILITIES_H__
|
#endif // GLOG_INTERNAL_UTILITIES_H
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 1999, 2007, Google Inc.
|
// Copyright (c) 2024, 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
|
||||||
@ -39,9 +39,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "glog/logging.h"
|
|
||||||
#include "glog/raw_logging.h"
|
#include "glog/raw_logging.h"
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
// glog doesn't have annotation
|
// glog doesn't have annotation
|
||||||
#define ANNOTATE_BENIGN_RACE(address, description)
|
#define ANNOTATE_BENIGN_RACE(address, description)
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
* under the MIT license. For all details and documentation, see
|
* under the MIT license. For all details and documentation, see
|
||||||
* https://github.com/tronkko/dirent
|
* https://github.com/tronkko/dirent
|
||||||
*/
|
*/
|
||||||
#ifndef DIRENT_H
|
#ifndef GLOG_INTERNAL_WINDOWS_DIRENT_H
|
||||||
#define DIRENT_H
|
#define GLOG_INTERNAL_WINDOWS_DIRENT_H
|
||||||
|
|
||||||
/* Hide warnings about unreferenced local functions */
|
/* Hide warnings about unreferenced local functions */
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
@ -1037,4 +1037,4 @@ static void dirent_set_errno(int error) {
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /*DIRENT_H*/
|
#endif /*GLOG_INTERNAL_WINDOWS_DIRENT_H*/
|
||||||
|
|||||||
@ -42,6 +42,9 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
|
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifndef HAVE_LOCALTIME_R
|
||||||
struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
|
struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
|
||||||
localtime_s(result, timep);
|
localtime_s(result, timep);
|
||||||
@ -54,3 +57,6 @@ struct tm* gmtime_r(const std::time_t* timep, std::tm* result) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // not HAVE_GMTIME_R
|
#endif // not HAVE_GMTIME_R
|
||||||
|
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
|
} // namespace google
|
||||||
|
|||||||
@ -43,6 +43,14 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(GLOG_USE_GLOG_EXPORT)
|
||||||
|
# include "glog/export.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GLOG_EXPORT)
|
||||||
|
# error "port.h" was not included correctly.
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
@ -62,8 +70,6 @@
|
|||||||
* used by both C and C++ code, so we put all the C++ together.
|
* used by both C and C++ code, so we put all the C++ together.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "glog/logging.h"
|
|
||||||
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
|
|
||||||
/* 4244: otherwise we get problems when substracting two size_t's to an int
|
/* 4244: otherwise we get problems when substracting two size_t's to an int
|
||||||
@ -89,9 +95,6 @@
|
|||||||
# define O_CREAT _O_CREAT
|
# define O_CREAT _O_CREAT
|
||||||
# define O_EXCL _O_EXCL
|
# define O_EXCL _O_EXCL
|
||||||
|
|
||||||
# ifndef __MINGW32__
|
|
||||||
enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
|
|
||||||
# endif
|
|
||||||
# define S_IRUSR S_IREAD
|
# define S_IRUSR S_IREAD
|
||||||
# define S_IWUSR S_IWRITE
|
# define S_IWUSR S_IWRITE
|
||||||
|
|
||||||
@ -116,24 +119,23 @@ enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
|
|||||||
|
|
||||||
# endif // _MSC_VER
|
# endif // _MSC_VER
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
inline namespace glog_internal_namespace_ {
|
||||||
# ifndef HAVE_LOCALTIME_R
|
# ifndef HAVE_LOCALTIME_R
|
||||||
extern GLOG_EXPORT std::tm* localtime_r(const std::time_t* timep,
|
GLOG_NO_EXPORT std::tm* localtime_r(const std::time_t* timep, std::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 std::tm* gmtime_r(const std::time_t* timep, std::tm* result);
|
GLOG_NO_EXPORT std::tm* gmtime_r(const std::time_t* timep, std::tm* result);
|
||||||
# endif // not HAVE_GMTIME_R
|
# endif // not HAVE_GMTIME_R
|
||||||
|
|
||||||
|
GLOG_NO_EXPORT
|
||||||
inline char* strerror_r(int errnum, char* buf, std::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;
|
||||||
}
|
}
|
||||||
|
} // namespace glog_internal_namespace_
|
||||||
# ifndef __cplusplus
|
} // namespace google
|
||||||
/* I don't see how to get inlining for C code in MSVC. Ah well. */
|
|
||||||
# define inline
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user