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 (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 (pwrite unistd.h HAVE_PWRITE)
|
||||
check_cxx_symbol_exists (sigaction csignal HAVE_SIGACTION)
|
||||
@ -364,6 +365,8 @@ set (GLOG_SRCS
|
||||
src/logging.cc
|
||||
src/raw_logging.cc
|
||||
src/signalhandler.cc
|
||||
src/stacktrace.cc
|
||||
src/stacktrace.h
|
||||
src/symbolize.cc
|
||||
src/symbolize.h
|
||||
src/utilities.cc
|
||||
|
||||
@ -48,8 +48,6 @@ def glog_library(with_gflags = 1, **kwargs):
|
||||
|
||||
common_copts = [
|
||||
"-std=c++14",
|
||||
"-DGLOG_BAZEL_BUILD",
|
||||
"-DHAVE_STRING_H",
|
||||
"-I%s/glog_internal" % gendir,
|
||||
] + (["-DGLOG_USE_GFLAGS"] if with_gflags else [])
|
||||
|
||||
@ -74,6 +72,7 @@ def glog_library(with_gflags = 1, **kwargs):
|
||||
"-DGLOG_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||
"-DGLOG_NO_EXPORT=__attribute__((visibility(\\\"default\\\")))",
|
||||
"-DHAVE_MODE_T",
|
||||
"-DHAVE_POSIX_FADVISE",
|
||||
"-DHAVE_SSIZE_T",
|
||||
"-DHAVE_SYS_TYPES_H",
|
||||
# For src/utilities.cc.
|
||||
@ -102,10 +101,11 @@ def glog_library(with_gflags = 1, **kwargs):
|
||||
windows_only_copts = [
|
||||
# Override -DGLOG_EXPORT= from the cc_library's defines.
|
||||
"-DGLOG_EXPORT=__declspec(dllexport)",
|
||||
"-DGLOG_NO_EXPORT=",
|
||||
"-DGLOG_NO_ABBREVIATED_SEVERITIES",
|
||||
"-DGLOG_NO_EXPORT=",
|
||||
"-DGLOG_USE_WINDOWS_PORT",
|
||||
"-DHAVE__CHSIZE_S",
|
||||
"-DHAVE_DBGHELP",
|
||||
"-I" + src_windows,
|
||||
]
|
||||
|
||||
@ -115,7 +115,6 @@ def glog_library(with_gflags = 1, **kwargs):
|
||||
]
|
||||
|
||||
windows_only_srcs = [
|
||||
"src/glog/log_severity.h",
|
||||
"src/windows/dirent.h",
|
||||
"src/windows/port.cc",
|
||||
"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
|
||||
# generated for Bazel.
|
||||
"@bazel_tools//src/conditions:windows": [
|
||||
"GLOG_EXPORT=",
|
||||
"GLOG_DEPRECATED=__declspec(deprecated)",
|
||||
"GLOG_EXPORT=",
|
||||
"GLOG_NO_ABBREVIATED_SEVERITIES",
|
||||
"GLOG_NO_EXPORT=",
|
||||
],
|
||||
"//conditions:default": [
|
||||
"GLOG_DEPRECATED=__attribute__((deprecated))",
|
||||
"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/raw_logging.cc",
|
||||
"src/signalhandler.cc",
|
||||
"src/stacktrace.cc",
|
||||
"src/stacktrace.h",
|
||||
"src/stacktrace_generic-inl.h",
|
||||
"src/stacktrace_libunwind-inl.h",
|
||||
"src/stacktrace_powerpc-inl.h",
|
||||
@ -180,6 +183,7 @@ def glog_library(with_gflags = 1, **kwargs):
|
||||
"src/symbolize.cc",
|
||||
"src/symbolize.h",
|
||||
"src/utilities.cc",
|
||||
"src/utilities.h",
|
||||
"src/vlog_is_on.cc",
|
||||
] + select({
|
||||
"@bazel_tools//src/conditions:windows": windows_only_srcs,
|
||||
|
||||
@ -31,6 +31,9 @@
|
||||
/* Define if you have the 'pread' function */
|
||||
#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. */
|
||||
#cmakedefine HAVE_PWD_H
|
||||
|
||||
|
||||
@ -37,7 +37,6 @@
|
||||
#include "demangle.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
|
||||
@ -52,6 +51,7 @@
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
#if !defined(GLOG_OS_WINDOWS) && !defined(HAVE___CXA_DEMANGLE)
|
||||
namespace {
|
||||
@ -1359,4 +1359,5 @@ bool Demangle(const char* mangled, char* out, size_t out_size) {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -67,19 +67,28 @@
|
||||
// C++ ABI in the future.
|
||||
//
|
||||
|
||||
#ifndef BASE_DEMANGLE_H_
|
||||
#define BASE_DEMANGLE_H_
|
||||
#ifndef GLOG_INTERNAL_DEMANGLE_H
|
||||
#define GLOG_INTERNAL_DEMANGLE_H
|
||||
|
||||
#include "config.h"
|
||||
#include "glog/logging.h"
|
||||
#include <cstddef>
|
||||
|
||||
#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 {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Demangle "mangled". On success, return true and write the
|
||||
// demangled symbol name to "out". Otherwise, return false.
|
||||
// "out" is modified even if demangling is unsuccessful.
|
||||
bool GLOG_EXPORT Demangle(const char* mangled, char* out, size_t out_size);
|
||||
bool GLOG_NO_EXPORT Demangle(const char* mangled, char* out, size_t out_size);
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
#endif // BASE_DEMANGLE_H_
|
||||
#endif // GLOG_INTERNAL_DEMANGLE_H
|
||||
|
||||
@ -95,8 +95,6 @@ constexpr int NUM_SEVERITIES = 4;
|
||||
# define DFATAL_LEVEL FATAL
|
||||
#endif
|
||||
|
||||
extern GLOG_EXPORT const char* const LogSeverityNames[NUM_SEVERITIES];
|
||||
|
||||
// NDEBUG usage helpers related to (RAW_)DCHECK:
|
||||
//
|
||||
// DEBUG_MODE is for small !NDEBUG uses like
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
# include "glog/export.h"
|
||||
#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.
|
||||
#endif
|
||||
|
||||
@ -580,13 +580,16 @@ class LogSink; // defined below
|
||||
LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
|
||||
<< "Check failed: " #condition " "
|
||||
|
||||
namespace logging {
|
||||
namespace internal {
|
||||
|
||||
// A container for a string pointer which can be evaluated to a bool -
|
||||
// true iff the pointer is nullptr.
|
||||
struct CheckOpString {
|
||||
CheckOpString(std::string* str) : str_(str) {}
|
||||
// No destructor: if str_ is non-nullptr, we're about to LOG(FATAL),
|
||||
// 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);
|
||||
}
|
||||
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.
|
||||
struct DummyClassToDefineOperator {};
|
||||
|
||||
} // namespace google
|
||||
|
||||
// Define global operator<< to declare using ::operator<<.
|
||||
// This declaration will allow use to use CHECK macros for user
|
||||
// defined classes which have operator<< (e.g., stl_logging.h).
|
||||
inline std::ostream& operator<<(std::ostream& out,
|
||||
const google::DummyClassToDefineOperator&) {
|
||||
const DummyClassToDefineOperator&) {
|
||||
return out;
|
||||
}
|
||||
|
||||
namespace google {
|
||||
|
||||
// This formats a value for a failing CHECK_XX statement. Ordinarily,
|
||||
// it uses the definition for operator<<, with a few special cases below.
|
||||
template <typename T>
|
||||
@ -660,8 +659,6 @@ std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
|
||||
#endif
|
||||
;
|
||||
|
||||
namespace base {
|
||||
|
||||
// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
|
||||
// statement. See MakeCheckOpString for sample usage. Other
|
||||
// approaches were considered: use of a template method (e.g.,
|
||||
@ -685,12 +682,10 @@ class GLOG_EXPORT CheckOpMessageBuilder {
|
||||
std::ostringstream* stream_;
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
template <typename T1, typename T2>
|
||||
std::string* MakeCheckOpString(const T1& v1, const T2& v2,
|
||||
const char* exprtext) {
|
||||
base::CheckOpMessageBuilder comb(exprtext);
|
||||
CheckOpMessageBuilder comb(exprtext);
|
||||
MakeCheckOpValueString(comb.ForVar1(), v1);
|
||||
MakeCheckOpValueString(comb.ForVar2(), v2);
|
||||
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.
|
||||
// This happens if, for example, those are used as token names in a
|
||||
// yacc grammar.
|
||||
DEFINE_CHECK_OP_IMPL(Check_EQ,
|
||||
==) // Compilation error with CHECK_EQ(nullptr, x)?
|
||||
DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == nullptr) instead.
|
||||
DEFINE_CHECK_OP_IMPL(Check_EQ, ==)
|
||||
DEFINE_CHECK_OP_IMPL(Check_NE, !=)
|
||||
DEFINE_CHECK_OP_IMPL(Check_LE, <=)
|
||||
DEFINE_CHECK_OP_IMPL(Check_LT, <)
|
||||
DEFINE_CHECK_OP_IMPL(Check_GE, >=)
|
||||
DEFINE_CHECK_OP_IMPL(Check_GT, >)
|
||||
|
||||
#undef DEFINE_CHECK_OP_IMPL
|
||||
|
||||
// Helper macro for binary operators.
|
||||
@ -743,18 +738,23 @@ DEFINE_CHECK_OP_IMPL(Check_GT, >)
|
||||
// file is included). Save the current meaning now and use it
|
||||
// in the macro.
|
||||
typedef std::string _Check_string;
|
||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||
while (google::_Check_string* _result = google::Check##name##Impl( \
|
||||
google::GetReferenceableValue(val1), \
|
||||
google::GetReferenceableValue(val2), #val1 " " #op " " #val2)) \
|
||||
log(__FILE__, __LINE__, google::CheckOpString(_result)).stream()
|
||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||
while (google::logging::internal::_Check_string* _result = \
|
||||
google::logging::internal::Check##name##Impl( \
|
||||
google::logging::internal::GetReferenceableValue(val1), \
|
||||
google::logging::internal::GetReferenceableValue(val2), \
|
||||
#val1 " " #op " " #val2)) \
|
||||
log(__FILE__, __LINE__, google::logging::internal::CheckOpString(_result)) \
|
||||
.stream()
|
||||
#else
|
||||
// In optimized mode, use CheckOpString to hint to compiler that
|
||||
// the while condition is unlikely.
|
||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||
while (google::CheckOpString _result = google::Check##name##Impl( \
|
||||
google::GetReferenceableValue(val1), \
|
||||
google::GetReferenceableValue(val2), #val1 " " #op " " #val2)) \
|
||||
# define CHECK_OP_LOG(name, op, val1, val2, log) \
|
||||
while (google::logging::internal::CheckOpString _result = \
|
||||
google::logging::internal::Check##name##Impl( \
|
||||
google::logging::internal::GetReferenceableValue(val1), \
|
||||
google::logging::internal::GetReferenceableValue(val2), \
|
||||
#val1 " " #op " " #val2)) \
|
||||
log(__FILE__, __LINE__, _result).stream()
|
||||
#endif // STATIC_ANALYSIS, DCHECK_IS_ON()
|
||||
|
||||
@ -794,26 +794,32 @@ typedef std::string _Check_string;
|
||||
// Check that the input is non nullptr. This very useful in constructor
|
||||
// initializer lists.
|
||||
|
||||
#define CHECK_NOTNULL(val) \
|
||||
google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non nullptr", \
|
||||
(val))
|
||||
#define CHECK_NOTNULL(val) \
|
||||
google::logging::internal::CheckNotNull( \
|
||||
__FILE__, __LINE__, "'" #val "' Must be non nullptr", (val))
|
||||
|
||||
// Helper functions for string comparisons.
|
||||
// To avoid bloat, the definitions are in logging.cc.
|
||||
#define DECLARE_CHECK_STROP_IMPL(func, expected) \
|
||||
GLOG_EXPORT std::string* Check##func##expected##Impl( \
|
||||
const char* s1, const char* s2, const char* names);
|
||||
|
||||
DECLARE_CHECK_STROP_IMPL(strcmp, true)
|
||||
DECLARE_CHECK_STROP_IMPL(strcmp, false)
|
||||
DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
|
||||
DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
|
||||
|
||||
} // namespace internal
|
||||
} // namespace logging
|
||||
|
||||
#undef DECLARE_CHECK_STROP_IMPL
|
||||
|
||||
// Helper macro for string comparisons.
|
||||
// Don't use this macro directly in your code, use CHECK_STREQ et al below.
|
||||
#define CHECK_STROP(func, op, expected, s1, s2) \
|
||||
while (google::CheckOpString _result = google::Check##func##expected##Impl( \
|
||||
(s1), (s2), #s1 " " #op " " #s2)) \
|
||||
#define CHECK_STROP(func, op, expected, s1, s2) \
|
||||
while (google::logging::internal::CheckOpString _result = \
|
||||
google::logging::internal::Check##func##expected##Impl( \
|
||||
(s1), (s2), #s1 " " #op " " #s2)) \
|
||||
LOG(FATAL) << *_result.str_
|
||||
|
||||
// String (char*) equality/inequality checks.
|
||||
@ -1181,6 +1187,12 @@ class GLOG_EXPORT LogStreamBuf : public std::streambuf {
|
||||
|
||||
} // 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
|
||||
// create an instance of LogMessage and then stream stuff to it.
|
||||
@ -1297,7 +1309,8 @@ class GLOG_EXPORT LogMessage {
|
||||
std::string* message);
|
||||
|
||||
// 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();
|
||||
|
||||
@ -1355,8 +1368,8 @@ class GLOG_EXPORT LogMessage {
|
||||
|
||||
// We keep the data in a separate struct so that each instance of
|
||||
// LogMessage uses less stack space.
|
||||
LogMessageData* allocated_;
|
||||
LogMessageData* data_;
|
||||
logging::internal::LogMessageData* allocated_;
|
||||
logging::internal::LogMessageData* data_;
|
||||
LogMessageTime time_;
|
||||
|
||||
friend class LogDestination;
|
||||
@ -1371,7 +1384,8 @@ class GLOG_EXPORT LogMessage {
|
||||
class GLOG_EXPORT LogMessageFatal : public LogMessage {
|
||||
public:
|
||||
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();
|
||||
};
|
||||
|
||||
@ -1388,22 +1402,6 @@ inline void LogAtLevel(LogSeverity severity, std::string const& msg) {
|
||||
#define LOG_AT_LEVEL(severity) \
|
||||
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
|
||||
// only works if ostream is a LogStream. If the ostream is not a
|
||||
// LogStream you'll get an assert saying as much at runtime.
|
||||
@ -1429,13 +1427,29 @@ class GLOG_EXPORT ErrnoLogMessage : public LogMessage {
|
||||
|
||||
namespace logging {
|
||||
namespace internal {
|
||||
class LogMessageVoidify {
|
||||
public:
|
||||
LogMessageVoidify() {}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
struct LogMessageVoidify {
|
||||
// This has to be an operator with a precedence lower than << but
|
||||
// higher than ?:
|
||||
void operator&(std::ostream&) {}
|
||||
void operator&(std::ostream&) noexcept {}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace logging
|
||||
|
||||
@ -1637,7 +1651,7 @@ class GLOG_EXPORT NullStream : public LogMessage::LogStream {
|
||||
// the overloaded NullStream::operator<< will not be invoked.
|
||||
NullStream();
|
||||
NullStream(const char* /*file*/, int /*line*/,
|
||||
const CheckOpString& /*result*/);
|
||||
const logging::internal::CheckOpString& /*result*/);
|
||||
NullStream& stream();
|
||||
|
||||
private:
|
||||
|
||||
@ -52,6 +52,8 @@
|
||||
# define GLOG_OS_OPENBSD
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
# define GLOG_OS_EMSCRIPTEN
|
||||
#elif defined(__ANDROID__)
|
||||
# define GLOG_OS_ANDROID
|
||||
#else
|
||||
// TODO(hamaji): Add other platforms.
|
||||
#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
|
||||
|
||||
@ -51,12 +51,16 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "config.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLOG_USE_WINDOWS_PORT)
|
||||
# include "port.h"
|
||||
#endif // defined(GLOG_USE_WINDOWS_PORT)
|
||||
#include "base/commandlineflags.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#if __cplusplus < 201103L && !defined(_MSC_VER)
|
||||
# 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
|
||||
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.
|
||||
// fd - Should be STDOUT_FILENO or STDERR_FILENO
|
||||
// fd - Should be stdout or stderr
|
||||
// filename - File where output should be stored
|
||||
static inline void CaptureTestOutput(int fd, const string& filename) {
|
||||
CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
|
||||
CHECK(s_captured_streams[fd] == nullptr);
|
||||
CHECK((fd == fileno(stdout)) || (fd == fileno(stderr)));
|
||||
CHECK(s_captured_streams.find(fd) == s_captured_streams.end());
|
||||
s_captured_streams[fd] = std::make_unique<CapturedStream>(fd, filename);
|
||||
}
|
||||
static inline void CaptureTestStdout() {
|
||||
CaptureTestOutput(STDOUT_FILENO, FLAGS_test_tmpdir + "/captured.out");
|
||||
CaptureTestOutput(fileno(stdout), FLAGS_test_tmpdir + "/captured.out");
|
||||
}
|
||||
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
|
||||
static inline size_t GetFileSize(FILE* file) {
|
||||
@ -379,11 +383,11 @@ static inline string ReadEntireFile(FILE* file) {
|
||||
|
||||
return std::string(content.data(), bytes_read);
|
||||
}
|
||||
// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
|
||||
// fd is STDERR_FILENO) as a string
|
||||
// Get the captured stdout or stderr as a string
|
||||
static inline string GetCapturedTestOutput(int fd) {
|
||||
CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
|
||||
std::unique_ptr<CapturedStream> cap = std::move(s_captured_streams[fd]);
|
||||
CHECK((fd == fileno(stdout)) || (fd == fileno(stderr)));
|
||||
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()?";
|
||||
|
||||
// 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.
|
||||
static inline string GetCapturedTestStderr() {
|
||||
return GetCapturedTestOutput(STDERR_FILENO);
|
||||
return GetCapturedTestOutput(fileno(stderr));
|
||||
}
|
||||
|
||||
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,
|
||||
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()?";
|
||||
} else {
|
||||
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) {
|
||||
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) {
|
||||
return MungeAndDiffTest(golden_filename,
|
||||
s_captured_streams[STDOUT_FILENO].get());
|
||||
s_captured_streams.at(fileno(stdout)).get());
|
||||
}
|
||||
|
||||
// Save flags used from logging_unittest.cc.
|
||||
|
||||
@ -48,13 +48,11 @@
|
||||
#include <utility>
|
||||
|
||||
#include "config.h"
|
||||
#include "glog/platform.h"
|
||||
#include "glog/raw_logging.h"
|
||||
#include "stacktrace.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef HAVE_STACKTRACE
|
||||
# include "stacktrace.h"
|
||||
#endif
|
||||
|
||||
#ifdef GLOG_OS_WINDOWS
|
||||
# include "windows/dirent.h"
|
||||
#else
|
||||
@ -217,6 +215,7 @@ static bool TerminalSupportsColor() {
|
||||
|
||||
namespace google {
|
||||
|
||||
GLOG_NO_EXPORT
|
||||
std::string StrError(int err);
|
||||
|
||||
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.
|
||||
const size_t LogMessage::kMaxLogMessageLen = 30000;
|
||||
|
||||
struct LogMessage::LogMessageData {
|
||||
namespace logging {
|
||||
namespace internal {
|
||||
struct LogMessageData {
|
||||
LogMessageData();
|
||||
|
||||
int preserved_errno_; // preserved errno
|
||||
// Buffer space; contains complete message text.
|
||||
char message_text_[LogMessage::kMaxLogMessageLen + 1];
|
||||
LogStream stream_;
|
||||
LogMessage::LogStream stream_;
|
||||
LogSeverity severity_; // What level is this LogMessage logged at?
|
||||
int line_; // line number where logging call is.
|
||||
void (LogMessage::*send_method_)(); // Call this in destructor to send
|
||||
@ -311,6 +312,8 @@ struct LogMessage::LogMessageData {
|
||||
LogMessageData(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
|
||||
// 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)
|
||||
static bool stop_writing = false;
|
||||
|
||||
const char* const LogSeverityNames[NUM_SEVERITIES] = {"INFO", "WARNING",
|
||||
"ERROR", "FATAL"};
|
||||
const char* const LogSeverityNames[] = {"INFO", "WARNING", "ERROR", "FATAL"};
|
||||
|
||||
// Has the user called SetExitOnDFatal(true)?
|
||||
static bool exit_on_dfatal = true;
|
||||
@ -547,7 +549,7 @@ class LogDestination {
|
||||
|
||||
// Wait for all registered sinks via WaitTillSent
|
||||
// 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);
|
||||
|
||||
@ -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_};
|
||||
if (sinks_) {
|
||||
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_;
|
||||
if (this_drop_length >= (2U << 20U)) {
|
||||
// Only advise when >= 2MiB to drop
|
||||
# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
|
||||
// 'posix_fadvise' introduced in API 21:
|
||||
// * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732
|
||||
# else
|
||||
# if defined(HAVE_POSIX_FADVISE)
|
||||
posix_fadvise(
|
||||
fileno(file_.get()), static_cast<off_t>(dropped_mem_length_),
|
||||
static_cast<off_t>(this_drop_length), POSIX_FADV_DONTNEED);
|
||||
@ -1488,8 +1488,8 @@ bool LogCleaner::IsLogLastModifiedOver(
|
||||
static std::mutex fatal_msg_lock;
|
||||
static logging::internal::CrashReason crash_reason;
|
||||
static bool fatal_msg_exclusive = true;
|
||||
static LogMessage::LogMessageData fatal_msg_data_exclusive;
|
||||
static LogMessage::LogMessageData fatal_msg_data_shared;
|
||||
static logging::internal::LogMessageData fatal_msg_data_exclusive;
|
||||
static logging::internal::LogMessageData fatal_msg_data_shared;
|
||||
|
||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||
// 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
|
||||
// std::aligned_storage is deprecated in C++23
|
||||
alignas(LogMessage::LogMessageData) static thread_local std::byte
|
||||
thread_msg_data[sizeof(LogMessage::LogMessageData)];
|
||||
alignas(logging::internal::LogMessageData) static thread_local std::byte
|
||||
thread_msg_data[sizeof(logging::internal::LogMessageData)];
|
||||
# else // !(defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L)
|
||||
static thread_local std::aligned_storage<
|
||||
sizeof(LogMessage::LogMessageData),
|
||||
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
|
||||
sizeof(logging::internal::LogMessageData),
|
||||
alignof(logging::internal::LogMessageData)>::type thread_msg_data;
|
||||
# endif // defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
|
||||
LogMessage::LogMessageData::LogMessageData()
|
||||
logging::internal::LogMessageData::LogMessageData()
|
||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
|
||||
LogMessage::LogMessage(const char* file, int line,
|
||||
const logging::internal::CheckOpString& result)
|
||||
: allocated_(nullptr) {
|
||||
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
|
||||
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.
|
||||
if (thread_data_available) {
|
||||
thread_data_available = false;
|
||||
data_ = new (&thread_msg_data) LogMessageData;
|
||||
data_ = new (&thread_msg_data) logging::internal::LogMessageData;
|
||||
} else {
|
||||
allocated_ = new LogMessageData();
|
||||
allocated_ = new logging::internal::LogMessageData();
|
||||
data_ = allocated_;
|
||||
}
|
||||
#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
allocated_ = new LogMessageData();
|
||||
allocated_ = new logging::internal::LogMessageData();
|
||||
data_ = allocated_;
|
||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
data_->first_fatal_ = false;
|
||||
@ -1828,7 +1829,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
|
||||
LogDestination::WaitForSinks(data_);
|
||||
|
||||
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.
|
||||
}
|
||||
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(const char* /*file*/, int /*line*/,
|
||||
const CheckOpString& /*result*/)
|
||||
const logging::internal::CheckOpString& /*result*/)
|
||||
: LogMessage::LogStream(message_buffer_, 2, 0) {}
|
||||
NullStream& NullStream::stream() { return *this; }
|
||||
|
||||
@ -2455,6 +2456,8 @@ void TruncateStdoutStderr() {
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace logging {
|
||||
namespace internal {
|
||||
// Helper functions for string comparisons.
|
||||
#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
|
||||
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_STRCASENE, strcasecmp, false)
|
||||
#undef DEFINE_CHECK_STROP_IMPL
|
||||
} // namespace internal
|
||||
} // namespace logging
|
||||
|
||||
// glibc has traditionally implemented two incompatible versions of
|
||||
// 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
|
||||
// given POSIX error code.
|
||||
GLOG_NO_EXPORT
|
||||
string StrError(int err) {
|
||||
char buf[100];
|
||||
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) {}
|
||||
|
||||
LogMessageFatal::LogMessageFatal(const char* file, int line,
|
||||
const CheckOpString& result)
|
||||
const logging::internal::CheckOpString& result)
|
||||
: LogMessage(file, line, result) {}
|
||||
|
||||
LogMessageFatal::~LogMessageFatal() {
|
||||
@ -2563,7 +2567,8 @@ LogMessageFatal::~LogMessageFatal() {
|
||||
LogMessage::Fail();
|
||||
}
|
||||
|
||||
namespace base {
|
||||
namespace logging {
|
||||
namespace internal {
|
||||
|
||||
CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext)
|
||||
: stream_(new ostringstream) {
|
||||
@ -2582,8 +2587,6 @@ string* CheckOpMessageBuilder::NewString() {
|
||||
return new string(stream_->str());
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
template <>
|
||||
void MakeCheckOpValueString(std::ostream* os, const char& v) {
|
||||
if (v >= 32 && v <= 126) {
|
||||
@ -2616,9 +2619,10 @@ void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
|
||||
(*os) << "nullptr";
|
||||
}
|
||||
|
||||
void InitGoogleLogging(const char* argv0) {
|
||||
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
|
||||
}
|
||||
} // namespace internal
|
||||
} // namespace logging
|
||||
|
||||
void InitGoogleLogging(const char* argv0) { InitGoogleLoggingUtilities(argv0); }
|
||||
|
||||
void InitGoogleLogging(const char* argv0, CustomPrefixCallback prefix_callback,
|
||||
void* prefix_callback_data) {
|
||||
@ -2628,7 +2632,7 @@ void InitGoogleLogging(const char* argv0, CustomPrefixCallback prefix_callback,
|
||||
}
|
||||
|
||||
void ShutdownGoogleLogging() {
|
||||
glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
|
||||
ShutdownGoogleLoggingUtilities();
|
||||
LogDestination::DeleteLogDestinations();
|
||||
logging_directories_list = nullptr;
|
||||
}
|
||||
|
||||
@ -61,6 +61,7 @@
|
||||
#include "glog/logging.h"
|
||||
#include "glog/raw_logging.h"
|
||||
#include "googletest.h"
|
||||
#include "stacktrace.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef GLOG_USE_GFLAGS
|
||||
|
||||
@ -33,29 +33,18 @@
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <thread>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h> // for close() and write()
|
||||
#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)
|
||||
# include <syscall.h> // for syscall()
|
||||
#elif defined(HAVE_SYS_SYSCALL_H)
|
||||
@ -64,6 +53,12 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#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)) && \
|
||||
(!(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
|
||||
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);
|
||||
|
||||
// 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
|
||||
// libc (to side-step any libc interception).
|
||||
// We write just once to avoid races with other invocations of RawLog__.
|
||||
safe_write(STDERR_FILENO, buffer, strlen(buffer));
|
||||
safe_write(fileno(stderr), buffer, strlen(buffer));
|
||||
if (severity == GLOG_FATAL) {
|
||||
std::call_once(crashed, [file, line, msg_start, msg_size] {
|
||||
crash_reason.filename = file;
|
||||
|
||||
@ -33,12 +33,15 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "config.h"
|
||||
#include "glog/logging.h"
|
||||
#include "glog/platform.h"
|
||||
#include "stacktrace.h"
|
||||
#include "symbolize.h"
|
||||
#include "utilities.h"
|
||||
@ -155,7 +158,7 @@ class MinimalFormatter {
|
||||
|
||||
// Writes the given data with the size to the standard error.
|
||||
void WriteToStderr(const char* data, size_t size) {
|
||||
if (write(STDERR_FILENO, data, size) < 0) {
|
||||
if (write(fileno(stderr), data, size) < 0) {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
@ -231,6 +234,7 @@ void DumpSignalInfo(int signal_number, siginfo_t* siginfo) {
|
||||
void DumpStackFrameInfo(const char* prefix, void* pc) {
|
||||
// Get the symbol name.
|
||||
const char* symbol = "(unknown)";
|
||||
#if defined(HAVE_SYMBOLIZE)
|
||||
char symbolized[1024]; // Big enough for a sane symbol.
|
||||
// Symbolizes the previous address of pc because pc may be in the
|
||||
// next function.
|
||||
@ -238,6 +242,10 @@ void DumpStackFrameInfo(const char* prefix, void* pc) {
|
||||
sizeof(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.
|
||||
MinimalFormatter formatter(buf, sizeof(buf));
|
||||
|
||||
@ -39,13 +39,21 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include "config.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
|
||||
# include <gflags/gflags.h>
|
||||
using namespace GFLAGS_NAMESPACE;
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
# include <io.h> // write
|
||||
#endif
|
||||
|
||||
using namespace google;
|
||||
|
||||
@ -59,7 +67,7 @@ static void DieInThread(int* a) {
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
//
|
||||
// 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
|
||||
// thread-safe.
|
||||
|
||||
#ifndef BASE_STACKTRACE_H_
|
||||
#define BASE_STACKTRACE_H_
|
||||
#ifndef GLOG_INTERNAL_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 "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 {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
#if defined(HAVE_STACKTRACE)
|
||||
|
||||
// This is similar to the GetStackFrames routine, except that it returns
|
||||
// the stack trace only, and not the stack frame sizes as well.
|
||||
@ -54,8 +87,11 @@ namespace google {
|
||||
// .... ...
|
||||
//
|
||||
// "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
|
||||
|
||||
#endif // BASE_STACKTRACE_H_
|
||||
#endif // GLOG_INTERNAL_STACKTRACE_H
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include "stacktrace.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// If you change this function, also change GetStackFrames below.
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -41,6 +41,7 @@ extern "C" {
|
||||
#include "stacktrace.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Sometimes, we can try to get a stack trace from within a stack
|
||||
// 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;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "stacktrace.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Given a pointer to a stack frame, locate and return the calling
|
||||
// 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;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -41,8 +41,6 @@
|
||||
# include <execinfo.h>
|
||||
#endif
|
||||
|
||||
using namespace google;
|
||||
|
||||
#ifdef HAVE_STACKTRACE
|
||||
|
||||
// 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]);
|
||||
INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
|
||||
DECLARE_ADDRESS_LABEL(start);
|
||||
size = GetStackTrace(stack, STACK_LEN, 0);
|
||||
size = google::GetStackTrace(stack, STACK_LEN, 0);
|
||||
printf("Obtained %d stack frames.\n", size);
|
||||
CHECK_GE(size, 1);
|
||||
CHECK_LE(size, STACK_LEN);
|
||||
@ -231,7 +229,7 @@ static
|
||||
|
||||
int main(int, char** argv) {
|
||||
FLAGS_logtostderr = true;
|
||||
InitGoogleLogging(argv[0]);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
CheckStackTrace(0);
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "stacktrace.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
struct trace_arg_t {
|
||||
void** result;
|
||||
@ -101,4 +102,5 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||
return targ.count;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -31,15 +31,13 @@
|
||||
//
|
||||
// Windows implementation - just use CaptureStackBackTrace
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h> // Must come before <dbghelp.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "config.h"
|
||||
#if defined(GLOG_USE_WINDOWS_PORT)
|
||||
# include "port.h"
|
||||
#endif
|
||||
#include "stacktrace.h"
|
||||
// clang-format on
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#include "stacktrace.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Given a pointer to a stack frame, locate and return the calling
|
||||
// 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;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -71,6 +71,7 @@
|
||||
# define GLOG_SAFE_ASSERT(expr) ((expr) ? 0 : (std::abort(), 0))
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
namespace {
|
||||
|
||||
@ -105,6 +106,7 @@ void InstallSymbolizeOpenObjectFileCallback(
|
||||
g_symbolize_open_object_file_callback = callback;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
# if defined(__ELF__)
|
||||
@ -135,6 +137,7 @@ void InstallSymbolizeOpenObjectFileCallback(
|
||||
# include "symbolize.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
namespace {
|
||||
|
||||
@ -822,6 +825,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
|
||||
@ -831,6 +835,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||
# include <cstring>
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||
void* pc, char* out, size_t out_size, SymbolizeOptions /*options*/) {
|
||||
@ -848,6 +853,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
|
||||
@ -856,6 +862,9 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(
|
||||
# include <windows.h>
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
namespace {
|
||||
|
||||
class SymInitializer final {
|
||||
public:
|
||||
@ -883,6 +892,8 @@ class SymInitializer final {
|
||||
SymInitializer& operator=(SymInitializer&&) = delete;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
|
||||
size_t out_size,
|
||||
SymbolizeOptions options) {
|
||||
@ -942,6 +953,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
# else
|
||||
@ -949,28 +961,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
|
||||
# endif
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
bool Symbolize(void* pc, char* out, size_t out_size, SymbolizeOptions options) {
|
||||
return SymbolizeAndDemangle(pc, out, out_size, options);
|
||||
}
|
||||
|
||||
} // namespace google
|
||||
|
||||
#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 glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
#endif
|
||||
|
||||
@ -51,14 +51,38 @@
|
||||
// malloc() and other unsafe operations. It should be both
|
||||
// thread-safe and async-signal-safe.
|
||||
|
||||
#ifndef BASE_SYMBOLIZE_H_
|
||||
#define BASE_SYMBOLIZE_H_
|
||||
#ifndef GLOG_INTERNAL_SYMBOLIZE_H
|
||||
#define GLOG_INTERNAL_SYMBOLIZE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include "config.h"
|
||||
#include "glog/logging.h"
|
||||
#include "utilities.h"
|
||||
#include "glog/platform.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
|
||||
|
||||
@ -69,7 +93,7 @@
|
||||
# include <elf.h>
|
||||
# endif
|
||||
|
||||
# if !defined(ANDROID)
|
||||
# if !defined(GLOG_OS_ANDROID)
|
||||
# include <link.h> // For ElfW() macro.
|
||||
# endif
|
||||
|
||||
@ -95,17 +119,21 @@
|
||||
# endif
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Gets the section header for the given name, if it exists. Returns true on
|
||||
// success. Otherwise, returns false.
|
||||
GLOG_NO_EXPORT
|
||||
bool GetSectionHeaderByName(int fd, const char* name, size_t name_len,
|
||||
ElfW(Shdr) * out);
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
# endif /* __ELF__ */
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
// Restrictions on the callbacks that follow:
|
||||
// - 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
|
||||
// function should return -1.
|
||||
using SymbolizeCallback = int (*)(int, void*, char*, size_t, uint64_t);
|
||||
GLOG_EXPORT
|
||||
GLOG_NO_EXPORT
|
||||
void InstallSymbolizeCallback(SymbolizeCallback callback);
|
||||
|
||||
// Installs a callback function, which will be called instead of
|
||||
@ -134,15 +162,19 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
|
||||
// (including the null-terminator).
|
||||
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&,
|
||||
char*, size_t);
|
||||
GLOG_EXPORT
|
||||
GLOG_NO_EXPORT
|
||||
void InstallSymbolizeOpenObjectFileCallback(
|
||||
SymbolizeOpenObjectFileCallback callback);
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
#if defined(HAVE_SYMBOLIZE)
|
||||
|
||||
enum class SymbolizeOptions {
|
||||
// No additional options.
|
||||
@ -169,9 +201,13 @@ constexpr SymbolizeOptions operator|(SymbolizeOptions lhs,
|
||||
// symbol name to "out". The symbol name is demangled if possible
|
||||
// (supports symbols generated by GCC 3.x or newer). Otherwise,
|
||||
// returns false.
|
||||
GLOG_EXPORT bool Symbolize(void* pc, char* out, size_t out_size,
|
||||
SymbolizeOptions options = SymbolizeOptions::kNone);
|
||||
GLOG_NO_EXPORT bool Symbolize(
|
||||
void* pc, char* out, size_t out_size,
|
||||
SymbolizeOptions options = SymbolizeOptions::kNone);
|
||||
|
||||
#endif // defined(HAVE_SYMBOLIZE)
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
#endif // BASE_SYMBOLIZE_H_
|
||||
#endif // GLOG_INTERNAL_SYMBOLIZE_H
|
||||
|
||||
@ -41,8 +41,12 @@
|
||||
|
||||
#include "base/googleinit.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>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
@ -88,7 +92,7 @@ void AlsoErrorWrite(LogSeverity severity, const char* tag,
|
||||
(void)tag;
|
||||
// On Windows, also output to the debugger
|
||||
::OutputDebugStringA(message);
|
||||
#elif defined(__ANDROID__)
|
||||
#elif defined(GLOG_OS_ANDROID)
|
||||
constexpr int android_log_levels[] = {
|
||||
ANDROID_LOG_INFO,
|
||||
ANDROID_LOG_WARN,
|
||||
@ -125,7 +129,7 @@ static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
|
||||
|
||||
static void DebugWriteToStderr(const char* data, void*) {
|
||||
// This one is signal-safe.
|
||||
if (write(STDERR_FILENO, data, strlen(data)) < 0) {
|
||||
if (write(fileno(stderr), data, strlen(data)) < 0) {
|
||||
// Ignore errors.
|
||||
}
|
||||
AlsoErrorWrite(GLOG_FATAL,
|
||||
@ -319,18 +323,4 @@ void ShutdownGoogleLoggingUtilities() {
|
||||
}
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
|
||||
} // 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.
|
||||
|
||||
#ifndef UTILITIES_H__
|
||||
#define UTILITIES_H__
|
||||
#ifndef GLOG_INTERNAL_UTILITIES_H
|
||||
#define GLOG_INTERNAL_UTILITIES_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
@ -60,18 +60,14 @@
|
||||
#define PRIXS __PRIS_PREFIX "X"
|
||||
#define PRIoS __PRIS_PREFIX "o"
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "glog/platform.h"
|
||||
#if defined(GLOG_USE_WINDOWS_PORT)
|
||||
# include "port.h"
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SSIZE_T)
|
||||
# if defined(GLOG_OS_WINDOWS)
|
||||
# include <basetsd.h>
|
||||
@ -81,6 +77,9 @@ using ssize_t = std::ptrdiff_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "glog/log_severity.h"
|
||||
#include "glog/types.h"
|
||||
|
||||
// There are three different ways we can try to get the stack trace:
|
||||
//
|
||||
// 1) The libunwind library. This is still in development, and as a
|
||||
@ -103,43 +102,6 @@ using ssize_t = std::ptrdiff_t;
|
||||
// correctly when GetStackTrace() is called with max_depth == 0.
|
||||
// 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
|
||||
// There is a better way, but this is good enough for our purpose.
|
||||
# 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); }
|
||||
};
|
||||
|
||||
#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.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@ -39,9 +39,7 @@
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "glog/raw_logging.h"
|
||||
#include "utilities.h"
|
||||
|
||||
// glog doesn't have annotation
|
||||
#define ANNOTATE_BENIGN_RACE(address, description)
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
* under the MIT license. For all details and documentation, see
|
||||
* https://github.com/tronkko/dirent
|
||||
*/
|
||||
#ifndef DIRENT_H
|
||||
#define DIRENT_H
|
||||
#ifndef GLOG_INTERNAL_WINDOWS_DIRENT_H
|
||||
#define GLOG_INTERNAL_WINDOWS_DIRENT_H
|
||||
|
||||
/* Hide warnings about unreferenced local functions */
|
||||
#if defined(__clang__)
|
||||
@ -1037,4 +1037,4 @@ static void dirent_set_errno(int error) {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*DIRENT_H*/
|
||||
#endif /*GLOG_INTERNAL_WINDOWS_DIRENT_H*/
|
||||
|
||||
@ -42,6 +42,9 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
|
||||
localtime_s(result, timep);
|
||||
@ -54,3 +57,6 @@ struct tm* gmtime_r(const std::time_t* timep, std::tm* result) {
|
||||
return result;
|
||||
}
|
||||
#endif // not HAVE_GMTIME_R
|
||||
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
@ -43,6 +43,14 @@
|
||||
|
||||
#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
|
||||
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
@ -62,8 +70,6 @@
|
||||
* used by both C and C++ code, so we put all the C++ together.
|
||||
*/
|
||||
|
||||
# include "glog/logging.h"
|
||||
|
||||
# ifdef _MSC_VER
|
||||
|
||||
/* 4244: otherwise we get problems when substracting two size_t's to an int
|
||||
@ -89,9 +95,6 @@
|
||||
# define O_CREAT _O_CREAT
|
||||
# define O_EXCL _O_EXCL
|
||||
|
||||
# ifndef __MINGW32__
|
||||
enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
|
||||
# endif
|
||||
# define S_IRUSR S_IREAD
|
||||
# define S_IWUSR S_IWRITE
|
||||
|
||||
@ -116,24 +119,23 @@ enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
|
||||
|
||||
# endif // _MSC_VER
|
||||
|
||||
namespace google {
|
||||
inline namespace glog_internal_namespace_ {
|
||||
# ifndef HAVE_LOCALTIME_R
|
||||
extern GLOG_EXPORT std::tm* localtime_r(const std::time_t* timep,
|
||||
std::tm* result);
|
||||
GLOG_NO_EXPORT std::tm* localtime_r(const std::time_t* timep, std::tm* result);
|
||||
# endif // not HAVE_LOCALTIME_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
|
||||
|
||||
GLOG_NO_EXPORT
|
||||
inline char* strerror_r(int errnum, char* buf, std::size_t buflen) {
|
||||
strerror_s(buf, buflen, errnum);
|
||||
return buf;
|
||||
}
|
||||
|
||||
# ifndef __cplusplus
|
||||
/* I don't see how to get inlining for C code in MSVC. Ah well. */
|
||||
# define inline
|
||||
# endif
|
||||
} // namespace glog_internal_namespace_
|
||||
} // namespace google
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user