chore: apply clang-format

This commit is contained in:
Sergiu Deitsch 2023-12-30 20:01:33 +01:00
parent e3f5398aa1
commit 93549f3600
43 changed files with 2661 additions and 2791 deletions

View File

@ -58,7 +58,7 @@ ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
@ -84,7 +84,7 @@ IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentPPDirectives: AfterHash
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave

View File

@ -48,63 +48,64 @@
#ifndef BASE_COMMANDLINEFLAGS_H__
#define BASE_COMMANDLINEFLAGS_H__
#include "config.h"
#include <cstdlib> // for getenv
#include <cstring> // for memchr
#include <cstdlib> // for getenv
#include <cstring> // for memchr
#include <string>
#include "config.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
#else
#include "glog/logging.h"
# include "glog/logging.h"
#define DECLARE_VARIABLE(type, shorttype, name, tn) \
namespace fL##shorttype { \
extern GLOG_EXPORT type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name
#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \
namespace fL##shorttype { \
GLOG_EXPORT type FLAGS_##name(value); \
char FLAGS_no##name; \
} \
using fL##shorttype::FLAGS_##name
# define DECLARE_VARIABLE(type, shorttype, name, tn) \
namespace fL##shorttype { \
extern GLOG_EXPORT type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name
# define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \
namespace fL##shorttype { \
GLOG_EXPORT type FLAGS_##name(value); \
char FLAGS_no##name; \
} \
using fL##shorttype::FLAGS_##name
// bool specialization
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name, bool)
#define DEFINE_bool(name, value, meaning) \
DEFINE_VARIABLE(bool, B, name, value, meaning, bool)
# define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name, bool)
# define DEFINE_bool(name, value, meaning) \
DEFINE_VARIABLE(bool, B, name, value, meaning, bool)
// int32 specialization
#define DECLARE_int32(name) DECLARE_VARIABLE(google::int32, I, name, int32)
#define DEFINE_int32(name, value, meaning) \
DEFINE_VARIABLE(google::int32, I, name, value, meaning, int32)
# define DECLARE_int32(name) DECLARE_VARIABLE(google::int32, I, name, int32)
# define DEFINE_int32(name, value, meaning) \
DEFINE_VARIABLE(google::int32, I, name, value, meaning, int32)
// uint32 specialization
#ifndef DECLARE_uint32
#define DECLARE_uint32(name) DECLARE_VARIABLE(google::uint32, U, name, uint32)
#endif // DECLARE_uint64
#define DEFINE_uint32(name, value, meaning) \
DEFINE_VARIABLE(google::uint32, U, name, value, meaning, uint32)
# ifndef DECLARE_uint32
# define DECLARE_uint32(name) \
DECLARE_VARIABLE(google::uint32, U, name, uint32)
# endif // DECLARE_uint64
# define DEFINE_uint32(name, value, meaning) \
DEFINE_VARIABLE(google::uint32, U, name, value, meaning, uint32)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
#define DECLARE_string(name) \
namespace fLS { \
extern GLOG_EXPORT std::string& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#define DEFINE_string(name, value, meaning) \
namespace fLS { \
std::string FLAGS_##name##_buf(value); \
GLOG_EXPORT std::string& FLAGS_##name = FLAGS_##name##_buf; \
char FLAGS_no##name; \
} \
using fLS::FLAGS_##name
# define DECLARE_string(name) \
namespace fLS { \
extern GLOG_EXPORT std::string& FLAGS_##name; \
} \
using fLS::FLAGS_##name
# define DEFINE_string(name, value, meaning) \
namespace fLS { \
std::string FLAGS_##name##_buf(value); \
GLOG_EXPORT std::string& FLAGS_##name = FLAGS_##name##_buf; \
char FLAGS_no##name; \
} \
using fLS::FLAGS_##name
#endif // GLOG_USE_GFLAGS
@ -130,8 +131,7 @@
// These macros (could be functions, but I don't want to bother with a .cc
// file), make it easier to initialize flags from the environment.
#define EnvToString(envname, dflt) \
(!getenv(envname) ? (dflt) : getenv(envname))
#define EnvToString(envname, dflt) (!getenv(envname) ? (dflt) : getenv(envname))
#define EnvToBool(envname, dflt) \
(!getenv(envname) ? (dflt) \

View File

@ -36,16 +36,14 @@
class GoogleInitializer {
public:
using void_function = void (*)();
GoogleInitializer(const char*, void_function f) {
f();
}
GoogleInitializer(const char*, void_function f) { f(); }
};
#define REGISTER_MODULE_INITIALIZER(name, body) \
namespace { \
static void google_init_module_##name () { body; } \
GoogleInitializer google_initializer_module_##name(#name, \
google_init_module_##name); \
#define REGISTER_MODULE_INITIALIZER(name, body) \
namespace { \
static void google_init_module_##name() { body; } \
GoogleInitializer google_initializer_module_##name( \
#name, google_init_module_##name); \
}
#endif /* _GOOGLEINIT_H */

View File

@ -102,55 +102,56 @@
#ifndef GOOGLE_MUTEX_H_
#define GOOGLE_MUTEX_H_
#include "config.h" // to figure out pthreads support
#include "config.h" // to figure out pthreads support
#if defined(NO_THREADS)
typedef int MutexType; // to keep a lock-count
typedef int MutexType; // to keep a lock-count
#elif defined(_WIN32) || defined(__CYGWIN__)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN // We only need minimal includes
# endif
# ifdef GMUTEX_TRYLOCK
// We need Windows NT or later for TryEnterCriticalSection(). If you
// don't need that functionality, you can remove these _WIN32_WINNT
// lines, and change TryLock() to assert(0) or something.
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
# endif
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN // We only need minimal includes
# endif
# ifdef GMUTEX_TRYLOCK
// We need Windows NT or later for TryEnterCriticalSection(). If you
// don't need that functionality, you can remove these _WIN32_WINNT
// lines, and change TryLock() to assert(0) or something.
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
# endif
# endif
// To avoid macro definition of ERROR.
# ifndef NOGDI
# define NOGDI
# endif
# ifndef NOGDI
# define NOGDI
# endif
// To avoid macro definition of min/max.
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
typedef CRITICAL_SECTION MutexType;
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
typedef CRITICAL_SECTION MutexType;
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
// Needed for pthread_rwlock_*. If it causes problems, you could take it
// out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
// *does* cause problems for FreeBSD, or MacOSX, but isn't needed
// for locking there.)
# ifdef __linux__
# ifndef _XOPEN_SOURCE // Some other header might have already set it for us.
# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
# endif
# endif
# include <pthread.h>
// Needed for pthread_rwlock_*. If it causes problems, you could take it
// out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
// *does* cause problems for FreeBSD, or MacOSX, but isn't needed
// for locking there.)
# ifdef __linux__
# ifndef _XOPEN_SOURCE // Some other header might have already set it for
// us.
# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
# endif
# endif
# include <pthread.h>
using MutexType = pthread_rwlock_t;
#elif defined(HAVE_PTHREAD)
# include <pthread.h>
typedef pthread_mutex_t MutexType;
# include <pthread.h>
typedef pthread_mutex_t MutexType;
#else
# error Need to implement mutex.h for your architecture, or #define NO_THREADS
# error Need to implement mutex.h for your architecture, or #define NO_THREADS
#endif
// We need to include these header files after defining _XOPEN_SOURCE
// as they may define the _XOPEN_SOURCE macro.
#include <cassert>
#include <cstdlib> // for abort()
#include <cstdlib> // for abort()
#define MUTEX_NAMESPACE glog_internal_namespace_
@ -170,16 +171,16 @@ class Mutex {
inline void Lock(); // Block if needed until free then acquire exclusively
inline void Unlock(); // Release a lock acquired via Lock()
#ifdef GMUTEX_TRYLOCK
inline bool TryLock(); // If free, Lock() and return true, else return false
inline bool TryLock(); // If free, Lock() and return true, else return false
#endif
// Note that on systems that don't support read-write locks, these may
// be implemented as synonyms to Lock() and Unlock(). So you can use
// these for efficiency, but don't use them anyplace where being able
// to do shared reads is necessary to avoid deadlock.
inline void ReaderLock(); // Block until free or shared then acquire a share
inline void ReaderUnlock(); // Release a read share of this Mutex
inline void WriterLock() { Lock(); } // Acquire an exclusive lock
inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
inline void ReaderLock(); // Block until free or shared then acquire a share
inline void ReaderUnlock(); // Release a read share of this Mutex
inline void WriterLock() { Lock(); } // Acquire an exclusive lock
inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
// TODO(hamaji): Do nothing, implement correctly.
inline void AssertHeld() {}
@ -194,10 +195,10 @@ class Mutex {
inline void SetIsSafe() { is_safe_ = true; }
// Catch the error of writing Mutex when intending MutexLock.
explicit Mutex(Mutex * /*ignored*/) {}
explicit Mutex(Mutex* /*ignored*/) {}
// Disallow "evil" constructors
Mutex(const Mutex &) = delete;
void operator=(const Mutex &) = delete;
Mutex(const Mutex&) = delete;
void operator=(const Mutex&) = delete;
};
// Now the implementation of Mutex for various systems
@ -213,71 +214,86 @@ class Mutex {
// we do nothing, for efficiency. That's why everything is in an
// assert.
Mutex::Mutex() : mutex_(0) { }
Mutex::~Mutex() { assert(mutex_ == 0); }
void Mutex::Lock() { assert(--mutex_ == -1); }
void Mutex::Unlock() { assert(mutex_++ == -1); }
#ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
#endif
void Mutex::ReaderLock() { assert(++mutex_ > 0); }
Mutex::Mutex() : mutex_(0) {}
Mutex::~Mutex() { assert(mutex_ == 0); }
void Mutex::Lock() { assert(--mutex_ == -1); }
void Mutex::Unlock() { assert(mutex_++ == -1); }
# ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() {
if (mutex_) return false;
Lock();
return true;
}
# endif
void Mutex::ReaderLock() { assert(++mutex_ > 0); }
void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
#elif defined(_WIN32) || defined(__CYGWIN__)
Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); }
Mutex::~Mutex() { DeleteCriticalSection(&mutex_); }
void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); }
void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); }
#ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() { return is_safe_ ?
TryEnterCriticalSection(&mutex_) != 0 : true; }
#endif
void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
Mutex::Mutex() {
InitializeCriticalSection(&mutex_);
SetIsSafe();
}
Mutex::~Mutex() { DeleteCriticalSection(&mutex_); }
void Mutex::Lock() {
if (is_safe_) EnterCriticalSection(&mutex_);
}
void Mutex::Unlock() {
if (is_safe_) LeaveCriticalSection(&mutex_);
}
# ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() {
return is_safe_ ? TryEnterCriticalSection(&mutex_) != 0 : true;
}
# endif
void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
void Mutex::ReaderUnlock() { Unlock(); }
#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
} while (0)
# define SAFE_PTHREAD(fncall) \
do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
} while (0)
Mutex::Mutex() {
SetIsSafe();
if (is_safe_ && pthread_rwlock_init(&mutex_, nullptr) != 0) abort();
}
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
#ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() { return is_safe_ ?
pthread_rwlock_trywrlock(&mutex_) == 0 :
true; }
#endif
void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); }
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
# ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() {
return is_safe_ ? pthread_rwlock_trywrlock(&mutex_) == 0 : true;
}
# endif
void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); }
void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
#undef SAFE_PTHREAD
# undef SAFE_PTHREAD
#elif defined(HAVE_PTHREAD)
#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
} while (0)
# define SAFE_PTHREAD(fncall) \
do { /* run fncall if is_safe_ is true */ \
if (is_safe_ && fncall(&mutex_) != 0) abort(); \
} while (0)
Mutex::Mutex() {
Mutex::Mutex() {
SetIsSafe();
if (is_safe_ && pthread_mutex_init(&mutex_, nullptr) != 0) abort();
}
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); }
#ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() { return is_safe_ ?
pthread_mutex_trylock(&mutex_) == 0 : true; }
#endif
void Mutex::ReaderLock() { Lock(); }
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); }
# ifdef GMUTEX_TRYLOCK
bool Mutex::TryLock() {
return is_safe_ ? pthread_mutex_trylock(&mutex_) == 0 : true;
}
# endif
void Mutex::ReaderLock() { Lock(); }
void Mutex::ReaderUnlock() { Unlock(); }
#undef SAFE_PTHREAD
# undef SAFE_PTHREAD
#endif
@ -287,36 +303,39 @@ void Mutex::ReaderUnlock() { Unlock(); }
// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
class MutexLock {
public:
explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
explicit MutexLock(Mutex* mu) : mu_(mu) { mu_->Lock(); }
~MutexLock() { mu_->Unlock(); }
private:
Mutex * const mu_;
Mutex* const mu_;
// Disallow "evil" constructors
MutexLock(const MutexLock &) = delete;
void operator=(const MutexLock &) = delete;
MutexLock(const MutexLock&) = delete;
void operator=(const MutexLock&) = delete;
};
// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
class ReaderMutexLock {
public:
explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
explicit ReaderMutexLock(Mutex* mu) : mu_(mu) { mu_->ReaderLock(); }
~ReaderMutexLock() { mu_->ReaderUnlock(); }
private:
Mutex * const mu_;
Mutex* const mu_;
// Disallow "evil" constructors
ReaderMutexLock(const ReaderMutexLock &) = delete;
void operator=(const ReaderMutexLock &) = delete;
ReaderMutexLock(const ReaderMutexLock&) = delete;
void operator=(const ReaderMutexLock&) = delete;
};
class WriterMutexLock {
public:
explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
explicit WriterMutexLock(Mutex* mu) : mu_(mu) { mu_->WriterLock(); }
~WriterMutexLock() { mu_->WriterUnlock(); }
private:
Mutex * const mu_;
Mutex* const mu_;
// Disallow "evil" constructors
WriterMutexLock(const WriterMutexLock &) = delete;
void operator=(const WriterMutexLock &) = delete;
WriterMutexLock(const WriterMutexLock&) = delete;
void operator=(const WriterMutexLock&) = delete;
};
// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
@ -330,4 +349,4 @@ using namespace MUTEX_NAMESPACE;
#undef MUTEX_NAMESPACE
#endif /* #define GOOGLE_MUTEX_H__ */
#endif /* #define GOOGLE_MUTEX_H__ */

View File

@ -33,14 +33,14 @@
#include "googletest.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
#ifdef HAVE_LIB_GMOCK
#include <gmock/gmock.h>
# include <gmock/gmock.h>
#include "mock-log.h"
# include "mock-log.h"
// Introduce several symbols from gmock.
using google::glog_testing::ScopedMockLog;
using testing::_;
@ -65,7 +65,7 @@ TEST(CleanImmediately, logging) {
google::DisableLogCleaner();
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
FLAGS_colorlogtostderr = false;
FLAGS_timestamp_in_logfile_name = true;
#ifdef GLOG_USE_GFLAGS

View File

@ -33,14 +33,14 @@
#include "googletest.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
#ifdef HAVE_LIB_GMOCK
#include <gmock/gmock.h>
# include <gmock/gmock.h>
#include "mock-log.h"
# include "mock-log.h"
// Introduce several symbols from gmock.
using google::glog_testing::ScopedMockLog;
using testing::_;
@ -70,7 +70,7 @@ TEST(CleanImmediatelyWithAbsolutePrefix, logging) {
google::DisableLogCleaner();
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
FLAGS_colorlogtostderr = false;
FLAGS_timestamp_in_logfile_name = true;
#ifdef GLOG_USE_GFLAGS

View File

@ -33,14 +33,14 @@
#include "googletest.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
#ifdef HAVE_LIB_GMOCK
#include <gmock/gmock.h>
# include <gmock/gmock.h>
#include "mock-log.h"
# include "mock-log.h"
// Introduce several symbols from gmock.
using google::glog_testing::ScopedMockLog;
using testing::_;
@ -66,7 +66,7 @@ TEST(CleanImmediatelyWithRelativePrefix, logging) {
google::DisableLogCleaner();
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
FLAGS_colorlogtostderr = false;
FLAGS_timestamp_in_logfile_name = true;
#ifdef GLOG_USE_GFLAGS

View File

@ -43,15 +43,15 @@
#include "utilities.h"
#if defined(GLOG_OS_WINDOWS)
#include <dbghelp.h>
# include <dbghelp.h>
#endif
namespace google {
#if !defined(GLOG_OS_WINDOWS)
struct AbbrevPair {
const char *abbrev;
const char *real_name;
const char* abbrev;
const char* real_name;
};
// List of operators from Itanium C++ ABI.
@ -102,11 +102,11 @@ static const AbbrevPair kSubstitutionList[] = {
// State needed for demangling.
struct State {
const char *mangled_cur; // Cursor of mangled name.
char *out_cur; // Cursor of output string.
const char *out_begin; // Beginning of output string.
const char *out_end; // End of output string.
const char *prev_name; // For constructors/destructors.
const char* mangled_cur; // Cursor of mangled name.
char* out_cur; // Cursor of output string.
const char* out_begin; // Beginning of output string.
const char* out_end; // End of output string.
const char* prev_name; // For constructors/destructors.
ssize_t prev_name_length; // For constructors/destructors.
short nest_level; // For nested names.
bool append; // Append flag.
@ -118,7 +118,7 @@ struct State {
// We don't use strlen() in libc since it's not guaranteed to be async
// signal safe.
static size_t StrLen(const char *str) {
static size_t StrLen(const char* str) {
size_t len = 0;
while (*str != '\0') {
++str;
@ -128,7 +128,7 @@ static size_t StrLen(const char *str) {
}
// Returns true if "str" has at least "n" characters remaining.
static bool AtLeastNumCharsRemaining(const char *str, ssize_t n) {
static bool AtLeastNumCharsRemaining(const char* str, ssize_t n) {
for (ssize_t i = 0; i < n; ++i) {
if (str[i] == '\0') {
return false;
@ -138,17 +138,16 @@ static bool AtLeastNumCharsRemaining(const char *str, ssize_t n) {
}
// Returns true if "str" has "prefix" as a prefix.
static bool StrPrefix(const char *str, const char *prefix) {
static bool StrPrefix(const char* str, const char* prefix) {
size_t i = 0;
while (str[i] != '\0' && prefix[i] != '\0' &&
str[i] == prefix[i]) {
while (str[i] != '\0' && prefix[i] != '\0' && str[i] == prefix[i]) {
++i;
}
return prefix[i] == '\0'; // Consumed everything in "prefix".
}
static void InitState(State *state, const char *mangled,
char *out, size_t out_size) {
static void InitState(State* state, const char* mangled, char* out,
size_t out_size) {
state->mangled_cur = mangled;
state->out_cur = out;
state->out_begin = out;
@ -166,7 +165,7 @@ static void InitState(State *state, const char *mangled,
// Returns true and advances "mangled_cur" if we find "one_char_token"
// at "mangled_cur" position. It is assumed that "one_char_token" does
// not contain '\0'.
static bool ParseOneCharToken(State *state, const char one_char_token) {
static bool ParseOneCharToken(State* state, const char one_char_token) {
if (state->mangled_cur[0] == one_char_token) {
++state->mangled_cur;
return true;
@ -177,7 +176,7 @@ static bool ParseOneCharToken(State *state, const char one_char_token) {
// Returns true and advances "mangled_cur" if we find "two_char_token"
// at "mangled_cur" position. It is assumed that "two_char_token" does
// not contain '\0'.
static bool ParseTwoCharToken(State *state, const char *two_char_token) {
static bool ParseTwoCharToken(State* state, const char* two_char_token) {
if (state->mangled_cur[0] == two_char_token[0] &&
state->mangled_cur[1] == two_char_token[1]) {
state->mangled_cur += 2;
@ -188,8 +187,8 @@ static bool ParseTwoCharToken(State *state, const char *two_char_token) {
// Returns true and advances "mangled_cur" if we find any character in
// "char_class" at "mangled_cur" position.
static bool ParseCharClass(State *state, const char *char_class) {
const char *p = char_class;
static bool ParseCharClass(State* state, const char* char_class) {
const char* p = char_class;
for (; *p != '\0'; ++p) {
if (state->mangled_cur[0] == *p) {
++state->mangled_cur;
@ -200,13 +199,11 @@ static bool ParseCharClass(State *state, const char *char_class) {
}
// This function is used for handling an optional non-terminal.
static bool Optional(bool) {
return true;
}
static bool Optional(bool) { return true; }
// This function is used for handling <non-terminal>+ syntax.
using ParseFunc = bool (*)(State *);
static bool OneOrMore(ParseFunc parse_func, State *state) {
using ParseFunc = bool (*)(State*);
static bool OneOrMore(ParseFunc parse_func, State* state) {
if (parse_func(state)) {
while (parse_func(state)) {
}
@ -219,7 +216,7 @@ static bool OneOrMore(ParseFunc parse_func, State *state) {
// always returns true and must be followed by a termination token or a
// terminating sequence not handled by parse_func (e.g.
// ParseOneCharToken(state, 'E')).
static bool ZeroOrMore(ParseFunc parse_func, State *state) {
static bool ZeroOrMore(ParseFunc parse_func, State* state) {
while (parse_func(state)) {
}
return true;
@ -228,7 +225,7 @@ static bool ZeroOrMore(ParseFunc parse_func, State *state) {
// Append "str" at "out_cur". If there is an overflow, "overflowed"
// is set to true for later use. The output string is ensured to
// always terminate with '\0' as long as there is no overflow.
static void Append(State *state, const char * const str, ssize_t length) {
static void Append(State* state, const char* const str, ssize_t length) {
if (state->out_cur == nullptr) {
state->overflowed = true;
return;
@ -248,23 +245,19 @@ static void Append(State *state, const char * const str, ssize_t length) {
}
// We don't use equivalents in libc to avoid locale issues.
static bool IsLower(char c) {
return c >= 'a' && c <= 'z';
}
static bool IsLower(char c) { return c >= 'a' && c <= 'z'; }
static bool IsAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
static bool IsDigit(char c) {
return c >= '0' && c <= '9';
}
static bool IsDigit(char c) { return c >= '0' && c <= '9'; }
// Returns true if "str" is a function clone suffix. These suffixes are used
// by GCC 4.5.x and later versions to indicate functions which have been
// cloned during optimization. We treat any sequence (.<alpha>+.<digit>+)+ as
// a function clone suffix.
static bool IsFunctionCloneSuffix(const char *str) {
static bool IsFunctionCloneSuffix(const char* str) {
size_t i = 0;
while (str[i] != '\0') {
// Consume a single .<alpha>+.<digit>+ sequence.
@ -288,12 +281,12 @@ static bool IsFunctionCloneSuffix(const char *str) {
// Append "str" with some tweaks, iff "append" state is true.
// Returns true so that it can be placed in "if" conditions.
static void MaybeAppendWithLength(State *state, const char * const str,
static void MaybeAppendWithLength(State* state, const char* const str,
ssize_t length) {
if (state->append && length > 0) {
// Append a space if the output buffer ends with '<' and "str"
// starts with '<' to avoid <<<.
if (str[0] == '<' && state->out_begin < state->out_cur &&
if (str[0] == '<' && state->out_begin < state->out_cur &&
state->out_cur[-1] == '<') {
Append(state, " ", 1);
}
@ -307,7 +300,7 @@ static void MaybeAppendWithLength(State *state, const char * const str,
}
// A convenient wrapper around MaybeAppendWithLength().
static bool MaybeAppend(State *state, const char * const str) {
static bool MaybeAppend(State* state, const char* const str) {
if (state->append) {
size_t length = StrLen(str);
MaybeAppendWithLength(state, str, static_cast<ssize_t>(length));
@ -316,45 +309,45 @@ static bool MaybeAppend(State *state, const char * const str) {
}
// This function is used for handling nested names.
static bool EnterNestedName(State *state) {
static bool EnterNestedName(State* state) {
state->nest_level = 0;
return true;
}
// This function is used for handling nested names.
static bool LeaveNestedName(State *state, short prev_value) {
static bool LeaveNestedName(State* state, short prev_value) {
state->nest_level = prev_value;
return true;
}
// Disable the append mode not to print function parameters, etc.
static bool DisableAppend(State *state) {
static bool DisableAppend(State* state) {
state->append = false;
return true;
}
// Restore the append mode to the previous state.
static bool RestoreAppend(State *state, bool prev_value) {
static bool RestoreAppend(State* state, bool prev_value) {
state->append = prev_value;
return true;
}
// Increase the nest level for nested names.
static void MaybeIncreaseNestLevel(State *state) {
static void MaybeIncreaseNestLevel(State* state) {
if (state->nest_level > -1) {
++state->nest_level;
}
}
// Appends :: for nested names if necessary.
static void MaybeAppendSeparator(State *state) {
static void MaybeAppendSeparator(State* state) {
if (state->nest_level >= 1) {
MaybeAppend(state, "::");
}
}
// Cancel the last separator if necessary.
static void MaybeCancelLastSeparator(State *state) {
static void MaybeCancelLastSeparator(State* state) {
if (state->nest_level >= 1 && state->append &&
state->out_begin <= state->out_cur - 2) {
state->out_cur -= 2;
@ -364,7 +357,7 @@ static void MaybeCancelLastSeparator(State *state) {
// Returns true if the identifier of the given length pointed to by
// "mangled_cur" is anonymous namespace.
static bool IdentifierIsAnonymousNamespace(State *state, ssize_t length) {
static bool IdentifierIsAnonymousNamespace(State* state, ssize_t length) {
static const char anon_prefix[] = "_GLOBAL__N_";
return (length > static_cast<ssize_t>(sizeof(anon_prefix)) -
1 && // Should be longer.
@ -372,45 +365,45 @@ static bool IdentifierIsAnonymousNamespace(State *state, ssize_t length) {
}
// Forward declarations of our parsing functions.
static bool ParseMangledName(State *state);
static bool ParseEncoding(State *state);
static bool ParseName(State *state);
static bool ParseUnscopedName(State *state);
static bool ParseUnscopedTemplateName(State *state);
static bool ParseNestedName(State *state);
static bool ParsePrefix(State *state);
static bool ParseUnqualifiedName(State *state);
static bool ParseSourceName(State *state);
static bool ParseLocalSourceName(State *state);
static bool ParseNumber(State *state, int *number_out);
static bool ParseFloatNumber(State *state);
static bool ParseSeqId(State *state);
static bool ParseIdentifier(State *state, ssize_t length);
static bool ParseAbiTags(State *state);
static bool ParseAbiTag(State *state);
static bool ParseOperatorName(State *state);
static bool ParseSpecialName(State *state);
static bool ParseCallOffset(State *state);
static bool ParseNVOffset(State *state);
static bool ParseVOffset(State *state);
static bool ParseCtorDtorName(State *state);
static bool ParseType(State *state);
static bool ParseCVQualifiers(State *state);
static bool ParseBuiltinType(State *state);
static bool ParseFunctionType(State *state);
static bool ParseBareFunctionType(State *state);
static bool ParseClassEnumType(State *state);
static bool ParseArrayType(State *state);
static bool ParsePointerToMemberType(State *state);
static bool ParseTemplateParam(State *state);
static bool ParseTemplateTemplateParam(State *state);
static bool ParseTemplateArgs(State *state);
static bool ParseTemplateArg(State *state);
static bool ParseExpression(State *state);
static bool ParseExprPrimary(State *state);
static bool ParseLocalName(State *state);
static bool ParseDiscriminator(State *state);
static bool ParseSubstitution(State *state);
static bool ParseMangledName(State* state);
static bool ParseEncoding(State* state);
static bool ParseName(State* state);
static bool ParseUnscopedName(State* state);
static bool ParseUnscopedTemplateName(State* state);
static bool ParseNestedName(State* state);
static bool ParsePrefix(State* state);
static bool ParseUnqualifiedName(State* state);
static bool ParseSourceName(State* state);
static bool ParseLocalSourceName(State* state);
static bool ParseNumber(State* state, int* number_out);
static bool ParseFloatNumber(State* state);
static bool ParseSeqId(State* state);
static bool ParseIdentifier(State* state, ssize_t length);
static bool ParseAbiTags(State* state);
static bool ParseAbiTag(State* state);
static bool ParseOperatorName(State* state);
static bool ParseSpecialName(State* state);
static bool ParseCallOffset(State* state);
static bool ParseNVOffset(State* state);
static bool ParseVOffset(State* state);
static bool ParseCtorDtorName(State* state);
static bool ParseType(State* state);
static bool ParseCVQualifiers(State* state);
static bool ParseBuiltinType(State* state);
static bool ParseFunctionType(State* state);
static bool ParseBareFunctionType(State* state);
static bool ParseClassEnumType(State* state);
static bool ParseArrayType(State* state);
static bool ParsePointerToMemberType(State* state);
static bool ParseTemplateParam(State* state);
static bool ParseTemplateTemplateParam(State* state);
static bool ParseTemplateArgs(State* state);
static bool ParseTemplateArg(State* state);
static bool ParseExpression(State* state);
static bool ParseExprPrimary(State* state);
static bool ParseLocalName(State* state);
static bool ParseDiscriminator(State* state);
static bool ParseSubstitution(State* state);
// Implementation note: the following code is a straightforward
// translation of the Itanium C++ ABI defined in BNF with a couple of
@ -443,14 +436,14 @@ static bool ParseSubstitution(State *state);
// <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
// <mangled-name> ::= _Z <encoding>
static bool ParseMangledName(State *state) {
static bool ParseMangledName(State* state) {
return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
}
// <encoding> ::= <(function) name> <bare-function-type>
// ::= <(data) name>
// ::= <special-name>
static bool ParseEncoding(State *state) {
static bool ParseEncoding(State* state) {
State copy = *state;
if (ParseName(state) && ParseBareFunctionType(state)) {
return true;
@ -467,14 +460,13 @@ static bool ParseEncoding(State *state) {
// ::= <unscoped-template-name> <template-args>
// ::= <unscoped-name>
// ::= <local-name>
static bool ParseName(State *state) {
static bool ParseName(State* state) {
if (ParseNestedName(state) || ParseLocalName(state)) {
return true;
}
State copy = *state;
if (ParseUnscopedTemplateName(state) &&
ParseTemplateArgs(state)) {
if (ParseUnscopedTemplateName(state) && ParseTemplateArgs(state)) {
return true;
}
*state = copy;
@ -488,14 +480,13 @@ static bool ParseName(State *state) {
// <unscoped-name> ::= <unqualified-name>
// ::= St <unqualified-name>
static bool ParseUnscopedName(State *state) {
static bool ParseUnscopedName(State* state) {
if (ParseUnqualifiedName(state)) {
return true;
}
State copy = *state;
if (ParseTwoCharToken(state, "St") &&
MaybeAppend(state, "std::") &&
if (ParseTwoCharToken(state, "St") && MaybeAppend(state, "std::") &&
ParseUnqualifiedName(state)) {
return true;
}
@ -505,18 +496,16 @@ static bool ParseUnscopedName(State *state) {
// <unscoped-template-name> ::= <unscoped-name>
// ::= <substitution>
static bool ParseUnscopedTemplateName(State *state) {
static bool ParseUnscopedTemplateName(State* state) {
return ParseUnscopedName(state) || ParseSubstitution(state);
}
// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
// ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
static bool ParseNestedName(State *state) {
static bool ParseNestedName(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'N') &&
EnterNestedName(state) &&
Optional(ParseCVQualifiers(state)) &&
ParsePrefix(state) &&
if (ParseOneCharToken(state, 'N') && EnterNestedName(state) &&
Optional(ParseCVQualifiers(state)) && ParsePrefix(state) &&
LeaveNestedName(state, copy.nest_level) &&
ParseOneCharToken(state, 'E')) {
return true;
@ -536,12 +525,11 @@ static bool ParseNestedName(State *state) {
// <template-prefix> ::= <prefix> <(template) unqualified-name>
// ::= <template-param>
// ::= <substitution>
static bool ParsePrefix(State *state) {
static bool ParsePrefix(State* state) {
bool has_something = false;
while (true) {
MaybeAppendSeparator(state);
if (ParseTemplateParam(state) ||
ParseSubstitution(state) ||
if (ParseTemplateParam(state) || ParseSubstitution(state) ||
ParseUnscopedName(state)) {
has_something = true;
MaybeIncreaseNestLevel(state);
@ -561,15 +549,14 @@ static bool ParsePrefix(State *state) {
// ::= <ctor-dtor-name>
// ::= <source-name> [<abi-tags>]
// ::= <local-source-name> [<abi-tags>]
static bool ParseUnqualifiedName(State *state) {
return (ParseOperatorName(state) ||
ParseCtorDtorName(state) ||
static bool ParseUnqualifiedName(State* state) {
return (ParseOperatorName(state) || ParseCtorDtorName(state) ||
(ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
(ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
}
// <source-name> ::= <positive length number> <identifier>
static bool ParseSourceName(State *state) {
static bool ParseSourceName(State* state) {
State copy = *state;
int length = -1;
if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
@ -584,7 +571,7 @@ static bool ParseSourceName(State *state) {
// References:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
// http://gcc.gnu.org/viewcvs?view=rev&revision=124467
static bool ParseLocalSourceName(State *state) {
static bool ParseLocalSourceName(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
Optional(ParseDiscriminator(state))) {
@ -597,15 +584,15 @@ static bool ParseLocalSourceName(State *state) {
// <number> ::= [n] <non-negative decimal integer>
// If "number_out" is non-null, then *number_out is set to the value of the
// parsed number on success.
static bool ParseNumber(State *state, int *number_out) {
static bool ParseNumber(State* state, int* number_out) {
int sign = 1;
if (ParseOneCharToken(state, 'n')) {
sign = -1;
}
const char *p = state->mangled_cur;
const char* p = state->mangled_cur;
int number = 0;
constexpr int int_max_by_10 = std::numeric_limits<int>::max() / 10;
for (;*p != '\0'; ++p) {
for (; *p != '\0'; ++p) {
if (IsDigit(*p)) {
// Prevent signed integer overflow when multiplying
if (number > int_max_by_10) {
@ -637,9 +624,9 @@ static bool ParseNumber(State *state, int *number_out) {
// Floating-point literals are encoded using a fixed-length lowercase
// hexadecimal string.
static bool ParseFloatNumber(State *state) {
const char *p = state->mangled_cur;
for (;*p != '\0'; ++p) {
static bool ParseFloatNumber(State* state) {
const char* p = state->mangled_cur;
for (; *p != '\0'; ++p) {
if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
break;
}
@ -653,9 +640,9 @@ static bool ParseFloatNumber(State *state) {
// The <seq-id> is a sequence number in base 36,
// using digits and upper case letters
static bool ParseSeqId(State *state) {
const char *p = state->mangled_cur;
for (;*p != '\0'; ++p) {
static bool ParseSeqId(State* state) {
const char* p = state->mangled_cur;
for (; *p != '\0'; ++p) {
if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
break;
}
@ -668,9 +655,8 @@ static bool ParseSeqId(State *state) {
}
// <identifier> ::= <unqualified source code identifier> (of given length)
static bool ParseIdentifier(State *state, ssize_t length) {
if (length == -1 ||
!AtLeastNumCharsRemaining(state->mangled_cur, length)) {
static bool ParseIdentifier(State* state, ssize_t length) {
if (length == -1 || !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
return false;
}
if (IdentifierIsAnonymousNamespace(state, length)) {
@ -687,7 +673,7 @@ static bool ParseIdentifier(State *state, ssize_t length) {
}
// <abi-tags> ::= <abi-tag> [<abi-tags>]
static bool ParseAbiTags(State *state) {
static bool ParseAbiTags(State* state) {
State copy = *state;
DisableAppend(state);
if (OneOrMore(ParseAbiTag, state)) {
@ -699,23 +685,21 @@ static bool ParseAbiTags(State *state) {
}
// <abi-tag> ::= B <source-name>
static bool ParseAbiTag(State *state) {
static bool ParseAbiTag(State* state) {
return ParseOneCharToken(state, 'B') && ParseSourceName(state);
}
// <operator-name> ::= nw, and other two letters cases
// ::= cv <type> # (cast)
// ::= v <digit> <source-name> # vendor extended operator
static bool ParseOperatorName(State *state) {
static bool ParseOperatorName(State* state) {
if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
return false;
}
// First check with "cv" (cast) case.
State copy = *state;
if (ParseTwoCharToken(state, "cv") &&
MaybeAppend(state, "operator ") &&
EnterNestedName(state) &&
ParseType(state) &&
if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") &&
EnterNestedName(state) && ParseType(state) &&
LeaveNestedName(state, copy.nest_level)) {
return true;
}
@ -730,12 +714,11 @@ static bool ParseOperatorName(State *state) {
// Other operator names should start with a lower alphabet followed
// by a lower/upper alphabet.
if (!(IsLower(state->mangled_cur[0]) &&
IsAlpha(state->mangled_cur[1]))) {
if (!(IsLower(state->mangled_cur[0]) && IsAlpha(state->mangled_cur[1]))) {
return false;
}
// We may want to perform a binary search if we really need speed.
const AbbrevPair *p;
const AbbrevPair* p;
for (p = kOperatorList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[0] &&
state->mangled_cur[1] == p->abbrev[1]) {
@ -769,10 +752,9 @@ static bool ParseOperatorName(State *state) {
//
// Note: we don't care much about them since they don't appear in
// stack traces. The are special data.
static bool ParseSpecialName(State *state) {
static bool ParseSpecialName(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'T') &&
ParseCharClass(state, "VTIS") &&
if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") &&
ParseType(state)) {
return true;
}
@ -784,8 +766,7 @@ static bool ParseSpecialName(State *state) {
}
*state = copy;
if (ParseTwoCharToken(state, "GV") &&
ParseName(state)) {
if (ParseTwoCharToken(state, "GV") && ParseName(state)) {
return true;
}
*state = copy;
@ -831,16 +812,16 @@ static bool ParseSpecialName(State *state) {
// <call-offset> ::= h <nv-offset> _
// ::= v <v-offset> _
static bool ParseCallOffset(State *state) {
static bool ParseCallOffset(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'h') &&
ParseNVOffset(state) && ParseOneCharToken(state, '_')) {
if (ParseOneCharToken(state, 'h') && ParseNVOffset(state) &&
ParseOneCharToken(state, '_')) {
return true;
}
*state = copy;
if (ParseOneCharToken(state, 'v') &&
ParseVOffset(state) && ParseOneCharToken(state, '_')) {
if (ParseOneCharToken(state, 'v') && ParseVOffset(state) &&
ParseOneCharToken(state, '_')) {
return true;
}
*state = copy;
@ -849,10 +830,10 @@ static bool ParseCallOffset(State *state) {
}
// <nv-offset> ::= <(offset) number>
static bool ParseNVOffset(State *state) { return ParseNumber(state, nullptr); }
static bool ParseNVOffset(State* state) { return ParseNumber(state, nullptr); }
// <v-offset> ::= <(offset) number> _ <(virtual offset) number>
static bool ParseVOffset(State *state) {
static bool ParseVOffset(State* state) {
State copy = *state;
if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
ParseNumber(state, nullptr)) {
@ -864,20 +845,18 @@ static bool ParseVOffset(State *state) {
// <ctor-dtor-name> ::= C1 | C2 | C3
// ::= D0 | D1 | D2
static bool ParseCtorDtorName(State *state) {
static bool ParseCtorDtorName(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'C') &&
ParseCharClass(state, "123")) {
const char * const prev_name = state->prev_name;
if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "123")) {
const char* const prev_name = state->prev_name;
const ssize_t prev_name_length = state->prev_name_length;
MaybeAppendWithLength(state, prev_name, prev_name_length);
return true;
}
*state = copy;
if (ParseOneCharToken(state, 'D') &&
ParseCharClass(state, "012")) {
const char * const prev_name = state->prev_name;
if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "012")) {
const char* const prev_name = state->prev_name;
const ssize_t prev_name_length = state->prev_name_length;
MaybeAppend(state, "~");
MaybeAppendWithLength(state, prev_name, prev_name_length);
@ -907,7 +886,7 @@ static bool ParseCtorDtorName(State *state) {
// # member access (C++0x)
// ::= DT <expression> E # decltype of an expression (C++0x)
//
static bool ParseType(State *state) {
static bool ParseType(State* state) {
// We should check CV-qualifers, and PRGC things first.
State copy = *state;
if (ParseCVQualifiers(state) && ParseType(state)) {
@ -937,17 +916,13 @@ static bool ParseType(State *state) {
}
*state = copy;
if (ParseBuiltinType(state) ||
ParseFunctionType(state) ||
ParseClassEnumType(state) ||
ParseArrayType(state) ||
ParsePointerToMemberType(state) ||
ParseSubstitution(state)) {
if (ParseBuiltinType(state) || ParseFunctionType(state) ||
ParseClassEnumType(state) || ParseArrayType(state) ||
ParsePointerToMemberType(state) || ParseSubstitution(state)) {
return true;
}
if (ParseTemplateTemplateParam(state) &&
ParseTemplateArgs(state)) {
if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) {
return true;
}
*state = copy;
@ -963,7 +938,7 @@ static bool ParseType(State *state) {
// <CV-qualifiers> ::= [r] [V] [K]
// We don't allow empty <CV-qualifiers> to avoid infinite loop in
// ParseType().
static bool ParseCVQualifiers(State *state) {
static bool ParseCVQualifiers(State* state) {
int num_cv_qualifiers = 0;
num_cv_qualifiers += ParseOneCharToken(state, 'r');
num_cv_qualifiers += ParseOneCharToken(state, 'V');
@ -973,8 +948,8 @@ static bool ParseCVQualifiers(State *state) {
// <builtin-type> ::= v, etc.
// ::= u <source-name>
static bool ParseBuiltinType(State *state) {
const AbbrevPair *p;
static bool ParseBuiltinType(State* state) {
const AbbrevPair* p;
for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[0]) {
MaybeAppend(state, p->real_name);
@ -992,11 +967,11 @@ static bool ParseBuiltinType(State *state) {
}
// <function-type> ::= F [Y] <bare-function-type> E
static bool ParseFunctionType(State *state) {
static bool ParseFunctionType(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'F') &&
Optional(ParseOneCharToken(state, 'Y')) &&
ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) {
Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) &&
ParseOneCharToken(state, 'E')) {
return true;
}
*state = copy;
@ -1004,7 +979,7 @@ static bool ParseFunctionType(State *state) {
}
// <bare-function-type> ::= <(signature) type>+
static bool ParseBareFunctionType(State *state) {
static bool ParseBareFunctionType(State* state) {
State copy = *state;
DisableAppend(state);
if (OneOrMore(ParseType, state)) {
@ -1017,13 +992,11 @@ static bool ParseBareFunctionType(State *state) {
}
// <class-enum-type> ::= <name>
static bool ParseClassEnumType(State *state) {
return ParseName(state);
}
static bool ParseClassEnumType(State* state) { return ParseName(state); }
// <array-type> ::= A <(positive dimension) number> _ <(element) type>
// ::= A [<(dimension) expression>] _ <(element) type>
static bool ParseArrayType(State *state) {
static bool ParseArrayType(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_') && ParseType(state)) {
@ -1040,10 +1013,9 @@ static bool ParseArrayType(State *state) {
}
// <pointer-to-member-type> ::= M <(class) type> <(member) type>
static bool ParsePointerToMemberType(State *state) {
static bool ParsePointerToMemberType(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'M') && ParseType(state) &&
ParseType(state)) {
if (ParseOneCharToken(state, 'M') && ParseType(state) && ParseType(state)) {
return true;
}
*state = copy;
@ -1052,7 +1024,7 @@ static bool ParsePointerToMemberType(State *state) {
// <template-param> ::= T_
// ::= T <parameter-2 non-negative number> _
static bool ParseTemplateParam(State *state) {
static bool ParseTemplateParam(State* state) {
if (ParseTwoCharToken(state, "T_")) {
MaybeAppend(state, "?"); // We don't support template substitutions.
return true;
@ -1068,20 +1040,17 @@ static bool ParseTemplateParam(State *state) {
return false;
}
// <template-template-param> ::= <template-param>
// ::= <substitution>
static bool ParseTemplateTemplateParam(State *state) {
return (ParseTemplateParam(state) ||
ParseSubstitution(state));
static bool ParseTemplateTemplateParam(State* state) {
return (ParseTemplateParam(state) || ParseSubstitution(state));
}
// <template-args> ::= I <template-arg>+ E
static bool ParseTemplateArgs(State *state) {
static bool ParseTemplateArgs(State* state) {
State copy = *state;
DisableAppend(state);
if (ParseOneCharToken(state, 'I') &&
OneOrMore(ParseTemplateArg, state) &&
if (ParseOneCharToken(state, 'I') && OneOrMore(ParseTemplateArg, state) &&
ParseOneCharToken(state, 'E')) {
RestoreAppend(state, copy.append);
MaybeAppend(state, "<>");
@ -1096,7 +1065,7 @@ static bool ParseTemplateArgs(State *state) {
// ::= I <template-arg>* E # argument pack
// ::= J <template-arg>* E # argument pack
// ::= X <expression> E
static bool ParseTemplateArg(State *state) {
static bool ParseTemplateArg(State* state) {
// Avoid recursion above max_levels
constexpr uint32 max_levels = 5;
@ -1107,15 +1076,13 @@ static bool ParseTemplateArg(State *state) {
State copy = *state;
if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
ZeroOrMore(ParseTemplateArg, state) &&
ParseOneCharToken(state, 'E')) {
ZeroOrMore(ParseTemplateArg, state) && ParseOneCharToken(state, 'E')) {
--state->arg_level;
return true;
}
*state = copy;
if (ParseType(state) ||
ParseExprPrimary(state)) {
if (ParseType(state) || ParseExprPrimary(state)) {
--state->arg_level;
return true;
}
@ -1139,7 +1106,7 @@ static bool ParseTemplateArg(State *state) {
// ::= st <type>
// ::= sr <type> <unqualified-name> <template-args>
// ::= sr <type> <unqualified-name>
static bool ParseExpression(State *state) {
static bool ParseExpression(State* state) {
if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
return true;
}
@ -1153,25 +1120,21 @@ static bool ParseExpression(State *state) {
++state->expr_level;
State copy = *state;
if (ParseOperatorName(state) &&
ParseExpression(state) &&
ParseExpression(state) &&
if (ParseOperatorName(state) && ParseExpression(state) &&
ParseExpression(state) && ParseExpression(state)) {
--state->expr_level;
return true;
}
*state = copy;
if (ParseOperatorName(state) && ParseExpression(state) &&
ParseExpression(state)) {
--state->expr_level;
return true;
}
*state = copy;
if (ParseOperatorName(state) &&
ParseExpression(state) &&
ParseExpression(state)) {
--state->expr_level;
return true;
}
*state = copy;
if (ParseOperatorName(state) &&
ParseExpression(state)) {
if (ParseOperatorName(state) && ParseExpression(state)) {
--state->expr_level;
return true;
}
@ -1184,8 +1147,7 @@ static bool ParseExpression(State *state) {
*state = copy;
if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
ParseUnqualifiedName(state) &&
ParseTemplateArgs(state)) {
ParseUnqualifiedName(state) && ParseTemplateArgs(state)) {
--state->expr_level;
return true;
}
@ -1205,7 +1167,7 @@ static bool ParseExpression(State *state) {
// ::= L <mangled-name> E
// // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
// ::= LZ <encoding> E
static bool ParseExprPrimary(State *state) {
static bool ParseExprPrimary(State* state) {
State copy = *state;
if (ParseOneCharToken(state, 'L') && ParseType(state) &&
ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
@ -1214,8 +1176,7 @@ static bool ParseExprPrimary(State *state) {
*state = copy;
if (ParseOneCharToken(state, 'L') && ParseType(state) &&
ParseFloatNumber(state) &&
ParseOneCharToken(state, 'E')) {
ParseFloatNumber(state) && ParseOneCharToken(state, 'E')) {
return true;
}
*state = copy;
@ -1238,7 +1199,7 @@ static bool ParseExprPrimary(State *state) {
// <local-name> := Z <(function) encoding> E <(entity) name>
// [<discriminator>]
// := Z <(function) encoding> E s [<discriminator>]
static bool ParseLocalName(State *state) {
static bool ParseLocalName(State* state) {
// Avoid recursion above max_levels
constexpr uint32 max_levels = 5;
if (state->local_level > max_levels) {
@ -1265,7 +1226,7 @@ static bool ParseLocalName(State *state) {
}
// <discriminator> := _ <(non-negative) number>
static bool ParseDiscriminator(State *state) {
static bool ParseDiscriminator(State* state) {
State copy = *state;
if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
return true;
@ -1277,7 +1238,7 @@ static bool ParseDiscriminator(State *state) {
// <substitution> ::= S_
// ::= S <seq-id> _
// ::= St, etc.
static bool ParseSubstitution(State *state) {
static bool ParseSubstitution(State* state) {
if (ParseTwoCharToken(state, "S_")) {
MaybeAppend(state, "?"); // We don't support substitutions.
return true;
@ -1293,7 +1254,7 @@ static bool ParseSubstitution(State *state) {
// Expand abbreviations like "St" => "std".
if (ParseOneCharToken(state, 'S')) {
const AbbrevPair *p;
const AbbrevPair* p;
for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[1]) {
MaybeAppend(state, "std");
@ -1312,7 +1273,7 @@ static bool ParseSubstitution(State *state) {
// Parse <mangled-name>, optionally followed by either a function-clone suffix
// or version suffix. Returns true only if all of "mangled_cur" was consumed.
static bool ParseTopLevelMangledName(State *state) {
static bool ParseTopLevelMangledName(State* state) {
if (ParseMangledName(state)) {
if (state->mangled_cur[0] != '\0') {
// Drop trailing function clone suffix, if any.
@ -1334,9 +1295,9 @@ static bool ParseTopLevelMangledName(State *state) {
#endif
// The demangler entry point.
bool Demangle(const char *mangled, char *out, size_t out_size) {
bool Demangle(const char* mangled, char* out, size_t out_size) {
#if defined(GLOG_OS_WINDOWS)
#if defined(HAVE_DBGHELP)
# if defined(HAVE_DBGHELP)
// When built with incremental linking, the Windows debugger
// library provides a more complicated `Symbol->Name` with the
// Incremental Linking Table offset, which looks like
@ -1347,23 +1308,23 @@ bool Demangle(const char *mangled, char *out, size_t out_size) {
//
// Since we may be in a signal handler here, we cannot use `std::string`.
char buffer[1024]; // Big enough for a sane symbol.
const char *lparen = strchr(mangled, '(');
const char* lparen = strchr(mangled, '(');
if (lparen) {
// Extract the string `(?...)`
const char *rparen = strchr(lparen, ')');
const char* rparen = strchr(lparen, ')');
size_t length = static_cast<size_t>(rparen - lparen) - 1;
strncpy(buffer, lparen + 1, length);
buffer[length] = '\0';
mangled = buffer;
} // Else the symbol wasn't inside a set of parentheses
} // Else the symbol wasn't inside a set of parentheses
// We use the ANSI version to ensure the string type is always `char *`.
return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE);
#else
# else
(void)mangled;
(void)out;
(void)out_size;
return false;
#endif
# endif
#else
State state;
InitState(&state, mangled, out, out_size);

View File

@ -78,7 +78,7 @@ namespace google {
// 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_EXPORT Demangle(const char* mangled, char* out, size_t out_size);
} // namespace google

View File

@ -43,7 +43,7 @@
#include "utilities.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
@ -54,7 +54,7 @@ using namespace std;
using namespace google;
// A wrapper function for Demangle() to make the unit test simple.
static const char *DemangleIt(const char * const mangled) {
static const char* DemangleIt(const char* const mangled) {
static char demangled[4096];
if (Demangle(mangled, demangled, sizeof(demangled))) {
return demangled;
@ -65,28 +65,25 @@ static const char *DemangleIt(const char * const mangled) {
#if defined(GLOG_OS_WINDOWS)
#if defined(HAVE_DBGHELP) && !defined(NDEBUG)
# if defined(HAVE_DBGHELP) && !defined(NDEBUG)
TEST(Demangle, Windows) {
EXPECT_STREQ(
"public: static void __cdecl Foo::func(int)",
DemangleIt("?func@Foo@@SAXH@Z"));
EXPECT_STREQ(
"public: static void __cdecl Foo::func(int)",
DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
EXPECT_STREQ(
"int __cdecl foobarArray(int * const)",
DemangleIt("?foobarArray@@YAHQAH@Z"));
EXPECT_STREQ("public: static void __cdecl Foo::func(int)",
DemangleIt("?func@Foo@@SAXH@Z"));
EXPECT_STREQ("public: static void __cdecl Foo::func(int)",
DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
EXPECT_STREQ("int __cdecl foobarArray(int * const)",
DemangleIt("?foobarArray@@YAHQAH@Z"));
}
#endif
# endif
#else
// Test corner cases of boundary conditions.
TEST(Demangle, CornerCases) {
const size_t size = 10;
char tmp[size] = { 0 };
const char *demangled = "foobar()";
const char *mangled = "_Z6foobarv";
char tmp[size] = {0};
const char* demangled = "foobar()";
const char* mangled = "_Z6foobarv";
EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp)));
// sizeof("foobar()") == size - 1
EXPECT_STREQ(demangled, tmp);
@ -147,7 +144,7 @@ TEST(Demangle, FromFile) {
#endif
int main(int argc, char **argv) {
int main(int argc, char** argv) {
#ifdef GLOG_USE_GFLAGS
ParseCommandLineFlags(&argc, &argv, true);
#endif

View File

@ -18,7 +18,7 @@
#include "demangle.h"
extern "C" int LLVMFuzzerTestOneInput(const unsigned char *Data,
extern "C" int LLVMFuzzerTestOneInput(const unsigned char* Data,
unsigned Size) {
if (Size >= 4095) {
return 0;

View File

@ -51,20 +51,20 @@
using LogSeverity = int;
const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
NUM_SEVERITIES = 4;
NUM_SEVERITIES = 4;
#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
# ifdef ERROR
# ifdef ERROR
# error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail.
# endif
const int INFO = GLOG_INFO, WARNING = GLOG_WARNING,
ERROR = GLOG_ERROR, FATAL = GLOG_FATAL;
# endif
const int INFO = GLOG_INFO, WARNING = GLOG_WARNING, ERROR = GLOG_ERROR,
FATAL = GLOG_FATAL;
#endif
// DFATAL is FATAL in debug mode, ERROR in normal mode
#ifdef NDEBUG
#define DFATAL_LEVEL ERROR
# define DFATAL_LEVEL ERROR
#else
#define DFATAL_LEVEL FATAL
# define DFATAL_LEVEL FATAL
#endif
extern GLOG_EXPORT const char* const LogSeverityNames[NUM_SEVERITIES];
@ -89,10 +89,10 @@ extern GLOG_EXPORT const char* const LogSeverityNames[NUM_SEVERITIES];
//
#ifdef NDEBUG
enum { DEBUG_MODE = 0 };
#define IF_DEBUG_MODE(x)
# define IF_DEBUG_MODE(x)
#else
enum { DEBUG_MODE = 1 };
#define IF_DEBUG_MODE(x) x
# define IF_DEBUG_MODE(x) x
#endif
#endif // BASE_LOG_SEVERITY_H__

View File

@ -50,28 +50,28 @@
#include <vector>
#if defined(_MSC_VER)
#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) \
__pragma(warning(push)) __pragma(warning(disable : n))
#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
# define GLOG_MSVC_PUSH_DISABLE_WARNING(n) \
__pragma(warning(push)) __pragma(warning(disable : n))
# define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
#else
#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
#define GLOG_MSVC_POP_WARNING()
# define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
# define GLOG_MSVC_POP_WARNING()
#endif
#include "glog/platform.h"
#if defined(__has_attribute)
#if __has_attribute(used)
#define GLOG_USED __attribute__((used))
#endif // __has_attribute(used)
#endif // defined(__has_attribute)
# if __has_attribute(used)
# define GLOG_USED __attribute__((used))
# endif // __has_attribute(used)
#endif // defined(__has_attribute)
#if !defined(GLOG_USED)
#define GLOG_USED
# define GLOG_USED
#endif // !defined(GLOG_USED)
#if defined(GLOG_USE_GLOG_EXPORT)
#include "glog/export.h"
# include "glog/export.h"
#endif
// We care a lot about number of bits things take up. Unfortunately,
@ -83,7 +83,7 @@
#include <cstdint> // the normal place uint16_t is defined
#if defined(GLOG_USE_GFLAGS)
#include <gflags/gflags.h>
# include <gflags/gflags.h>
#endif
#include <atomic>
@ -158,7 +158,7 @@ typedef void (*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l,
// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
// base/logging.h
#ifndef GOOGLE_STRIP_LOG
#define GOOGLE_STRIP_LOG 0
# define GOOGLE_STRIP_LOG 0
#endif
// GCC can be told that a certain branch is not likely to be taken (for
@ -167,43 +167,43 @@ typedef void (*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l,
// the absence of better information (ie. -fprofile-arcs).
//
#if defined(__has_builtin)
#if __has_builtin(__builtin_expect)
#define GLOG_BUILTIN_EXPECT_PRESENT
#endif
# if __has_builtin(__builtin_expect)
# define GLOG_BUILTIN_EXPECT_PRESENT
# endif
#endif
#if !defined(GLOG_BUILTIN_EXPECT_PRESENT) && defined(__GNUG__)
// __has_builtin is not available prior to GCC 10
#define GLOG_BUILTIN_EXPECT_PRESENT
# define GLOG_BUILTIN_EXPECT_PRESENT
#endif
#if defined(GLOG_BUILTIN_EXPECT_PRESENT)
#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
#endif
# ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
# define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
# endif
#ifndef GOOGLE_PREDICT_FALSE
#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
#endif
# ifndef GOOGLE_PREDICT_FALSE
# define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
# endif
#ifndef GOOGLE_PREDICT_TRUE
#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#endif
# ifndef GOOGLE_PREDICT_TRUE
# define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
# endif
#else
#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
#endif
# ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
# define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
# endif
#ifndef GOOGLE_PREDICT_TRUE
#define GOOGLE_PREDICT_FALSE(x) x
#endif
# ifndef GOOGLE_PREDICT_TRUE
# define GOOGLE_PREDICT_FALSE(x) x
# endif
#ifndef GOOGLE_PREDICT_TRUE
#define GOOGLE_PREDICT_TRUE(x) x
#endif
# ifndef GOOGLE_PREDICT_TRUE
# define GOOGLE_PREDICT_TRUE(x) x
# endif
#endif
@ -370,50 +370,51 @@ typedef void (*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l,
#pragma push_macro("DECLARE_uint32")
#ifdef DECLARE_VARIABLE
#undef DECLARE_VARIABLE
# undef DECLARE_VARIABLE
#endif
#ifdef DECLARE_bool
#undef DECLARE_bool
# undef DECLARE_bool
#endif
#ifdef DECLARE_string
#undef DECLARE_string
# undef DECLARE_string
#endif
#ifdef DECLARE_int32
#undef DECLARE_int32
# undef DECLARE_int32
#endif
#ifdef DECLARE_uint32
#undef DECLARE_uint32
# undef DECLARE_uint32
#endif
#ifndef DECLARE_VARIABLE
#define DECLARE_VARIABLE(type, shorttype, name, tn) \
namespace fL##shorttype { \
extern GLOG_EXPORT type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name
# define DECLARE_VARIABLE(type, shorttype, name, tn) \
namespace fL##shorttype { \
extern GLOG_EXPORT type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name
// bool specialization
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name, bool)
# define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name, bool)
// int32 specialization
#define DECLARE_int32(name) DECLARE_VARIABLE(google::int32, I, name, int32)
# define DECLARE_int32(name) DECLARE_VARIABLE(google::int32, I, name, int32)
#if !defined(DECLARE_uint32)
# if !defined(DECLARE_uint32)
// uint32 specialization
#define DECLARE_uint32(name) DECLARE_VARIABLE(google::uint32, U, name, uint32)
#endif // !defined(DECLARE_uint32) && !defined(GLOG_USE_GFLAGS)
# define DECLARE_uint32(name) \
DECLARE_VARIABLE(google::uint32, U, name, uint32)
# endif // !defined(DECLARE_uint32) && !defined(GLOG_USE_GFLAGS)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
#define DECLARE_string(name) \
namespace fLS { \
extern GLOG_EXPORT std::string& FLAGS_##name; \
} \
using fLS::FLAGS_##name
# define DECLARE_string(name) \
namespace fLS { \
extern GLOG_EXPORT std::string& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif
// Set whether appending a timestamp to the log file name
@ -493,58 +494,58 @@ DECLARE_string(logmailer);
// better to have compact code for these operations.
#if GOOGLE_STRIP_LOG == 0
#define COMPACT_GOOGLE_LOG_INFO google::LogMessage(__FILE__, __LINE__)
#define LOG_TO_STRING_INFO(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, message)
# define COMPACT_GOOGLE_LOG_INFO google::LogMessage(__FILE__, __LINE__)
# define LOG_TO_STRING_INFO(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, message)
#else
#define COMPACT_GOOGLE_LOG_INFO google::NullStream()
#define LOG_TO_STRING_INFO(message) google::NullStream()
# define COMPACT_GOOGLE_LOG_INFO google::NullStream()
# define LOG_TO_STRING_INFO(message) google::NullStream()
#endif
#if GOOGLE_STRIP_LOG <= 1
#define COMPACT_GOOGLE_LOG_WARNING \
google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING)
#define LOG_TO_STRING_WARNING(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, message)
# define COMPACT_GOOGLE_LOG_WARNING \
google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING)
# define LOG_TO_STRING_WARNING(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, message)
#else
#define COMPACT_GOOGLE_LOG_WARNING google::NullStream()
#define LOG_TO_STRING_WARNING(message) google::NullStream()
# define COMPACT_GOOGLE_LOG_WARNING google::NullStream()
# define LOG_TO_STRING_WARNING(message) google::NullStream()
#endif
#if GOOGLE_STRIP_LOG <= 2
#define COMPACT_GOOGLE_LOG_ERROR \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR)
#define LOG_TO_STRING_ERROR(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, message)
# define COMPACT_GOOGLE_LOG_ERROR \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR)
# define LOG_TO_STRING_ERROR(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, message)
#else
#define COMPACT_GOOGLE_LOG_ERROR google::NullStream()
#define LOG_TO_STRING_ERROR(message) google::NullStream()
# define COMPACT_GOOGLE_LOG_ERROR google::NullStream()
# define LOG_TO_STRING_ERROR(message) google::NullStream()
#endif
#if GOOGLE_STRIP_LOG <= 3
#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal(__FILE__, __LINE__)
#define LOG_TO_STRING_FATAL(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, message)
# define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal(__FILE__, __LINE__)
# define LOG_TO_STRING_FATAL(message) \
google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, message)
#else
#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal()
#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal()
# define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal()
# define LOG_TO_STRING_FATAL(message) google::NullStreamFatal()
#endif
#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
#define DCHECK_IS_ON() 0
# define DCHECK_IS_ON() 0
#else
#define DCHECK_IS_ON() 1
# define DCHECK_IS_ON() 1
#endif
// For DFATAL, we want to use LogMessage (as opposed to
// LogMessageFatal), to be consistent with the original behavior.
#if !DCHECK_IS_ON()
#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
# define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
#elif GOOGLE_STRIP_LOG <= 3
#define COMPACT_GOOGLE_LOG_DFATAL \
google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL)
# define COMPACT_GOOGLE_LOG_DFATAL \
google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL)
#else
#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal()
# define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal()
#endif
#define GOOGLE_LOG_INFO(counter) \
@ -581,22 +582,22 @@ DECLARE_string(logmailer);
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \
defined(__CYGWIN__) || defined(__CYGWIN32__)
// A very useful logging macro to log windows errors:
#define LOG_SYSRESULT(result) \
if (FAILED(HRESULT_FROM_WIN32(result))) { \
LPSTR message = nullptr; \
LPSTR msg = reinterpret_cast<LPSTR>(&message); \
DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM | \
FORMAT_MESSAGE_IGNORE_INSERTS, \
0, result, 0, msg, 100, nullptr); \
if (message_length > 0) { \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \
&google::LogMessage::SendToLog) \
.stream() \
<< reinterpret_cast<const char*>(message); \
LocalFree(message); \
} \
}
# define LOG_SYSRESULT(result) \
if (FAILED(HRESULT_FROM_WIN32(result))) { \
LPSTR message = nullptr; \
LPSTR msg = reinterpret_cast<LPSTR>(&message); \
DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM | \
FORMAT_MESSAGE_IGNORE_INSERTS, \
0, result, 0, msg, 100, nullptr); \
if (message_length > 0) { \
google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \
&google::LogMessage::SendToLog) \
.stream() \
<< reinterpret_cast<const char*>(message); \
LocalFree(message); \
} \
}
#endif
// We use the preprocessor's merging operator, "##", so that, e.g.,
@ -781,9 +782,9 @@ GLOG_EXPORT void MakeCheckOpValueString(std::ostream* os,
template <typename T1, typename T2>
std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
#if defined(__has_attribute)
#if __has_attribute(used)
# if __has_attribute(used)
__attribute__((noinline))
#endif
# endif
#endif
;
@ -866,7 +867,7 @@ DEFINE_CHECK_OP_IMPL(Check_GT, >)
#if defined(STATIC_ANALYSIS)
// Only for static analysis tool to know that it is equivalent to assert
#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1)op(val2))
# define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1)op(val2))
#elif DCHECK_IS_ON()
// In debug mode, avoid constructing CheckOpStrings if possible,
// to reduce the overhead of CHECK statements by 2x.
@ -878,27 +879,27 @@ 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::_Check_string* _result = google::Check##name##Impl( \
google::GetReferenceableValue(val1), \
google::GetReferenceableValue(val2), #val1 " " #op " " #val2)) \
log(__FILE__, __LINE__, google::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)) \
log(__FILE__, __LINE__, _result).stream()
# 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)) \
log(__FILE__, __LINE__, _result).stream()
#endif // STATIC_ANALYSIS, DCHECK_IS_ON()
#if GOOGLE_STRIP_LOG <= 3
#define CHECK_OP(name, op, val1, val2) \
CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal)
# define CHECK_OP(name, op, val1, val2) \
CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal)
#else
#define CHECK_OP(name, op, val1, val2) \
CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal)
# define CHECK_OP(name, op, val1, val2) \
CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal)
#endif // STRIP_LOG <= 3
// Equality/Inequality checks - compare two values, and log a FATAL message
@ -1028,20 +1029,20 @@ DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
#define LOG_PREVIOUS_TIME LOG_EVERY_N_VARNAME(previousTime_, __LINE__)
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define GLOG_SANITIZE_THREAD 1
#endif
# if __has_feature(thread_sanitizer)
# define GLOG_SANITIZE_THREAD 1
# endif
#endif
#if !defined(GLOG_SANITIZE_THREAD) && defined(__SANITIZE_THREAD__) && \
__SANITIZE_THREAD__
#define GLOG_SANITIZE_THREAD 1
# define GLOG_SANITIZE_THREAD 1
#endif
#if defined(GLOG_SANITIZE_THREAD)
#define GLOG_IFDEF_THREAD_SANITIZER(X) X
# define GLOG_IFDEF_THREAD_SANITIZER(X) X
#else
#define GLOG_IFDEF_THREAD_SANITIZER(X)
# define GLOG_IFDEF_THREAD_SANITIZER(X)
#endif
#if defined(GLOG_SANITIZE_THREAD)
@ -1166,9 +1167,9 @@ enum PRIVATE_Counter { COUNTER };
// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
// to keep using this syntax, we define this macro to do the same thing
// as COMPACT_GOOGLE_LOG_ERROR.
#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
#define SYSLOG_0 SYSLOG_ERROR
#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR
# define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
# define SYSLOG_0 SYSLOG_ERROR
# define LOG_TO_STRING_0 LOG_TO_STRING_ERROR
// Needed for LOG_IS_ON(ERROR).
const LogSeverity GLOG_0 = GLOG_ERROR;
#else
@ -1176,126 +1177,126 @@ const LogSeverity GLOG_0 = GLOG_ERROR;
// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN.
// For this case, we cannot detect if ERROR is defined before users
// actually use ERROR. Let's make an undefined symbol to warn users.
#define GLOG_ERROR_MSG \
ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail
#define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG
#define SYSLOG_0 GLOG_ERROR_MSG
#define LOG_TO_STRING_0 GLOG_ERROR_MSG
#define GLOG_0 GLOG_ERROR_MSG
# define GLOG_ERROR_MSG \
ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail
# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG
# define SYSLOG_0 GLOG_ERROR_MSG
# define LOG_TO_STRING_0 GLOG_ERROR_MSG
# define GLOG_0 GLOG_ERROR_MSG
#endif
// Plus some debug-logging macros that get compiled to nothing for production
#if DCHECK_IS_ON()
#define DLOG(severity) LOG(severity)
#define DVLOG(verboselevel) VLOG(verboselevel)
#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
#define DLOG_IF_EVERY_N(severity, condition, n) \
LOG_IF_EVERY_N(severity, condition, n)
#define DLOG_FIRST_N(severity, n) LOG_FIRST_N(severity, n)
#define DLOG_EVERY_T(severity, T) LOG_EVERY_T(severity, T)
#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
# define DLOG(severity) LOG(severity)
# define DVLOG(verboselevel) VLOG(verboselevel)
# define DLOG_IF(severity, condition) LOG_IF(severity, condition)
# define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
# define DLOG_IF_EVERY_N(severity, condition, n) \
LOG_IF_EVERY_N(severity, condition, n)
# define DLOG_FIRST_N(severity, n) LOG_FIRST_N(severity, n)
# define DLOG_EVERY_T(severity, T) LOG_EVERY_T(severity, T)
# define DLOG_ASSERT(condition) LOG_ASSERT(condition)
// debug-only checking. executed if DCHECK_IS_ON().
#define DCHECK(condition) CHECK(condition)
#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
# define DCHECK(condition) CHECK(condition)
# define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
# define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
# define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
# define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
# define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
# define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
# define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
# define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
# define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
# define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
# define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
#else // !DCHECK_IS_ON()
#define DLOG(severity) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
# define DLOG(severity) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
#define DVLOG(verboselevel) \
static_cast<void>(0), (true || !VLOG_IS_ON(verboselevel)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(INFO)
# define DVLOG(verboselevel) \
static_cast<void>(0), (true || !VLOG_IS_ON(verboselevel)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(INFO)
#define DLOG_IF(severity, condition) \
static_cast<void>(0), (true || !(condition)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(severity)
# define DLOG_IF(severity, condition) \
static_cast<void>(0), (true || !(condition)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(severity)
#define DLOG_EVERY_N(severity, n) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
# define DLOG_EVERY_N(severity, n) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
#define DLOG_IF_EVERY_N(severity, condition, n) \
static_cast<void>(0), (true || !(condition)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(severity)
# define DLOG_IF_EVERY_N(severity, condition, n) \
static_cast<void>(0), (true || !(condition)) \
? (void)0 \
: google::LogMessageVoidify() & LOG(severity)
#define DLOG_FIRST_N(severity, n) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
# define DLOG_FIRST_N(severity, n) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
#define DLOG_EVERY_T(severity, T) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
# define DLOG_EVERY_T(severity, T) \
static_cast<void>(0), \
true ? (void)0 : google::LogMessageVoidify() & LOG(severity)
#define DLOG_ASSERT(condition) \
static_cast<void>(0), true ? (void)0 : LOG_ASSERT(condition)
# define DLOG_ASSERT(condition) \
static_cast<void>(0), true ? (void)0 : LOG_ASSERT(condition)
// MSVC warning C4127: conditional expression is constant
#define DCHECK(condition) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK(condition)
# define DCHECK(condition) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK(condition)
#define DCHECK_EQ(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
# define DCHECK_EQ(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
# define DCHECK_NE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
# define DCHECK_LE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
# define DCHECK_LT(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
# define DCHECK_GE(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
# define DCHECK_GT(val1, val2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
// You may see warnings in release mode if you don't use the return
// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
#define DCHECK_NOTNULL(val) (val)
# define DCHECK_NOTNULL(val) (val)
#define DCHECK_STREQ(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
# define DCHECK_STREQ(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
#define DCHECK_STRCASEEQ(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
# define DCHECK_STRCASEEQ(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
#define DCHECK_STRNE(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
# define DCHECK_STRNE(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
#define DCHECK_STRCASENE(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
# define DCHECK_STRCASENE(str1, str2) \
GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
while (false) GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
#endif // DCHECK_IS_ON()

View File

@ -35,26 +35,26 @@
#define GLOG_PLATFORM_H
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#define GLOG_OS_WINDOWS
# define GLOG_OS_WINDOWS
#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
#define GLOG_OS_CYGWIN
# define GLOG_OS_CYGWIN
#elif defined(linux) || defined(__linux) || defined(__linux__)
#ifndef GLOG_OS_LINUX
#define GLOG_OS_LINUX
#endif
# ifndef GLOG_OS_LINUX
# define GLOG_OS_LINUX
# endif
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
#define GLOG_OS_MACOSX
# define GLOG_OS_MACOSX
#elif defined(__FreeBSD__)
#define GLOG_OS_FREEBSD
# define GLOG_OS_FREEBSD
#elif defined(__NetBSD__)
#define GLOG_OS_NETBSD
# define GLOG_OS_NETBSD
#elif defined(__OpenBSD__)
#define GLOG_OS_OPENBSD
# define GLOG_OS_OPENBSD
#elif defined(__EMSCRIPTEN__)
#define GLOG_OS_EMSCRIPTEN
# define GLOG_OS_EMSCRIPTEN
#else
// TODO(hamaji): Add other platforms.
#error Platform not supported by glog. Please consider to contribute platform information by submitting a pull request on Github.
#endif
#endif // GLOG_PLATFORM_H
#endif // GLOG_PLATFORM_H

View File

@ -44,8 +44,8 @@ namespace google {
#include "glog/vlog_is_on.h"
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wvariadic-macros"
#endif
// This is similar to LOG(severity) << format... and VLOG(level) << format..,
@ -85,46 +85,46 @@ namespace google {
// The following STRIP_LOG testing is performed in the header file so that it's
// possible to completely compile out the logging code and the log messages.
#if !defined(STRIP_LOG) || STRIP_LOG == 0
#define RAW_VLOG(verboselevel, ...) \
do { \
if (VLOG_IS_ON(verboselevel)) { \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
# define RAW_VLOG(verboselevel, ...) \
do { \
if (VLOG_IS_ON(verboselevel)) { \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
#else
#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
# define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if !defined(STRIP_LOG) || STRIP_LOG == 0
#define RAW_LOG_INFO(...) \
google::RawLog__(google::GLOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
# define RAW_LOG_INFO(...) \
google::RawLog__(google::GLOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
# define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if !defined(STRIP_LOG) || STRIP_LOG <= 1
#define RAW_LOG_WARNING(...) \
google::RawLog__(google::GLOG_WARNING, __FILE__, __LINE__, __VA_ARGS__)
# define RAW_LOG_WARNING(...) \
google::RawLog__(google::GLOG_WARNING, __FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
# define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 1
#if !defined(STRIP_LOG) || STRIP_LOG <= 2
#define RAW_LOG_ERROR(...) \
google::RawLog__(google::GLOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
# define RAW_LOG_ERROR(...) \
google::RawLog__(google::GLOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
# define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 2
#if !defined(STRIP_LOG) || STRIP_LOG <= 3
#define RAW_LOG_FATAL(...) \
google::RawLog__(google::GLOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
# define RAW_LOG_FATAL(...) \
google::RawLog__(google::GLOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_FATAL(...) \
do { \
google::RawLogStub__(0, __VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
# define RAW_LOG_FATAL(...) \
do { \
google::RawLogStub__(0, __VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
#endif // STRIP_LOG <= 3
// Similar to CHECK(condition) << message,
@ -142,20 +142,20 @@ namespace google {
// Debug versions of RAW_LOG and RAW_CHECK
#ifndef NDEBUG
#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
# define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
# define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
#else // NDEBUG
#define RAW_DLOG(severity, ...) \
while (false) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) \
while (false) RAW_CHECK(condition, message)
# define RAW_DLOG(severity, ...) \
while (false) RAW_LOG(severity, __VA_ARGS__)
# define RAW_DCHECK(condition, message) \
while (false) RAW_CHECK(condition, message)
#endif // NDEBUG
#if defined(__GNUC__)
#pragma GCC diagnostic pop
# pragma GCC diagnostic pop
#endif
// Stub log function used to work around for unused variable warnings when
@ -169,9 +169,9 @@ static inline void RawLogStub__(int /* ignored */, ...) {}
GLOG_EXPORT void RawLog__(LogSeverity severity, const char* file, int line,
const char* format, ...)
#if defined(__has_attribute)
#if __has_attribute(used)
# if __has_attribute(used)
__attribute__((__format__(__printf__, 4, 5)))
#endif
# endif
#endif
;
} // namespace google

View File

@ -72,20 +72,21 @@
// it's either FLAGS_v or an appropriate internal variable
// matching the current source file that represents results of
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__({ \
static google::SiteFlag vlocal__ = {nullptr, nullptr, 0, nullptr}; \
GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized( \
__FILE__, __LINE__, &vlocal__, sizeof(google::SiteFlag), "")); \
google::int32 verbose_level__ = (verboselevel); \
(vlocal__.level == nullptr \
? google::InitVLOG3__(&vlocal__, &FLAGS_v, __FILE__, verbose_level__) \
: *vlocal__.level >= verbose_level__); \
})
# define VLOG_IS_ON(verboselevel) \
__extension__({ \
static google::SiteFlag vlocal__ = {nullptr, nullptr, 0, nullptr}; \
GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized( \
__FILE__, __LINE__, &vlocal__, sizeof(google::SiteFlag), "")); \
google::int32 verbose_level__ = (verboselevel); \
(vlocal__.level == nullptr \
? google::InitVLOG3__(&vlocal__, &FLAGS_v, __FILE__, \
verbose_level__) \
: *vlocal__.level >= verbose_level__); \
})
#else
// GNU extensions not available, so we do not support --vmodule.
// Dynamic value of FLAGS_v always controls the logging level.
#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
# define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
#endif
// Set VLOG(_IS_ON) level for module_pattern to log_level.

View File

@ -31,7 +31,7 @@
// (based on googletest: http://code.google.com/p/googletest/)
#ifdef GOOGLETEST_H__
#error You must not include this file twice.
# error You must not include this file twice.
#endif
#define GOOGLETEST_H__
@ -53,15 +53,15 @@
#include "utilities.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
# include <unistd.h>
#endif
#include "base/commandlineflags.h"
#if __cplusplus < 201103L && !defined(_MSC_VER)
#define GOOGLE_GLOG_THROW_BAD_ALLOC throw (std::bad_alloc)
# define GOOGLE_GLOG_THROW_BAD_ALLOC throw(std::bad_alloc)
#else
#define GOOGLE_GLOG_THROW_BAD_ALLOC
# define GOOGLE_GLOG_THROW_BAD_ALLOC
#endif
using std::map;
@ -95,7 +95,7 @@ static inline string GetTempDir() {
// (e.g., glog/vsproject/logging_unittest).
static const char TEST_SRC_DIR[] = "../..";
#elif !defined(TEST_SRC_DIR)
# warning TEST_SRC_DIR should be defined in config.h
# warning TEST_SRC_DIR should be defined in config.h
static const char TEST_SRC_DIR[] = ".";
#endif
@ -112,10 +112,10 @@ DEFINE_int32(benchmark_iters, 100000, "Number of iterations per benchmark");
#endif
#ifdef HAVE_LIB_GTEST
# include <gtest/gtest.h>
# include <gtest/gtest.h>
// Use our ASSERT_DEATH implementation.
# undef ASSERT_DEATH
# undef ASSERT_DEBUG_DEATH
# undef ASSERT_DEATH
# undef ASSERT_DEBUG_DEATH
using testing::InitGoogleTest;
#else
@ -127,81 +127,83 @@ void InitGoogleTest(int*, char**) {}
// The following is some bare-bones testing infrastructure
#define EXPECT_NEAR(val1, val2, abs_error) \
do { \
if (abs(val1 - val2) > abs_error) { \
fprintf(stderr, "Check failed: %s within %s of %s\n", #val1, #abs_error, \
#val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_NEAR(val1, val2, abs_error) \
do { \
if (abs(val1 - val2) > abs_error) { \
fprintf(stderr, "Check failed: %s within %s of %s\n", #val1, \
#abs_error, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_TRUE(cond) \
do { \
if (!(cond)) { \
fprintf(stderr, "Check failed: %s\n", #cond); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_TRUE(cond) \
do { \
if (!(cond)) { \
fprintf(stderr, "Check failed: %s\n", #cond); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond))
# define EXPECT_FALSE(cond) EXPECT_TRUE(!(cond))
#define EXPECT_OP(op, val1, val2) \
do { \
if (!((val1) op (val2))) { \
fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_OP(op, val1, val2) \
do { \
if (!((val1)op(val2))) { \
fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2)
#define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2)
#define EXPECT_GT(val1, val2) EXPECT_OP(>, val1, val2)
#define EXPECT_LT(val1, val2) EXPECT_OP(<, val1, val2)
# define EXPECT_EQ(val1, val2) EXPECT_OP(==, val1, val2)
# define EXPECT_NE(val1, val2) EXPECT_OP(!=, val1, val2)
# define EXPECT_GT(val1, val2) EXPECT_OP(>, val1, val2)
# define EXPECT_LT(val1, val2) EXPECT_OP(<, val1, val2)
#define EXPECT_NAN(arg) \
do { \
if (!isnan(arg)) { \
fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_NAN(arg) \
do { \
if (!isnan(arg)) { \
fprintf(stderr, "Check failed: isnan(%s)\n", #arg); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_INF(arg) \
do { \
if (!isinf(arg)) { \
fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_INF(arg) \
do { \
if (!isinf(arg)) { \
fprintf(stderr, "Check failed: isinf(%s)\n", #arg); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_DOUBLE_EQ(val1, val2) \
do { \
if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) { \
fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_DOUBLE_EQ(val1, val2) \
do { \
if (((val1) < (val2)-0.001 || (val1) > (val2) + 0.001)) { \
fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define EXPECT_STREQ(val1, val2) \
do { \
if (strcmp((val1), (val2)) != 0) { \
fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define EXPECT_STREQ(val1, val2) \
do { \
if (strcmp((val1), (val2)) != 0) { \
fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2); \
exit(EXIT_FAILURE); \
} \
} while (0)
vector<void (*)()> g_testlist; // the tests to run
#define TEST(a, b) \
struct Test_##a##_##b { \
Test_##a##_##b() { g_testlist.push_back(&Run); } \
static void Run() { FlagSaver fs; RunTest(); } \
static void RunTest(); \
}; \
static Test_##a##_##b g_test_##a##_##b; \
void Test_##a##_##b::RunTest()
# define TEST(a, b) \
struct Test_##a##_##b { \
Test_##a##_##b() { g_testlist.push_back(&Run); } \
static void Run() { \
FlagSaver fs; \
RunTest(); \
} \
static void RunTest(); \
}; \
static Test_##a##_##b g_test_##a##_##b; \
void Test_##a##_##b::RunTest()
static inline int RUN_ALL_TESTS() {
vector<void (*)()>::const_iterator it;
@ -228,33 +230,33 @@ static inline void CalledAbort() {
#ifdef GLOG_OS_WINDOWS
// TODO(hamaji): Death test somehow doesn't work in Windows.
#define ASSERT_DEATH(fn, msg)
# define ASSERT_DEATH(fn, msg)
#else
#define ASSERT_DEATH(fn, msg) \
do { \
g_called_abort = false; \
/* in logging.cc */ \
void (*original_logging_fail_func)() = g_logging_fail_func; \
g_logging_fail_func = &CalledAbort; \
if (!setjmp(g_jmp_buf)) fn; \
/* set back to their default */ \
g_logging_fail_func = original_logging_fail_func; \
if (!g_called_abort) { \
fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \
exit(EXIT_FAILURE); \
} \
} while (0)
# define ASSERT_DEATH(fn, msg) \
do { \
g_called_abort = false; \
/* in logging.cc */ \
void (*original_logging_fail_func)() = g_logging_fail_func; \
g_logging_fail_func = &CalledAbort; \
if (!setjmp(g_jmp_buf)) fn; \
/* set back to their default */ \
g_logging_fail_func = original_logging_fail_func; \
if (!g_called_abort) { \
fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn); \
exit(EXIT_FAILURE); \
} \
} while (0)
#endif
#ifdef NDEBUG
#define ASSERT_DEBUG_DEATH(fn, msg)
# define ASSERT_DEBUG_DEATH(fn, msg)
#else
#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
# define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
#endif // NDEBUG
// Benchmark tools.
#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n);
#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_##n(#n, &n);
map<string, void (*)(int)> g_benchlist; // the benchmarks to run
@ -278,13 +280,13 @@ static inline void RunSpecifiedBenchmarks() {
double elapsed_ns = (static_cast<double>(clock()) - start) /
CLOCKS_PER_SEC * 1000 * 1000 * 1000;
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat="
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wformat="
#endif
printf("%s\t%8.2lf\t%10d\n", iter.first.c_str(), elapsed_ns / iter_cnt,
iter_cnt);
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
# pragma GCC diagnostic pop
#endif
}
puts("");
@ -317,8 +319,7 @@ class CapturedStream {
CHECK(uncaptured_fd_ != -1);
// Open file to save stream to
int cap_fd = open(filename_.c_str(),
O_CREAT | O_TRUNC | O_WRONLY,
int cap_fd = open(filename_.c_str(), O_CREAT | O_TRUNC | O_WRONLY,
S_IRUSR | S_IWUSR);
CHECK(cap_fd != -1);
@ -337,18 +338,18 @@ class CapturedStream {
}
}
const string & filename() const { return filename_; }
const string& filename() const { return filename_; }
private:
int fd_; // file descriptor being captured
int fd_; // file descriptor being captured
int uncaptured_fd_{-1}; // where the stream was originally being sent to
string filename_; // file where stream is being saved
string filename_; // file where stream is being saved
};
static CapturedStream * s_captured_streams[STDERR_FILENO+1];
static CapturedStream* s_captured_streams[STDERR_FILENO + 1];
// Redirect a file descriptor to a file.
// fd - Should be STDOUT_FILENO or STDERR_FILENO
// filename - File where output should be stored
static inline void CaptureTestOutput(int fd, const string & filename) {
static inline void CaptureTestOutput(int fd, const string& filename) {
CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
CHECK(s_captured_streams[fd] == nullptr);
s_captured_streams[fd] = new CapturedStream(fd, filename);
@ -360,14 +361,14 @@ static inline void CaptureTestStderr() {
CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
}
// Return the size (in bytes) of a file
static inline size_t GetFileSize(FILE * file) {
static inline size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file));
}
// Read the entire content of a file as a string
static inline string ReadEntireFile(FILE * file) {
static inline string ReadEntireFile(FILE* file) {
const size_t file_size = GetFileSize(file);
char * const buffer = new char[file_size];
char* const buffer = new char[file_size];
size_t bytes_last_read = 0; // # of bytes read in the last fread()
size_t bytes_read = 0; // # of bytes read so far
@ -377,11 +378,12 @@ static inline string ReadEntireFile(FILE * file) {
// Keep reading the file until we cannot read further or the
// pre-determined file size is reached.
do {
bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
bytes_last_read =
fread(buffer + bytes_read, 1, file_size - bytes_read, file);
bytes_read += bytes_last_read;
} while (bytes_last_read > 0 && bytes_read < file_size);
const string content = string(buffer, buffer+bytes_read);
const string content = string(buffer, buffer + bytes_read);
delete[] buffer;
return content;
@ -390,15 +392,14 @@ static inline string ReadEntireFile(FILE * file) {
// fd is STDERR_FILENO) as a string
static inline string GetCapturedTestOutput(int fd) {
CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
CapturedStream * const cap = s_captured_streams[fd];
CHECK(cap)
<< ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
CapturedStream* const cap = s_captured_streams[fd];
CHECK(cap) << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
// Make sure everything is flushed.
cap->StopCapture();
// Read the captured file.
FILE * const file = fopen(cap->filename().c_str(), "r");
FILE* const file = fopen(cap->filename().c_str(), "r");
const string content = ReadEntireFile(file);
fclose(file);
@ -421,7 +422,7 @@ static inline bool IsLoggingPrefix(const string& s) {
}
if (!strchr("IWEF", s[0])) return false;
for (size_t i = 1; i <= 8; ++i) {
if (!isdigit(s[i]) && s[i] != "YEARDATE"[i-1]) return false;
if (!isdigit(s[i]) && s[i] != "YEARDATE"[i - 1]) return false;
}
return true;
}
@ -461,16 +462,15 @@ static inline string MungeLine(const string& line) {
}
size_t index = thread_lineinfo.find(':');
CHECK_NE(string::npos, index);
thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]";
thread_lineinfo = thread_lineinfo.substr(0, index + 1) + "LINE]";
string rest;
std::getline(iss, rest);
return (before + logcode_date[0] + "YEARDATE TIME__ " + thread_lineinfo +
MungeLine(rest));
}
static inline void StringReplace(string* str,
const string& oldsub,
const string& newsub) {
static inline void StringReplace(string* str, const string& oldsub,
const string& newsub) {
size_t pos = str->find(oldsub);
if (pos != string::npos) {
str->replace(pos, oldsub.size(), newsub);
@ -589,9 +589,7 @@ class Thread {
handle_ = CreateThread(nullptr, 0, &Thread::InvokeThreadW, this, 0, &th_);
CHECK(handle_) << "CreateThread";
}
void Join() {
WaitForSingleObject(handle_, INFINITE);
}
void Join() { WaitForSingleObject(handle_, INFINITE); }
#elif defined(HAVE_PTHREAD)
void Start() { pthread_create(&th_, nullptr, &Thread::InvokeThread, this); }
void Join() { pthread_join(th_, nullptr); }
@ -623,12 +621,12 @@ class Thread {
static inline void SleepForMilliseconds(unsigned t) {
#ifndef GLOG_OS_WINDOWS
# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
const struct timespec req = {0, t * 1000 * 1000};
nanosleep(&req, nullptr);
# else
# else
usleep(t * 1000);
# endif
# endif
#else
Sleep(t);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -29,19 +29,19 @@
//
// Author: Ray Sidney
#include <fcntl.h>
#include "config.h"
#include "utilities.h"
#include <fcntl.h>
#ifdef HAVE_GLOB_H
# include <glob.h>
# include <glob.h>
#endif
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
# include <unistd.h>
#endif
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# include <sys/wait.h>
#endif
#include <cstdio>
@ -63,13 +63,14 @@
DECLARE_string(log_backtrace_at); // logging.cc
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
#ifdef HAVE_LIB_GMOCK
#include <gmock/gmock.h>
#include "mock-log.h"
# include <gmock/gmock.h>
# include "mock-log.h"
// Introduce several symbols from gmock.
using google::glog_testing::ScopedMockLog;
using testing::_;
@ -132,7 +133,8 @@ static void BM_Check1(int n) {
}
BENCHMARK(BM_Check1)
static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
static void CheckFailure(int a, int b, const char* file, int line,
const char* msg);
static void BM_Check3(int n) {
while (n-- > 0) {
if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
@ -165,8 +167,7 @@ static void BM_Check2(int n) {
BENCHMARK(BM_Check2)
static void CheckFailure(int, int, const char* /* file */, int /* line */,
const char* /* msg */) {
}
const char* /* msg */) {}
static void BM_logspeed(int n) {
while (n-- > 0) {
@ -182,31 +183,24 @@ static void BM_vlog(int n) {
}
BENCHMARK(BM_vlog)
// Dynamically generate a prefix using the default format and write it to the stream.
void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) {
// Dynamically generate a prefix using the default format and write it to the
// stream.
void PrefixAttacher(std::ostream& s, const LogMessageInfo& l, void* data) {
// Assert that `data` contains the expected contents before producing the
// prefix (otherwise causing the tests to fail):
if (data == nullptr || *static_cast<string*>(data) != "good data") {
return;
}
s << l.severity[0]
<< setw(4) << 1900 + l.time.year()
<< setw(2) << 1 + l.time.month()
<< setw(2) << l.time.day()
<< ' '
<< setw(2) << l.time.hour() << ':'
<< setw(2) << l.time.min() << ':'
<< setw(2) << l.time.sec() << "."
<< setw(6) << l.time.usec()
<< ' '
<< setfill(' ') << setw(5)
<< l.thread_id << setfill('0')
<< ' '
<< l.filename << ':' << l.line_number << "]";
s << l.severity[0] << setw(4) << 1900 + l.time.year() << setw(2)
<< 1 + l.time.month() << setw(2) << l.time.day() << ' ' << setw(2)
<< l.time.hour() << ':' << setw(2) << l.time.min() << ':' << setw(2)
<< l.time.sec() << "." << setw(6) << l.time.usec() << ' ' << setfill(' ')
<< setw(5) << l.thread_id << setfill('0') << ' ' << l.filename << ':'
<< l.line_number << "]";
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
FLAGS_colorlogtostderr = false;
FLAGS_timestamp_in_logfile_name = true;
@ -216,8 +210,8 @@ int main(int argc, char **argv) {
// Test some basics before InitGoogleLogging:
CaptureTestStderr();
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
FLAGS_logtostderr, FLAGS_alsologtostderr);
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold, FLAGS_logtostderr,
FLAGS_alsologtostderr);
LogWithLevels(0, 0, false, false); // simulate "before global c-tors"
const string early_stderr = GetCapturedTestStderr();
@ -226,7 +220,8 @@ int main(int argc, char **argv) {
// Setting a custom prefix generator (it will use the default format so that
// the golden outputs can be reused):
string prefix_attacher_data = "good data";
InitGoogleLogging(argv[0], &PrefixAttacher, static_cast<void*>(&prefix_attacher_data));
InitGoogleLogging(argv[0], &PrefixAttacher,
static_cast<void*>(&prefix_attacher_data));
EXPECT_TRUE(IsGoogleLoggingInitialized());
@ -249,7 +244,8 @@ int main(int argc, char **argv) {
CaptureTestStderr();
// re-emit early_stderr
LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
<< early_stderr;
TestLogging(true);
TestRawLogging();
@ -301,12 +297,12 @@ int main(int argc, char **argv) {
}
void TestLogging(bool check_counts) {
int64 base_num_infos = LogMessage::num_messages(GLOG_INFO);
int64 base_num_infos = LogMessage::num_messages(GLOG_INFO);
int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR);
int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR);
LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
for ( int i = 0; i < 10; ++i ) {
for (int i = 0; i < 10; ++i) {
int old_errno = errno;
errno = i;
PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
@ -330,7 +326,7 @@ void TestLogging(bool check_counts) {
const char const_s[] = "const array";
LOG(INFO) << const_s;
int j = 1000;
LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
LOG(ERROR) << string("foo") << ' ' << j << ' ' << setw(10) << j << " "
<< setw(1) << hex << j;
LOG(INFO) << "foo " << std::setw(10) << 1.0;
@ -341,32 +337,27 @@ void TestLogging(bool check_counts) {
LOG(ERROR) << "inner";
}
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
<< "no prefix";
if (check_counts) {
CHECK_EQ(base_num_infos + 15, LogMessage::num_messages(GLOG_INFO));
CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
CHECK_EQ(base_num_errors + 17, LogMessage::num_messages(GLOG_ERROR));
CHECK_EQ(base_num_infos + 15, LogMessage::num_messages(GLOG_INFO));
CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
CHECK_EQ(base_num_errors + 17, LogMessage::num_messages(GLOG_ERROR));
}
}
static void NoAllocNewHook() {
LOG(FATAL) << "unexpected new";
}
static void NoAllocNewHook() { LOG(FATAL) << "unexpected new"; }
struct NewHook {
NewHook() {
g_new_hook = &NoAllocNewHook;
}
NewHook() { g_new_hook = &NoAllocNewHook; }
~NewHook() { g_new_hook = nullptr; }
};
TEST(DeathNoAllocNewHook, logging) {
// tests that NewHook used below works
NewHook new_hook;
ASSERT_DEATH({
new int;
}, "unexpected new");
ASSERT_DEATH({ new int; }, "unexpected new");
}
void TestRawLogging() {
@ -425,8 +416,8 @@ void TestRawLogging() {
void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
RAW_LOG(INFO,
"Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
v, severity, err, alsoerr);
"Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d", v,
severity, err, alsoerr);
FlagSaver saver;
@ -463,28 +454,48 @@ void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
LOG_IF(ERROR, false) << "don't log_if error";
int c;
c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
c = 1;
VLOG_IF(100, c -= 2) << "vlog_if 100 expr";
EXPECT_EQ(c, -1);
c = 1;
VLOG_IF(0, c -= 2) << "vlog_if 0 expr";
EXPECT_EQ(c, -1);
c = 1;
LOG_IF(INFO, c -= 2) << "log_if info expr";
EXPECT_EQ(c, -1);
c = 1;
LOG_IF(ERROR, c -= 2) << "log_if error expr";
EXPECT_EQ(c, -1);
c = 2;
VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr";
EXPECT_EQ(c, 0);
c = 2;
LOG_IF(ERROR, c -= 2) << "don't log_if error expr";
EXPECT_EQ(c, 0);
c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
c = 3;
LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
EXPECT_EQ(c, -1);
c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
c = 3;
LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
EXPECT_EQ(c, -1);
c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
c = 4;
LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
EXPECT_EQ(c, 0);
c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
c = 4;
LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
EXPECT_EQ(c, 0);
c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
c = 5;
VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
EXPECT_EQ(c, 1);
c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
c = 5;
VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
EXPECT_EQ(c, 1);
c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
c = 6;
VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
EXPECT_EQ(c, 0);
c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
c = 6;
VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
EXPECT_EQ(c, 0);
}
@ -523,19 +534,24 @@ TEST(DeathRawCHECK, logging) {
ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
"RAW: Check false failed: failure 1");
ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
"RAW: Check 1 == 2 failed: failure 2");
"RAW: Check 1 == 2 failed: failure 2");
}
void TestLogString() {
vector<string> errors;
vector<string>* no_errors = nullptr;
LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
LOG_STRING(INFO, &errors) << "LOG_STRING: "
<< "collected info";
LOG_STRING(WARNING, &errors) << "LOG_STRING: "
<< "collected warning";
LOG_STRING(ERROR, &errors) << "LOG_STRING: "
<< "collected error";
LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
LOG_STRING(INFO, no_errors) << "LOG_STRING: "
<< "reported info";
LOG_STRING(WARNING, no_errors) << "LOG_STRING: "
<< "reported warning";
LOG_STRING(ERROR, nullptr) << "LOG_STRING: "
<< "reported error";
@ -548,15 +564,20 @@ void TestLogToString() {
string error;
string* no_error = nullptr;
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: "
<< "collected info";
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: "
<< "collected warning";
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: "
<< "collected error";
LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: "
<< "reported info";
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: "
<< "reported warning";
LOG_TO_STRING(ERROR, nullptr) << "LOG_TO_STRING: "
<< "reported error";
}
@ -568,8 +589,8 @@ class TestLogSinkImpl : public LogSink {
const char* base_filename, int line,
const LogMessageTime& logmsgtime, const char* message,
size_t message_len) override {
errors.push_back(
ToString(severity, base_filename, line, logmsgtime, message, message_len));
errors.push_back(ToString(severity, base_filename, line, logmsgtime,
message, message_len));
}
};
@ -577,26 +598,36 @@ void TestLogSink() {
TestLogSinkImpl sink;
LogSink* no_sink = nullptr;
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: "
<< "collected info";
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: "
<< "collected warning";
LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: "
<< "collected error";
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: "
<< "reported info";
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: "
<< "reported warning";
LOG_TO_SINK(nullptr, ERROR) << "LOG_TO_SINK: "
<< "reported error";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "collected info";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "collected warning";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "collected error";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "thrashed info";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "thrashed warning";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(nullptr, ERROR)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "thrashed error";
@ -608,10 +639,7 @@ void TestLogSink() {
}
// For testing using CHECK*() on anonymous enums.
enum {
CASE_A,
CASE_B
};
enum { CASE_A, CASE_B };
void TestCHECK() {
// Tests using CHECK*() on int values.
@ -641,9 +669,9 @@ void TestCHECK() {
void TestDCHECK() {
#if defined(NDEBUG)
DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode";
#endif
DCHECK( 1 == 1 );
DCHECK(1 == 1);
DCHECK_EQ(1, 1);
DCHECK_NE(1, 2);
DCHECK_GE(1, 1);
@ -668,9 +696,8 @@ void TestSTREQ() {
CHECK_STRNE("this", nullptr);
CHECK_STRCASENE("this", "that");
CHECK_STRCASENE(nullptr, "that");
CHECK_STREQ((string("a")+"b").c_str(), "ab");
CHECK_STREQ(string("test").c_str(),
(string("te") + string("st")).c_str());
CHECK_STREQ((string("a") + "b").c_str(), "ab");
CHECK_STREQ(string("test").c_str(), (string("te") + string("st")).c_str());
}
TEST(DeathSTREQ, logging) {
@ -680,18 +707,18 @@ TEST(DeathSTREQ, logging) {
ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
ASSERT_DEATH(CHECK_STRNE(nullptr, nullptr), "");
ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
ASSERT_DEATH(CHECK_STREQ((string("a") + "b").c_str(), "abc"), "");
}
TEST(CheckNOTNULL, Simple) {
int64 t;
void *ptr = static_cast<void *>(&t);
void *ref = CHECK_NOTNULL(ptr);
void* ptr = static_cast<void*>(&t);
void* ref = CHECK_NOTNULL(ptr);
EXPECT_EQ(ptr, ref);
CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
CHECK_NOTNULL(reinterpret_cast<char*>(ptr));
CHECK_NOTNULL(reinterpret_cast<unsigned char*>(ptr));
CHECK_NOTNULL(reinterpret_cast<int*>(ptr));
CHECK_NOTNULL(reinterpret_cast<int64*>(ptr));
}
TEST(DeathCheckNN, Simple) {
@ -728,7 +755,7 @@ static void GetFiles(const string& pattern, vector<string>* files) {
LOG_SYSRESULT(GetLastError());
}
#else
# error There is no way to do glob.
# error There is no way to do glob.
#endif
}
@ -741,8 +768,9 @@ static void DeleteFiles(const string& pattern) {
}
}
//check string is in file (or is *NOT*, depending on optional checkInFileOrNot)
static void CheckFile(const string& name, const string& expected_string, const bool checkInFileOrNot = true) {
// check string is in file (or is *NOT*, depending on optional checkInFileOrNot)
static void CheckFile(const string& name, const string& expected_string,
const bool checkInFileOrNot = true) {
vector<string> files;
GetFiles(name + "*", &files);
CHECK_EQ(files.size(), 1UL);
@ -760,7 +788,8 @@ static void CheckFile(const string& name, const string& expected_string, const b
}
}
fclose(file);
LOG(FATAL) << "Did " << (checkInFileOrNot? "not " : "") << "find " << expected_string << " in " << files[0];
LOG(FATAL) << "Did " << (checkInFileOrNot ? "not " : "") << "find "
<< expected_string << " in " << files[0];
}
static void TestBasename() {
@ -780,8 +809,11 @@ static void TestBasename() {
}
static void TestBasenameAppendWhenNoTimestamp() {
fprintf(stderr, "==== Test setting log file basename without timestamp and appending properly\n");
const string dest = FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp";
fprintf(stderr,
"==== Test setting log file basename without timestamp and appending "
"properly\n");
const string dest =
FLAGS_test_tmpdir + "/logging_test_basename_append_when_no_timestamp";
DeleteFiles(dest + "*");
ofstream out(dest.c_str());
@ -790,13 +822,13 @@ static void TestBasenameAppendWhenNoTimestamp() {
CheckFile(dest, "test preexisting content");
FLAGS_timestamp_in_logfile_name=false;
FLAGS_timestamp_in_logfile_name = false;
SetLogDestination(GLOG_INFO, dest.c_str());
LOG(INFO) << "message to new base, appending to preexisting file";
FlushLogFiles(GLOG_INFO);
FLAGS_timestamp_in_logfile_name=true;
FLAGS_timestamp_in_logfile_name = true;
//if the logging overwrites the file instead of appending it will fail.
// if the logging overwrites the file instead of appending it will fail.
CheckFile(dest, "test preexisting content");
CheckFile(dest, "message to new base, appending to preexisting file");
@ -806,14 +838,18 @@ static void TestBasenameAppendWhenNoTimestamp() {
}
static void TestTwoProcessesWrite() {
// test only implemented for platforms with fork & wait; the actual implementation relies on flock
// test only implemented for platforms with fork & wait; the actual
// implementation relies on flock
#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL)
fprintf(stderr, "==== Test setting log file basename and two processes writing - second should fail\n");
const string dest = FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing";
fprintf(stderr,
"==== Test setting log file basename and two processes writing - "
"second should fail\n");
const string dest =
FLAGS_test_tmpdir + "/logging_test_basename_two_processes_writing";
DeleteFiles(dest + "*");
//make both processes write into the same file (easier test)
FLAGS_timestamp_in_logfile_name=false;
// make both processes write into the same file (easier test)
FLAGS_timestamp_in_logfile_name = false;
SetLogDestination(GLOG_INFO, dest.c_str());
LOG(INFO) << "message to new base, parent";
FlushLogFiles(GLOG_INFO);
@ -821,16 +857,20 @@ static void TestTwoProcessesWrite() {
pid_t pid = fork();
CHECK_ERR(pid);
if (pid == 0) {
LOG(INFO) << "message to new base, child - should only appear on STDERR not on the file";
ShutdownGoogleLogging(); //for children proc
LOG(INFO) << "message to new base, child - should only appear on STDERR "
"not on the file";
ShutdownGoogleLogging(); // for children proc
exit(EXIT_SUCCESS);
} else if (pid > 0) {
wait(nullptr);
}
FLAGS_timestamp_in_logfile_name=true;
FLAGS_timestamp_in_logfile_name = true;
CheckFile(dest, "message to new base, parent");
CheckFile(dest, "message to new base, child - should only appear on STDERR not on the file", false);
CheckFile(dest,
"message to new base, child - should only appear on STDERR not on "
"the file",
false);
// Release
LogToStderr();
@ -924,7 +964,7 @@ static void TestErrno() {
CHECK_EQ(errno, ENOENT);
}
static void TestOneTruncate(const char *path, uint64 limit, uint64 keep,
static void TestOneTruncate(const char* path, uint64 limit, uint64 keep,
size_t dsize, size_t ksize, size_t expect) {
int fd;
CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
@ -992,33 +1032,31 @@ static void TestTruncate() {
// MacOSX 10.4 doesn't fail in this case.
// Windows doesn't have symlink.
// Let's just ignore this test for these cases.
#if !defined(GLOG_OS_MACOSX) && !defined(GLOG_OS_WINDOWS)
# if !defined(GLOG_OS_MACOSX) && !defined(GLOG_OS_WINDOWS)
// Through a symlink should fail to truncate
string linkname = path + ".link";
unlink(linkname.c_str());
CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
#endif
# endif
// The /proc/self path makes sense only for linux.
#if defined(GLOG_OS_LINUX)
# if defined(GLOG_OS_LINUX)
// Through an open fd symlink should work
int fd;
CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
char fdpath[64];
std::snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
#endif
# endif
#endif
}
struct RecordDeletionLogger : public base::Logger {
RecordDeletionLogger(bool* set_on_destruction,
base::Logger* wrapped_logger) :
set_on_destruction_(set_on_destruction),
wrapped_logger_(wrapped_logger)
{
RecordDeletionLogger(bool* set_on_destruction, base::Logger* wrapped_logger)
: set_on_destruction_(set_on_destruction),
wrapped_logger_(wrapped_logger) {
*set_on_destruction_ = false;
}
~RecordDeletionLogger() override { *set_on_destruction_ = true; }
@ -1074,9 +1112,9 @@ std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
}
// get elapsed time in nanoseconds
int64 elapsedTime_ns(const std::chrono::steady_clock::time_point& begin,
const std::chrono::steady_clock::time_point& end) {
const std::chrono::steady_clock::time_point& end) {
return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin))
.count();
.count();
}
static void TestLogPeriodically() {
@ -1087,16 +1125,16 @@ static void TestLogPeriodically() {
constexpr double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9;
while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) {
LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
<< timeLogger << "Timed Message #" << timeLogger.m_streamTimes;
LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
<< timeLogger << "Timed Message #" << timeLogger.m_streamTimes;
}
// Calculate time between each call in nanoseconds for higher resolution to
// minimize error.
int64 nsBetweenCalls[LogTimes::MAX_CALLS - 1];
for (size_t i = 1; i < LogTimes::MAX_CALLS; ++i) {
nsBetweenCalls[i - 1] = elapsedTime_ns(
timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]);
nsBetweenCalls[i - 1] = elapsedTime_ns(timeLogger.m_callTimes[i - 1],
timeLogger.m_callTimes[i]);
}
for (long time_ns : nsBetweenCalls) {
@ -1107,17 +1145,18 @@ static void TestLogPeriodically() {
namespace google {
namespace glog_internal_namespace_ {
extern // in logging.cc
bool SafeFNMatch_(const char* pattern, size_t patt_len,
const char* str, size_t str_len);
} // namespace glog_internal_namespace_
bool
SafeFNMatch_(const char* pattern, size_t patt_len, const char* str,
size_t str_len);
} // namespace glog_internal_namespace_
using glog_internal_namespace_::SafeFNMatch_;
} // namespace google
static bool WrapSafeFNMatch(string pattern, string str) {
pattern += "abc";
str += "defgh";
return SafeFNMatch_(pattern.data(), pattern.size() - 3,
str.data(), str.size() - 5);
return SafeFNMatch_(pattern.data(), pattern.size() - 3, str.data(),
str.size() - 5);
}
TEST(SafeFNMatch, logging) {
@ -1184,7 +1223,6 @@ class TestLogSinkWriter : public Thread {
}
private:
// helpers ---------------
// For creating a "Condition".
@ -1239,7 +1277,6 @@ class TestLogSinkWriter : public Thread {
// (that other thread can than use LOG() itself),
class TestWaitingLogSink : public LogSink {
public:
TestWaitingLogSink() {
tid_ = pthread_self(); // for thread-specific behavior
AddLogSink(this);
@ -1260,18 +1297,17 @@ class TestWaitingLogSink : public LogSink {
// Note: Something like ThreadLocalLogSink is a better choice
// to do thread-specific LogSink logic for real.
if (pthread_equal(tid_, pthread_self())) {
writer_.Buffer(ToString(severity, base_filename, line,
logmsgtime, message, message_len));
writer_.Buffer(ToString(severity, base_filename, line, logmsgtime,
message, message_len));
}
}
void WaitTillSent() override {
// Wait for Writer thread if we are the original logging thread.
if (pthread_equal(tid_, pthread_self())) writer_.Wait();
if (pthread_equal(tid_, pthread_self())) writer_.Wait();
}
private:
pthread_t tid_;
TestLogSinkWriter writer_;
};
@ -1282,7 +1318,8 @@ static void TestLogSinkWaitTillSent() {
// Clear global_messages here to make sure that this test case can be
// reentered
global_messages.clear();
{ TestWaitingLogSink sink;
{
TestWaitingLogSink sink;
// Sleeps give the sink threads time to do all their work,
// so that we get a reliable log capture to compare to the golden file.
LOG(INFO) << "Message 1";
@ -1300,15 +1337,16 @@ static void TestLogSinkWaitTillSent() {
TEST(Strerror, logging) {
int errcode = EINTR;
char *msg = strdup(strerror(errcode));
char* msg = strdup(strerror(errcode));
const size_t buf_size = strlen(msg) + 1;
char *buf = new char[buf_size];
char* buf = new char[buf_size];
CHECK_EQ(posix_strerror_r(errcode, nullptr, 0), -1);
buf[0] = 'A';
CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
CHECK_EQ(buf[0], 'A');
CHECK_EQ(posix_strerror_r(errcode, nullptr, buf_size), -1);
#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || \
defined(GLOG_OS_OPENBSD)
// MacOSX or FreeBSD considers this case is an error since there is
// no enough space.
CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
@ -1338,12 +1376,12 @@ static void MyCheck(bool a, bool b) {
TEST(DVLog, Basic) {
ScopedMockLog log;
#if defined(NDEBUG)
# if defined(NDEBUG)
// We are expecting that nothing is logged.
EXPECT_CALL(log, Log(_, _, _)).Times(0);
#else
# else
EXPECT_CALL(log, Log(GLOG_INFO, __FILE__, "debug log"));
#endif
# endif
FLAGS_v = 1;
DVLOG(1) << "debug log";
@ -1385,15 +1423,15 @@ TEST(TestExitOnDFatal, ToBeOrNotToBe) {
// We don't die.
{
ScopedMockLog log;
//EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
// LOG(DFATAL) has severity FATAL if debugging, but is
// downgraded to ERROR if not debugging.
// EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
// LOG(DFATAL) has severity FATAL if debugging, but is
// downgraded to ERROR if not debugging.
const LogSeverity severity =
#if defined(NDEBUG)
# if defined(NDEBUG)
GLOG_ERROR;
#else
# else
GLOG_FATAL;
#endif
# endif
EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
LOG(DFATAL) << "This should not be fatal";
}
@ -1402,20 +1440,19 @@ TEST(TestExitOnDFatal, ToBeOrNotToBe) {
base::internal::SetExitOnDFatal(true);
EXPECT_TRUE(base::internal::GetExitOnDFatal());
#ifdef GTEST_HAS_DEATH_TEST
# ifdef GTEST_HAS_DEATH_TEST
// Death comes on little cats' feet.
EXPECT_DEBUG_DEATH({
LOG(DFATAL) << "This should be fatal in debug mode";
}, "This should be fatal in debug mode");
#endif
EXPECT_DEBUG_DEATH({ LOG(DFATAL) << "This should be fatal in debug mode"; },
"This should be fatal in debug mode");
# endif
}
#ifdef HAVE_STACKTRACE
# ifdef HAVE_STACKTRACE
static void BacktraceAtHelper() {
LOG(INFO) << "Not me";
// The vertical spacing of the next 3 lines is significant.
// The vertical spacing of the next 3 lines is significant.
LOG(INFO) << "Backtrace me";
}
static int kBacktraceAtLine = __LINE__ - 2; // The line of the LOG(INFO) above
@ -1443,19 +1480,19 @@ TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
// the name of the containing function, followed by the log message.
// We use HasSubstr()s instead of ContainsRegex() for environments
// which don't have regexp.
EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
HasSubstr("BacktraceAtHelper"),
HasSubstr("main"),
HasSubstr("Backtrace me"))));
EXPECT_CALL(
log, Log(_, _,
AllOf(HasSubstr("stacktrace:"), HasSubstr("BacktraceAtHelper"),
HasSubstr("main"), HasSubstr("Backtrace me"))));
// Other LOGs should not include a backtrace.
EXPECT_CALL(log, Log(_, _, "Not me"));
BacktraceAtHelper();
}
#endif // HAVE_STACKTRACE
# endif // HAVE_STACKTRACE
#endif // HAVE_LIB_GMOCK
#endif // HAVE_LIB_GMOCK
struct UserDefinedClass {
bool operator==(const UserDefinedClass&) const { return true; }
@ -1480,7 +1517,8 @@ TEST(UserDefinedClass, logging) {
TEST(LogMsgTime, gmtoff) {
/*
* Unit test for GMT offset API
* TODO: To properly test this API, we need a platform independent way to set time-zone.
* TODO: To properly test this API, we need a platform independent way to set
* time-zone.
* */
google::LogMessage log_obj(__FILE__, __LINE__);
@ -1488,21 +1526,23 @@ TEST(LogMsgTime, gmtoff) {
// GMT offset ranges from UTC-12:00 to UTC+14:00
const long utc_min_offset = -43200;
const long utc_max_offset = 50400;
EXPECT_TRUE( (nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset) );
EXPECT_TRUE((nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset));
}
TEST(EmailLogging, ValidAddress) {
FlagSaver saver;
FLAGS_logmailer = "/usr/bin/true";
EXPECT_TRUE(SendEmail("example@example.com", "Example subject", "Example body"));
EXPECT_TRUE(
SendEmail("example@example.com", "Example subject", "Example body"));
}
TEST(EmailLogging, MultipleAddresses) {
FlagSaver saver;
FLAGS_logmailer = "/usr/bin/true";
EXPECT_TRUE(SendEmail("example@example.com,foo@bar.com", "Example subject", "Example body"));
EXPECT_TRUE(SendEmail("example@example.com,foo@bar.com", "Example subject",
"Example body"));
}
TEST(EmailLogging, InvalidAddress) {
@ -1516,5 +1556,6 @@ TEST(EmailLogging, MaliciousAddress) {
FlagSaver saver;
FLAGS_logmailer = "/usr/bin/true";
EXPECT_FALSE(SendEmail("!/bin/true@example.com", "Example subject", "Example body"));
EXPECT_FALSE(
SendEmail("!/bin/true@example.com", "Example subject", "Example body"));
}

View File

@ -33,11 +33,11 @@
#include "mock-log.h"
#include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>
namespace {
using google::GLOG_ERROR;
@ -57,8 +57,7 @@ TEST(ScopedMockLogTest, InterceptsLog) {
InSequence s;
EXPECT_CALL(log,
Log(GLOG_WARNING, EndsWith("mock-log_unittest.cc"), "Fishy."));
EXPECT_CALL(log, Log(GLOG_INFO, _, "Working..."))
.Times(2);
EXPECT_CALL(log, Log(GLOG_INFO, _, "Working...")).Times(2);
EXPECT_CALL(log, Log(GLOG_ERROR, _, "Bad!!"));
LOG(WARNING) << "Fishy.";
@ -67,13 +66,9 @@ TEST(ScopedMockLogTest, InterceptsLog) {
LOG(ERROR) << "Bad!!";
}
void LogBranch() {
LOG(INFO) << "Logging a branch...";
}
void LogBranch() { LOG(INFO) << "Logging a branch..."; }
void LogTree() {
LOG(INFO) << "Logging the whole tree...";
}
void LogTree() { LOG(INFO) << "Logging the whole tree..."; }
void LogForest() {
LOG(INFO) << "Logging the entire forest.";
@ -99,7 +94,7 @@ TEST(ScopedMockLogTest, LogDuringIntercept) {
} // namespace
int main(int argc, char **argv) {
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
testing::InitGoogleTest(&argc, argv);
testing::InitGoogleMock(&argc, argv);

View File

@ -1,6 +1,3 @@
#include "glog/logging.h"
int main(int /*argc*/, char** argv)
{
google::InitGoogleLogging(argv[0]);
}
int main(int /*argc*/, char** argv) { google::InitGoogleLogging(argv[0]); }

View File

@ -37,7 +37,7 @@
#include "utilities.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h> // for close() and write()
# include <unistd.h> // for close() and write()
#endif
#include <fcntl.h> // for open()
@ -49,37 +49,37 @@
#include "glog/raw_logging.h"
#ifdef HAVE_STACKTRACE
# include "stacktrace.h"
# include "stacktrace.h"
#endif
#if defined(HAVE_SYSCALL_H)
#include <syscall.h> // for syscall()
# include <syscall.h> // for syscall()
#elif defined(HAVE_SYS_SYSCALL_H)
#include <sys/syscall.h> // for syscall()
# include <sys/syscall.h> // for syscall()
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
# include <unistd.h>
#endif
#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_EMSCRIPTEN)
#define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
#else
// Not so safe, but what can you do?
#define safe_write(fd, s, len) write(fd, s, len)
# define safe_write(fd, s, len) write(fd, s, len)
#endif
namespace google {
#if defined(__GNUC__)
#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck) \
__attribute__((format(archetype, stringIndex, firstToCheck)))
#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex) \
__attribute__((format_arg(stringIndex)))
# define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck) \
__attribute__((format(archetype, stringIndex, firstToCheck)))
# define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex) \
__attribute__((format_arg(stringIndex)))
#else
#define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck)
#define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex)
# define GLOG_ATTRIBUTE_FORMAT(archetype, stringIndex, firstToCheck)
# define GLOG_ATTRIBUTE_FORMAT_ARG(stringIndex)
#endif
// CAVEAT: std::vsnprintf called from *DoRawLog below has some (exotic) code
@ -103,15 +103,15 @@ static bool DoRawLog(char** buf, size_t* size, const char* format, ...) {
}
// Helper for RawLog__ below.
inline static bool VADoRawLog(char** buf, size_t* size,
const char* format, va_list ap) {
inline static bool VADoRawLog(char** buf, size_t* size, const char* format,
va_list ap) {
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
int n = std::vsnprintf(*buf, *size, format, ap);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
# pragma GCC diagnostic pop
#endif
if (n < 0 || static_cast<size_t>(n) > *size) return false;
*size -= static_cast<size_t>(n);
@ -122,7 +122,7 @@ inline static bool VADoRawLog(char** buf, size_t* size,
static const int kLogBufSize = 3000;
static bool crashed = false;
static CrashReason crash_reason;
static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0'
static char crash_buf[kLogBufSize + 1] = {0}; // Will end in '\0'
GLOG_ATTRIBUTE_FORMAT(printf, 4, 5)
void RawLog__(LogSeverity severity, const char* file, int line,
@ -139,9 +139,8 @@ 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 %5u %s:%d] RAW: ",
LogSeverityNames[severity][0],
static_cast<unsigned int>(GetTID()),
const_basename(const_cast<char *>(file)), line);
LogSeverityNames[severity][0], static_cast<unsigned int>(GetTID()),
const_basename(const_cast<char*>(file)), line);
// Record the position and size of the buffer after the prefix
const char* msg_start = buf;
@ -161,7 +160,7 @@ void RawLog__(LogSeverity severity, const char* file, int line,
// libc (to side-step any libc interception).
// We write just once to avoid races with other invocations of RawLog__.
safe_write(STDERR_FILENO, buffer, strlen(buffer));
if (severity == GLOG_FATAL) {
if (severity == GLOG_FATAL) {
if (!sync_val_compare_and_swap(&crashed, false, true)) {
crash_reason.filename = file;
crash_reason.line_number = line;

View File

@ -41,13 +41,13 @@
#include "utilities.h"
#ifdef HAVE_UCONTEXT_H
# include <ucontext.h>
# include <ucontext.h>
#endif
#ifdef HAVE_SYS_UCONTEXT_H
# include <sys/ucontext.h>
# include <sys/ucontext.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
# include <unistd.h>
#endif
namespace google {
@ -61,16 +61,14 @@ namespace {
// The list should be synced with the comment in signalhandler.h.
const struct {
int number;
const char *name;
const char* name;
} kFailureSignals[] = {
{ SIGSEGV, "SIGSEGV" },
{ SIGILL, "SIGILL" },
{ SIGFPE, "SIGFPE" },
{ SIGABRT, "SIGABRT" },
{SIGSEGV, "SIGSEGV"}, {SIGILL, "SIGILL"},
{SIGFPE, "SIGFPE"}, {SIGABRT, "SIGABRT"},
#if !defined(GLOG_OS_WINDOWS)
{ SIGBUS, "SIGBUS" },
{SIGBUS, "SIGBUS"},
#endif
{ SIGTERM, "SIGTERM" },
{SIGTERM, "SIGTERM"},
};
static bool kFailureSignalHandlerInstalled = false;
@ -78,14 +76,15 @@ static bool kFailureSignalHandlerInstalled = false;
#if !defined(GLOG_OS_WINDOWS)
// Returns the program counter from signal context, nullptr if unknown.
void* GetPC(void* ucontext_in_void) {
#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
# if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && \
defined(PC_FROM_UCONTEXT)
if (ucontext_in_void != nullptr) {
ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
ucontext_t* context = reinterpret_cast<ucontext_t*>(ucontext_in_void);
return (void*)context->PC_FROM_UCONTEXT;
}
#else
# else
(void)ucontext_in_void;
#endif
# endif
return nullptr;
}
#endif
@ -94,14 +93,13 @@ void* GetPC(void* ucontext_in_void) {
// as it's not async signal safe.
class MinimalFormatter {
public:
MinimalFormatter(char *buffer, size_t size)
: buffer_(buffer),
cursor_(buffer),
end_(buffer + size) {
}
MinimalFormatter(char* buffer, size_t size)
: buffer_(buffer), cursor_(buffer), end_(buffer + size) {}
// Returns the number of bytes written in the buffer.
std::size_t num_bytes_written() const { return static_cast<std::size_t>(cursor_ - buffer_); }
std::size_t num_bytes_written() const {
return static_cast<std::size_t>(cursor_ - buffer_);
}
// Appends string from "str" and updates the internal cursor.
void AppendString(const char* str) {
@ -147,9 +145,9 @@ class MinimalFormatter {
}
private:
char *buffer_;
char *cursor_;
const char * const end_;
char* buffer_;
char* cursor_;
const char* const end_;
};
// Writes the given data with the size to the standard error.
@ -181,7 +179,7 @@ void DumpTimeInfo() {
#if defined(HAVE_STACKTRACE) && defined(HAVE_SIGACTION)
// Dumps information about the signal to STDERR.
void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
void DumpSignalInfo(int signal_number, siginfo_t* siginfo) {
// Get the signal name.
const char* signal_name = nullptr;
for (auto kFailureSignal : kFailureSignals) {
@ -217,11 +215,11 @@ void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
reinterpret_cast<uint64>(reinterpret_cast<const char*>(id)), 16);
formatter.AppendString(") ");
// Only linux has the PID of the signal sender in si_pid.
#ifdef GLOG_OS_LINUX
# ifdef GLOG_OS_LINUX
formatter.AppendString("from PID ");
formatter.AppendUint64(static_cast<uint64>(siginfo->si_pid), 10);
formatter.AppendString("; ");
#endif
# endif
formatter.AppendString("stack trace: ***\n");
g_failure_writer(buf, formatter.num_bytes_written());
}
@ -231,12 +229,12 @@ void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
// Dumps information about the stack frame to STDERR.
void DumpStackFrameInfo(const char* prefix, void* pc) {
// Get the symbol name.
const char *symbol = "(unknown)";
const char* symbol = "(unknown)";
char symbolized[1024]; // Big enough for a sane symbol.
// Symbolizes the previous address of pc because pc may be in the
// next function.
if (Symbolize(reinterpret_cast<char *>(pc) - 1,
symbolized, sizeof(symbolized))) {
if (Symbolize(reinterpret_cast<char*>(pc) - 1, symbolized,
sizeof(symbolized))) {
symbol = symbolized;
}
@ -279,9 +277,8 @@ static pthread_t* g_entered_thread_id_pointer = nullptr;
#if defined(GLOG_OS_WINDOWS)
void FailureSignalHandler(int signal_number)
#else
void FailureSignalHandler(int signal_number,
siginfo_t *signal_info,
void *ucontext)
void FailureSignalHandler(int signal_number, siginfo_t* signal_info,
void* ucontext)
#endif
{
// First check if we've already entered the function. We use an atomic
@ -324,20 +321,20 @@ void FailureSignalHandler(int signal_number,
#if !defined(GLOG_OS_WINDOWS)
// Get the program counter from ucontext.
void *pc = GetPC(ucontext);
void* pc = GetPC(ucontext);
DumpStackFrameInfo("PC: ", pc);
#endif
#ifdef HAVE_STACKTRACE
// Get the stack traces.
void *stack[32];
void* stack[32];
// +1 to exclude this function.
const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
# ifdef HAVE_SIGACTION
# ifdef HAVE_SIGACTION
DumpSignalInfo(signal_number, signal_info);
#elif !defined(GLOG_OS_WINDOWS)
# elif !defined(GLOG_OS_WINDOWS)
(void)signal_info;
# endif
# endif
// Dump the stack traces.
for (int i = 0; i < depth; ++i) {
DumpStackFrameInfo(" ", stack[i]);
@ -400,8 +397,7 @@ void InstallFailureSignalHandler() {
kFailureSignalHandlerInstalled = true;
#elif defined(GLOG_OS_WINDOWS)
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler),
SIG_ERR);
CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler), SIG_ERR);
}
kFailureSignalHandlerInstalled = true;
#endif // HAVE_SIGACTION

View File

@ -35,7 +35,7 @@
#include "utilities.h"
#if defined(HAVE_PTHREAD)
# include <pthread.h>
# include <pthread.h>
#endif
#include <csignal>
#include <cstdio>
@ -45,7 +45,7 @@
#include "glog/logging.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
@ -72,12 +72,12 @@ static void WriteToStdout(const char* data, size_t size) {
}
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE)
InitGoogleLogging(argv[0]);
#ifdef GLOG_USE_GFLAGS
# ifdef GLOG_USE_GFLAGS
ParseCommandLineFlags(&argc, &argv, true);
#endif
# endif
InstallFailureSignalHandler();
const std::string command = argc > 1 ? argv[1] : "none";
if (command == "segv") {
@ -85,26 +85,27 @@ int main(int argc, char **argv) {
LOG(INFO) << "create the log file";
LOG(INFO) << "a message before segv";
// We assume 0xDEAD is not writable.
int *a = (int*)0xDEAD;
int* a = (int*)0xDEAD;
*a = 0;
} else if (command == "loop") {
fprintf(stderr, "looping\n");
while (true);
while (true)
;
} else if (command == "die_in_thread") {
#if defined(HAVE_PTHREAD)
# if defined(HAVE_PTHREAD)
pthread_t thread;
pthread_create(&thread, nullptr, &DieInThread, nullptr);
pthread_join(thread, nullptr);
#else
# else
fprintf(stderr, "no pthread\n");
return 1;
#endif
# endif
} else if (command == "dump_to_stdout") {
InstallFailureWriter(WriteToStdout);
abort();
} else if (command == "installed") {
fprintf(stderr, "signal handler installed: %s\n",
IsFailureSignalHandlerInstalled() ? "true" : "false");
IsFailureSignalHandlerInstalled() ? "true" : "false");
} else {
// Tell the shell script
puts("OK");

View File

@ -42,7 +42,7 @@ namespace google {
// If you change this function, also change GetStackFrames below.
int GetStackTrace(void** result, int max_depth, int skip_count) {
static const int kStackLength = 64;
void * stack[kStackLength];
void* stack[kStackLength];
int size;
size = backtrace(stack, kStackLength);

View File

@ -51,11 +51,11 @@ namespace google {
// cases, we return 0 to indicate the situation.
// We can use the GCC __thread syntax here since libunwind is not supported on
// Windows.
static __thread bool g_tl_entered; // Initialized to false.
static __thread bool g_tl_entered; // Initialized to false.
// If you change this function, also change GetStackFrames below.
int GetStackTrace(void** result, int max_depth, int skip_count) {
void *ip;
void* ip;
int n = 0;
unw_cursor_t cursor;
unw_context_t uc;
@ -67,11 +67,11 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
unw_getcontext(&uc);
RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
skip_count++; // Do not include the "GetStackTrace" frame
skip_count++; // Do not include the "GetStackTrace" frame
while (n < max_depth) {
int ret =
unw_get_reg(&cursor, UNW_REG_IP, reinterpret_cast<unw_word_t *>(&ip));
unw_get_reg(&cursor, UNW_REG_IP, reinterpret_cast<unw_word_t*>(&ip));
if (ret < 0) {
break;
}

View File

@ -46,9 +46,9 @@ namespace google {
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING>
static void **NextStackFrame(void **old_sp) {
void **new_sp = static_cast<void **>(*old_sp);
template <bool STRICT_UNWINDING>
static void** NextStackFrame(void** old_sp) {
void** new_sp = static_cast<void**>(*old_sp);
// Check that the transition from frame pointer old_sp to frame
// pointer new_sp isn't clearly bogus
@ -68,7 +68,7 @@ static void **NextStackFrame(void **old_sp) {
return nullptr;
}
}
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return nullptr;
if ((uintptr_t)new_sp & (sizeof(void*) - 1)) return nullptr;
return new_sp;
}
@ -78,15 +78,15 @@ void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
// If you change this function, also change GetStackFrames below.
int GetStackTrace(void** result, int max_depth, int skip_count) {
void **sp;
void** sp;
// Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
// and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a
// different asm syntax. I don't know quite the best way to discriminate
// systems using the old as from the new one; I've gone with __APPLE__.
#ifdef __APPLE__
__asm__ volatile ("mr %0,r1" : "=r" (sp));
__asm__ volatile("mr %0,r1" : "=r"(sp));
#else
__asm__ volatile ("mr %0,1" : "=r" (sp));
__asm__ volatile("mr %0,1" : "=r"(sp));
#endif
// On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
@ -111,17 +111,18 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
// linux ppc64), it's in sp[2]. For SYSV (used by linux ppc),
// it's in sp[1].
#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
result[n++] = *(sp+2);
result[n++] = *(sp + 2);
#elif defined(_CALL_SYSV)
result[n++] = *(sp+1);
#elif defined(__APPLE__) || ((defined(__linux) || defined(__linux__)) && defined(__PPC64__))
result[n++] = *(sp + 1);
#elif defined(__APPLE__) || \
((defined(__linux) || defined(__linux__)) && defined(__PPC64__))
// This check is in case the compiler doesn't define _CALL_AIX/etc.
result[n++] = *(sp+2);
result[n++] = *(sp + 2);
#elif defined(__linux) || defined(__OpenBSD__)
// This check is in case the compiler doesn't define _CALL_SYSV.
result[n++] = *(sp+1);
result[n++] = *(sp + 1);
#else
#error Need to specify the PPC ABI for your architecture.
# error Need to specify the PPC ABI for your architecture.
#endif
}
// Use strict unwinding rules.

View File

@ -38,7 +38,7 @@
#include "utilities.h"
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
# include <execinfo.h>
# include <execinfo.h>
#endif
using namespace google;
@ -59,68 +59,74 @@ struct AddressRange {
// Expected function [start,end] range.
AddressRange expected_range[BACKTRACE_STEPS];
#if __GNUC__
# if __GNUC__
// Using GCC extension: address of a label can be taken with '&&label'.
// Start should be a label somewhere before recursive call, end somewhere
// after it.
#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
do { \
(prange)->start = &&start_label; \
(prange)->end = &&end_label; \
CHECK_LT((prange)->start, (prange)->end); \
} while (0)
# define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
do { \
(prange)->start = &&start_label; \
(prange)->end = &&end_label; \
CHECK_LT((prange)->start, (prange)->end); \
} while (0)
// This macro expands into "unmovable" code (opaque to GCC), and that
// prevents GCC from moving a_label up or down in the code.
// Without it, there is no code following the 'end' label, and GCC
// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before
// the recursive call.
#define DECLARE_ADDRESS_LABEL(a_label) \
a_label: do { __asm__ __volatile__(""); } while (0)
# define DECLARE_ADDRESS_LABEL(a_label) \
a_label: \
do { \
__asm__ __volatile__(""); \
} while (0)
// Gcc 4.4.0 may split function into multiple chunks, and the chunk
// performing recursive call may end up later in the code then the return
// instruction (this actually happens with FDO).
// Adjust function range from __builtin_return_address.
#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \
do { \
void *ra = __builtin_return_address(0); \
CHECK_LT((prange)->start, ra); \
if (ra > (prange)->end) { \
printf("Adjusting range from %p..%p to %p..%p\n", \
(prange)->start, (prange)->end, \
(prange)->start, ra); \
(prange)->end = ra; \
} \
} while (0)
#else
# define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \
do { \
void* ra = __builtin_return_address(0); \
CHECK_LT((prange)->start, ra); \
if (ra > (prange)->end) { \
printf("Adjusting range from %p..%p to %p..%p\n", (prange)->start, \
(prange)->end, (prange)->start, ra); \
(prange)->end = ra; \
} \
} while (0)
# else
// Assume the Check* functions below are not longer than 256 bytes.
#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
do { \
(prange)->start = reinterpret_cast<const void *>(&fn); \
(prange)->end = reinterpret_cast<const char *>(&fn) + 256; \
} while (0)
#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)
#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
#endif // __GNUC__
# define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
do { \
(prange)->start = reinterpret_cast<const void*>(&fn); \
(prange)->end = reinterpret_cast<const char*>(&fn) + 256; \
} while (0)
# define DECLARE_ADDRESS_LABEL(a_label) \
do { \
} while (0)
# define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \
do { \
} while (0)
# endif // __GNUC__
//-----------------------------------------------------------------------//
static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
{
static void CheckRetAddrIsInFunction(void* ret_addr,
const AddressRange& range) {
CHECK_GE(ret_addr, range.start);
CHECK_LE(ret_addr, range.end);
}
//-----------------------------------------------------------------------//
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-label-as-value"
#endif
# if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wgnu-label-as-value"
# endif
void ATTRIBUTE_NOINLINE CheckStackTrace(int);
static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
const int STACK_LEN = 10;
void *stack[STACK_LEN];
void* stack[STACK_LEN];
int size;
ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
@ -132,8 +138,8 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
CHECK_LE(size, STACK_LEN);
if (true) {
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
char **strings = backtrace_symbols(stack, size);
# ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
char** strings = backtrace_symbols(stack, size);
printf("Obtained %d stack frames.\n", size);
for (int i = 0; i < size; i++) {
printf("%s %p\n", strings[i], stack[i]);
@ -146,11 +152,11 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
printf("CheckStackTrace() addr: %p\n", p.p2);
free(strings);
#endif
# endif
}
for (int i = 0; i < BACKTRACE_STEPS; i++) {
printf("Backtrace %d: expected: %p..%p actual: %p ... ",
i, expected_range[i].start, expected_range[i].end, stack[i]);
printf("Backtrace %d: expected: %p..%p actual: %p ... ", i,
expected_range[i].start, expected_range[i].end, stack[i]);
fflush(stdout);
CheckRetAddrIsInFunction(stack[i], expected_range[i]);
printf("OK\n");
@ -198,7 +204,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {
DECLARE_ADDRESS_LABEL(end);
}
#ifndef __GNUC__
# ifndef __GNUC__
// On non-GNU environment, we use the address of `CheckStackTrace` to
// guess the address range of this function. This guess is wrong for
// non-static function on Windows. This is probably because
@ -206,8 +212,9 @@ static void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {
// not the actual address of `CheckStackTrace`.
// See https://github.com/google/glog/issues/421 for the detail.
static
#endif
void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
# endif
void ATTRIBUTE_NOINLINE
CheckStackTrace(int i) {
INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);
DECLARE_ADDRESS_LABEL(start);
for (int j = i; j >= 0; j--) {
@ -216,13 +223,13 @@ void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
DECLARE_ADDRESS_LABEL(end);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
# if defined(__clang__)
# pragma clang diagnostic pop
# endif
//-----------------------------------------------------------------------//
int main(int, char ** argv) {
int main(int, char** argv) {
FLAGS_logtostderr = true;
InitGoogleLogging(argv[0]);
@ -235,12 +242,12 @@ int main(int, char ** argv) {
#else
int main() {
#ifdef GLOG_BAZEL_BUILD
# ifdef GLOG_BAZEL_BUILD
printf("HAVE_STACKTRACE is expected to be defined in Bazel tests\n");
exit(EXIT_FAILURE);
#endif // GLOG_BAZEL_BUILD
# endif // GLOG_BAZEL_BUILD
printf("PASS (no stacktrace support)\n");
return 0;
}
#endif // HAVE_STACKTRACE
#endif // HAVE_STACKTRACE

View File

@ -38,41 +38,41 @@
namespace google {
struct trace_arg_t {
void **result;
void** result;
int max_depth;
int skip_count;
int count;
};
// Workaround for the malloc() in _Unwind_Backtrace() issue.
static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context */*uc*/, void */*opq*/) {
static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context* /*uc*/,
void* /*opq*/) {
return _URC_NO_REASON;
}
// This code is not considered ready to run until
// static initializers run so that we are guaranteed
// that any malloc-related initialization is done.
static bool ready_to_run = false;
class StackTraceInit {
public:
StackTraceInit() {
// Extra call to force initialization
_Unwind_Backtrace(nop_backtrace, nullptr);
ready_to_run = true;
}
StackTraceInit() {
// Extra call to force initialization
_Unwind_Backtrace(nop_backtrace, nullptr);
ready_to_run = true;
}
};
static StackTraceInit module_initializer; // Force initialization
static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
auto *targ = static_cast<trace_arg_t *>(opq);
static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context* uc, void* opq) {
auto* targ = static_cast<trace_arg_t*>(opq);
if (targ->skip_count > 0) {
targ->skip_count--;
} else {
targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc));
}
if (targ->skip_count > 0) {
targ->skip_count--;
} else {
targ->result[targ->count++] = reinterpret_cast<void*>(_Unwind_GetIP(uc));
}
if (targ->count == targ->max_depth) {
return _URC_END_OF_STACK;
@ -89,7 +89,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
trace_arg_t targ;
skip_count += 1; // Do not include the "GetStackTrace" frame
skip_count += 1; // Do not include the "GetStackTrace" frame
targ.result = result;
targ.max_depth = max_depth;

View File

@ -31,10 +31,11 @@
//
// Windows implementation - just use CaptureStackBackTrace
#include <dbghelp.h>
#include "config.h"
#include "port.h"
#include "stacktrace.h"
#include <dbghelp.h>
namespace google {

View File

@ -31,11 +31,11 @@
#include <cstdint> // for uintptr_t
#include "utilities.h" // for OS_* macros
#include "utilities.h" // for OS_* macros
#if !defined(GLOG_OS_WINDOWS)
#include <unistd.h>
#include <sys/mman.h>
# include <sys/mman.h>
# include <unistd.h>
#endif
#include <cstdio> // for nullptr
@ -48,9 +48,9 @@ namespace google {
// stackframe, or return nullptr if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING>
static void **NextStackFrame(void **old_sp) {
void **new_sp = static_cast<void **>(*old_sp);
template <bool STRICT_UNWINDING>
static void** NextStackFrame(void** old_sp) {
void** new_sp = static_cast<void**>(*old_sp);
// Check that the transition from frame pointer old_sp to frame
// pointer new_sp isn't clearly bogus
@ -75,7 +75,7 @@ static void **NextStackFrame(void **old_sp) {
return nullptr;
}
}
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) {
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void*) - 1)) {
return nullptr;
}
#ifdef __i386__
@ -92,9 +92,9 @@ static void **NextStackFrame(void **old_sp) {
// Note: NextStackFrame<false>() is only called while the program
// is already on its last leg, so it's ok to be slow here.
static int page_size = getpagesize();
void *new_sp_aligned =
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
static_cast<uintptr_t>(~(page_size - 1)));
void* new_sp_aligned =
reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(new_sp) &
static_cast<uintptr_t>(~(page_size - 1)));
if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
return nullptr;
}
@ -105,12 +105,12 @@ static void **NextStackFrame(void **old_sp) {
// If you change this function, also change GetStackFrames below.
int GetStackTrace(void** result, int max_depth, int skip_count) {
void **sp;
void** sp;
#ifdef __GNUC__
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
#define USE_BUILTIN_FRAME_ADDRESS
#endif
# if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
# define USE_BUILTIN_FRAME_ADDRESS
# endif
#endif
#ifdef USE_BUILTIN_FRAME_ADDRESS
@ -121,7 +121,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
// sp[1] caller address
// sp[2] first argument
// ...
sp = (void **)&result - 2;
sp = (void**)&result - 2;
#elif defined(__x86_64__)
// __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
unsigned long rbp;
@ -132,10 +132,10 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
// would be (before this __asm__ instruction) to call Noop() defined as
// static void Noop() __attribute__ ((noinline)); // prevent inlining
// static void Noop() { asm(""); } // prevent optimizing-away
__asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
__asm__ volatile("mov %%rbp, %0" : "=r"(rbp));
// Arguments are passed in registers on x86-64, so we can't just
// offset from &result
sp = (void **) rbp;
sp = (void**)rbp;
#endif
int n = 0;
@ -148,7 +148,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
if (skip_count > 0) {
skip_count--;
} else {
result[n++] = *(sp+1);
result[n++] = *(sp + 1);
}
// Use strict unwinding rules.
sp = NextStackFrame<true>(sp);

View File

@ -62,14 +62,14 @@ static void TestSTLLogging() {
{
// Test a sorted pair associative container.
map< int, string > m;
map<int, string> m;
m[20] = "twenty";
m[10] = "ten";
m[30] = "thirty";
ostringstream ss;
ss << m;
EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)");
map< int, string > copied_m(m);
map<int, string> copied_m(m);
CHECK_EQ(m, copied_m); // This must compile.
}
@ -95,14 +95,14 @@ static void TestSTLLogging() {
{
// Test a sorted pair associative container.
// Use a non-default comparison functor.
map<int, string, greater<> > m;
map<int, string, greater<>> m;
m[20] = "twenty";
m[10] = "ten";
m[30] = "thirty";
ostringstream ss;
ss << m;
EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
map<int, string, greater<> > copied_m(m);
map<int, string, greater<>> copied_m(m);
CHECK_EQ(m, copied_m); // This must compile.
}
}

View File

@ -57,13 +57,13 @@ int CheckNoReturn(bool b) {
}
struct A {};
std::ostream &operator<<(std::ostream &str, const A &) { return str; }
std::ostream& operator<<(std::ostream& str, const A&) { return str; }
namespace {
void handle_abort(int /*code*/) { std::exit(EXIT_FAILURE); }
} // namespace
int main(int, char *argv[]) {
int main(int, char* argv[]) {
#if defined(_MSC_VER)
// Avoid presenting an interactive dialog that will cause the test to time
// out.

View File

@ -49,20 +49,19 @@
// macro to add platform specific defines (e.g. GLOG_OS_OPENBSD).
#ifdef GLOG_BUILD_CONFIG_INCLUDE
#include GLOG_BUILD_CONFIG_INCLUDE
# include GLOG_BUILD_CONFIG_INCLUDE
#endif // GLOG_BUILD_CONFIG_INCLUDE
#include "utilities.h"
#if defined(HAVE_SYMBOLIZE)
#include <cstring>
# include <algorithm>
# include <cstring>
# include <limits>
#include <algorithm>
#include <limits>
#include "symbolize.h"
#include "demangle.h"
# include "demangle.h"
# include "symbolize.h"
namespace google {
@ -76,7 +75,7 @@ static int AssertFail() {
return 0; // Should not reach.
}
#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
# define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
static SymbolizeCallback g_symbolize_callback = nullptr;
void InstallSymbolizeCallback(SymbolizeCallback callback) {
@ -94,7 +93,7 @@ void InstallSymbolizeOpenObjectFileCallback(
// where the input symbol is demangled in-place.
// To keep stack consumption low, we would like this function to not
// get inlined.
static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, size_t out_size) {
static ATTRIBUTE_NOINLINE void DemangleInplace(char* out, size_t out_size) {
char demangled[256]; // Big enough for sane demangled symbols.
if (Demangle(out, demangled, sizeof(demangled))) {
// Demangling succeeded. Copy to out if the space allows.
@ -108,35 +107,37 @@ static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, size_t out_size) {
} // namespace google
#if defined(__ELF__)
# if defined(__ELF__)
#if defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#endif
#if defined(GLOG_OS_OPENBSD)
#include <sys/exec_elf.h>
#else
#include <elf.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
# if defined(HAVE_DLFCN_H)
# include <dlfcn.h>
# endif
# if defined(GLOG_OS_OPENBSD)
# include <sys/exec_elf.h>
# else
# include <elf.h>
# endif
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <unistd.h>
#include <cerrno>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
# include <cerrno>
# include <climits>
# include <cstddef>
# include <cstdint>
# include <cstdio>
# include <cstdlib>
# include <cstring>
#include "config.h"
#include "glog/raw_logging.h"
#include "symbolize.h"
# include "config.h"
# include "glog/raw_logging.h"
# include "symbolize.h"
// Re-runs fn until it doesn't cause EINTR.
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
# define NO_INTR(fn) \
do { \
} while ((fn) < 0 && errno == EINTR)
namespace google {
@ -144,11 +145,12 @@ namespace google {
// descriptor "fd" into the buffer starting at "buf" while handling short reads
// and EINTR. On success, return the number of bytes read. Otherwise, return
// -1.
static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count,
static ssize_t ReadFromOffset(const int fd, void* buf, const size_t count,
const size_t offset) {
SAFE_ASSERT(fd >= 0);
SAFE_ASSERT(count <= static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
char *buf0 = reinterpret_cast<char *>(buf);
SAFE_ASSERT(count <=
static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
char* buf0 = reinterpret_cast<char*>(buf);
size_t num_bytes = 0;
while (num_bytes < count) {
ssize_t len;
@ -170,8 +172,8 @@ static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count,
// pointed by "fd" into the buffer starting at "buf" while handling
// short reads and EINTR. On success, return true. Otherwise, return
// false.
static bool ReadFromOffsetExact(const int fd, void *buf,
const size_t count, const size_t offset) {
static bool ReadFromOffsetExact(const int fd, void* buf, const size_t count,
const size_t offset) {
ssize_t len = ReadFromOffset(fd, buf, count, offset);
return static_cast<size_t>(len) == count;
}
@ -193,9 +195,11 @@ static int FileGetElfType(const int fd) {
// and return true. Otherwise, return false.
// To keep stack consumption low, we would like this function to not get
// inlined.
static ATTRIBUTE_NOINLINE bool
GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const size_t sh_offset,
ElfW(Word) type, ElfW(Shdr) *out) {
static ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(const int fd,
ElfW(Half) sh_num,
const size_t sh_offset,
ElfW(Word) type,
ElfW(Shdr) * out) {
// Read at most 16 section headers at a time to save read calls.
ElfW(Shdr) buf[16];
for (size_t i = 0; i < sh_num;) {
@ -226,8 +230,8 @@ GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const size_t sh_offset,
const int kMaxSectionNameLen = 64;
// name_len should include terminating '\0'.
bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
ElfW(Shdr) *out) {
bool GetSectionHeaderByName(int fd, const char* name, size_t name_len,
ElfW(Shdr) * out) {
ElfW(Ehdr) elf_header;
if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
return false;
@ -242,8 +246,8 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
}
for (size_t i = 0; i < elf_header.e_shnum; ++i) {
size_t section_header_offset = (elf_header.e_shoff +
elf_header.e_shentsize * i);
size_t section_header_offset =
(elf_header.e_shoff + elf_header.e_shentsize * i);
if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
return false;
}
@ -277,10 +281,11 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
// to out. Otherwise, return false.
// To keep stack consumption low, we would like this function to not get
// inlined.
static ATTRIBUTE_NOINLINE bool
FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
uint64_t symbol_offset, const ElfW(Shdr) *strtab,
const ElfW(Shdr) *symtab) {
static ATTRIBUTE_NOINLINE bool FindSymbol(uint64_t pc, const int fd, char* out,
size_t out_size,
uint64_t symbol_offset,
const ElfW(Shdr) * strtab,
const ElfW(Shdr) * symtab) {
if (symtab == nullptr) {
return false;
}
@ -291,11 +296,11 @@ FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
// If we are reading Elf64_Sym's, we want to limit this array to
// 32 elements (to keep stack consumption low), otherwise we can
// have a 64 element Elf32_Sym array.
#if defined(__WORDSIZE) && __WORDSIZE == 64
# if defined(__WORDSIZE) && __WORDSIZE == 64
const size_t NUM_SYMBOLS = 32U;
#else
# else
const size_t NUM_SYMBOLS = 64U;
#endif
# endif
// Read at most NUM_SYMBOLS symbols at once to save read() calls.
ElfW(Sym) buf[NUM_SYMBOLS];
@ -331,11 +336,8 @@ FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
// both regular and dynamic symbol tables if necessary. On success,
// write the symbol name to "out" and return true. Otherwise, return
// false.
static bool GetSymbolFromObjectFile(const int fd,
uint64_t pc,
char* out,
size_t out_size,
uint64_t base_address) {
static bool GetSymbolFromObjectFile(const int fd, uint64_t pc, char* out,
size_t out_size, uint64_t base_address) {
// Read the ELF header.
ElfW(Ehdr) elf_header;
if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
@ -347,8 +349,9 @@ static bool GetSymbolFromObjectFile(const int fd,
// Consult a regular symbol table first.
if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
SHT_SYMTAB, &symtab)) {
if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
symtab.sh_link * sizeof(symtab))) {
if (!ReadFromOffsetExact(
fd, &strtab, sizeof(strtab),
elf_header.e_shoff + symtab.sh_link * sizeof(symtab))) {
return false;
}
if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
@ -359,8 +362,9 @@ static bool GetSymbolFromObjectFile(const int fd,
// If the symbol is not found, then consult a dynamic symbol table.
if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
SHT_DYNSYM, &symtab)) {
if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
symtab.sh_link * sizeof(symtab))) {
if (!ReadFromOffsetExact(
fd, &strtab, sizeof(strtab),
elf_header.e_shoff + symtab.sh_link * sizeof(symtab))) {
return false;
}
if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
@ -385,8 +389,8 @@ struct FileDescriptor {
int get() { return fd_; }
private:
FileDescriptor(const FileDescriptor &) = delete;
void operator=(const FileDescriptor &) = delete;
FileDescriptor(const FileDescriptor&) = delete;
void operator=(const FileDescriptor&) = delete;
};
// Helper class for reading lines from file.
@ -396,7 +400,7 @@ struct FileDescriptor {
// and std::snprintf().
class LineReader {
public:
explicit LineReader(int fd, char *buf, size_t buf_len, size_t offset)
explicit LineReader(int fd, char* buf, size_t buf_len, size_t offset)
: fd_(fd),
buf_(buf),
buf_len_(buf_len),
@ -410,7 +414,7 @@ class LineReader {
//
// Note: if the last line doesn't end with '\n', the line will be
// dropped. It's an intentional behavior to make the code simple.
bool ReadLine(const char **bol, const char **eol) {
bool ReadLine(const char** bol, const char** eol) {
if (BufferIsEmpty()) { // First time.
const ssize_t num_bytes = ReadFromOffset(fd_, buf_, buf_len_, offset_);
if (num_bytes <= 0) { // EOF or error.
@ -420,14 +424,14 @@ class LineReader {
eod_ = buf_ + num_bytes;
bol_ = buf_;
} else {
bol_ = eol_ + 1; // Advance to the next line in the buffer.
bol_ = eol_ + 1; // Advance to the next line in the buffer.
SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
if (!HasCompleteLine()) {
const auto incomplete_line_length = static_cast<size_t>(eod_ - bol_);
// Move the trailing incomplete line to the beginning.
memmove(buf_, bol_, incomplete_line_length);
// Read text from file and append it.
char * const append_pos = buf_ + incomplete_line_length;
char* const append_pos = buf_ + incomplete_line_length;
const size_t capacity_left = buf_len_ - incomplete_line_length;
const ssize_t num_bytes =
ReadFromOffset(fd_, append_pos, capacity_left, offset_);
@ -451,57 +455,53 @@ class LineReader {
}
// Beginning of line.
const char *bol() {
return bol_;
}
const char* bol() { return bol_; }
// End of line.
const char *eol() {
return eol_;
}
const char* eol() { return eol_; }
private:
LineReader(const LineReader &) = delete;
void operator=(const LineReader &) = delete;
LineReader(const LineReader&) = delete;
void operator=(const LineReader&) = delete;
char *FindLineFeed() {
return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
char* FindLineFeed() {
return reinterpret_cast<char*>(
memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
}
bool BufferIsEmpty() {
return buf_ == eod_;
}
bool BufferIsEmpty() { return buf_ == eod_; }
bool HasCompleteLine() {
return !BufferIsEmpty() && FindLineFeed() != nullptr;
}
const int fd_;
char * const buf_;
char* const buf_;
const size_t buf_len_;
size_t offset_;
char *bol_;
char *eol_;
const char *eod_; // End of data in "buf_".
char* bol_;
char* eol_;
const char* eod_; // End of data in "buf_".
};
} // namespace
// Place the hex number read from "start" into "*hex". The pointer to
// the first non-hex character or "end" is returned.
static char *GetHex(const char *start, const char *end, uint64_t *hex) {
static char* GetHex(const char* start, const char* end, uint64_t* hex) {
*hex = 0;
const char *p;
const char* p;
for (p = start; p < end; ++p) {
int ch = *p;
if ((ch >= '0' && ch <= '9') ||
(ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
*hex = (*hex << 4U) | (ch < 'A' ? static_cast<uint64_t>(ch - '0') : (ch & 0xF) + 9U);
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f')) {
*hex = (*hex << 4U) |
(ch < 'A' ? static_cast<uint64_t>(ch - '0') : (ch & 0xF) + 9U);
} else { // Encountered the first non-hex character.
break;
}
}
SAFE_ASSERT(p <= end);
return const_cast<char *>(p);
return const_cast<char*>(p);
}
// Searches for the object file (from /proc/self/maps) that contains
@ -512,12 +512,9 @@ static char *GetHex(const char *start, const char *end, uint64_t *hex) {
// file is opened successfully, returns the file descriptor. Otherwise,
// returns -1. |out_file_name_size| is the size of the file name buffer
// (including the null-terminator).
static ATTRIBUTE_NOINLINE int
OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
uint64_t &start_address,
uint64_t &base_address,
char *out_file_name,
size_t out_file_name_size) {
static ATTRIBUTE_NOINLINE int OpenObjectFileContainingPcAndGetStartAddress(
uint64_t pc, uint64_t& start_address, uint64_t& base_address,
char* out_file_name, size_t out_file_name_size) {
int object_fd;
int maps_fd;
@ -539,8 +536,8 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
char buf[1024]; // Big enough for line of sane /proc/self/maps
LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0);
while (true) {
const char *cursor;
const char *eol;
const char* cursor;
const char* eol;
if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line.
return -1;
}
@ -568,7 +565,7 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
++cursor; // Skip ' '.
// Read flags. Skip flags until we encounter a space or eol.
const char * const flags_start = cursor;
const char* const flags_start = cursor;
while (cursor < eol && *cursor != ' ') {
++cursor;
}
@ -620,7 +617,7 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
continue; // We skip this map. PC isn't in this map.
}
// Check flags. We are only interested in "r*x" maps.
// Check flags. We are only interested in "r*x" maps.
if (flags_start[0] != 'r' || flags_start[2] != 'x') {
continue; // We skip this map.
}
@ -672,7 +669,8 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
// "sz" bytes. Output will be truncated as needed, and a NUL character is always
// appended.
// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) {
static char* itoa_r(uintptr_t i, char* buf, size_t sz, unsigned base,
size_t padding) {
// Make sure we can write at least one NUL byte.
size_t n = 1;
if (n > sz) {
@ -684,11 +682,11 @@ static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t pad
return nullptr;
}
char *start = buf;
char* start = buf;
// Loop until we have converted the entire number. Output at least one
// character (i.e. '0').
char *ptr = start;
char* ptr = start;
do {
// Make sure there is still enough space left in our output buffer.
if (++n > sz) {
@ -749,7 +747,7 @@ static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) {
// and "out" is used as its output.
// To keep stack consumption low, we would like this function to not
// get inlined.
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
size_t out_size) {
auto pc0 = reinterpret_cast<uintptr_t>(pc);
uint64_t start_address = 0;
@ -763,24 +761,21 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
SafeAppendString("(", out, out_size);
if (g_symbolize_open_object_file_callback) {
object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
base_address, out + 1,
out_size - 1);
object_fd = g_symbolize_open_object_file_callback(
pc0, start_address, base_address, out + 1, out_size - 1);
} else {
object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
base_address,
out + 1,
out_size - 1);
object_fd = OpenObjectFileContainingPcAndGetStartAddress(
pc0, start_address, base_address, out + 1, out_size - 1);
}
FileDescriptor wrapped_object_fd(object_fd);
#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
# if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
{
#else
# else
// Check whether a file name was returned.
if (object_fd < 0) {
#endif
# endif
if (out[1]) {
// The object file containing PC was determined successfully however the
// object file was not opened successfully. This is still considered
@ -804,16 +799,15 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
// Note: relocation (and much of the rest of this code) will be
// wrong for prelinked shared libraries and PIE executables.
uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0;
int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
pc, out, out_size,
relocation);
int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(), pc,
out, out_size, relocation);
if (num_bytes_written > 0) {
out += static_cast<size_t>(num_bytes_written);
out_size -= static_cast<size_t>(num_bytes_written);
}
}
if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
out, out_size, base_address)) {
if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, out, out_size,
base_address)) {
if (out[1] && !g_symbolize_callback) {
// The object file containing PC was opened successfully however the
// symbol was not found. The object may have been stripped. This is still
@ -835,14 +829,15 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
} // namespace google
#elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
# elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
#include <dlfcn.h>
#include <cstring>
# include <dlfcn.h>
# include <cstring>
namespace google {
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
size_t out_size) {
Dl_info info;
if (dladdr(pc, &info)) {
@ -860,19 +855,19 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
} // namespace google
#elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
#include <windows.h>
#include <dbghelp.h>
# include <dbghelp.h>
# include <windows.h>
#ifdef _MSC_VER
#pragma comment(lib, "dbghelp")
#endif
# ifdef _MSC_VER
# pragma comment(lib, "dbghelp")
# endif
namespace google {
class SymInitializer {
public:
public:
HANDLE process;
bool ready;
SymInitializer() : process(nullptr), ready(false) {
@ -891,12 +886,13 @@ public:
SymCleanup(process);
// We do not need to close `HANDLE process` because it's a "pseudo handle."
}
private:
private:
SymInitializer(const SymInitializer&);
SymInitializer& operator=(const SymInitializer&);
};
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void* pc, char* out,
size_t out_size) {
const static SymInitializer symInitializer;
if (!symInitializer.ready) {
@ -905,13 +901,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
// Resolve symbol information from address.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx
char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf);
SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(buf);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
// We use the ANSI version to ensure the string type is always `char *`.
// This could break if a symbol has Unicode in it.
BOOL ret = SymFromAddr(symInitializer.process,
reinterpret_cast<DWORD64>(pc), 0, symbol);
BOOL ret = SymFromAddr(symInitializer.process, reinterpret_cast<DWORD64>(pc),
0, symbol);
if (ret == 1 && static_cast<ssize_t>(symbol->NameLen) < out_size) {
// `NameLen` does not include the null terminating character.
strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
@ -925,23 +921,23 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
} // namespace google
#else
# error BUG: HAVE_SYMBOLIZE was wrongly set
#endif
# else
# error BUG: HAVE_SYMBOLIZE was wrongly set
# endif
namespace google {
bool Symbolize(void *pc, char *out, size_t out_size) {
bool Symbolize(void* pc, char* out, size_t out_size) {
return SymbolizeAndDemangle(pc, out, out_size);
}
} // namespace google
#else /* HAVE_SYMBOLIZE */
#else /* HAVE_SYMBOLIZE */
#include <cassert>
# include <cassert>
#include "config.h"
# include "config.h"
namespace google {

View File

@ -60,48 +60,48 @@
#ifdef HAVE_SYMBOLIZE
#if defined(__ELF__) // defined by gcc
#if defined(__OpenBSD__)
#include <sys/exec_elf.h>
#else
#include <elf.h>
#endif
# if defined(__ELF__) // defined by gcc
# if defined(__OpenBSD__)
# include <sys/exec_elf.h>
# else
# include <elf.h>
# endif
#if !defined(ANDROID)
#include <link.h> // For ElfW() macro.
#endif
# if !defined(ANDROID)
# include <link.h> // For ElfW() macro.
# endif
// For systems where SIZEOF_VOID_P is not defined, determine it
// based on __LP64__ (defined by gcc on 64-bit systems)
#if !defined(SIZEOF_VOID_P)
# if defined(__LP64__)
# define SIZEOF_VOID_P 8
# else
# define SIZEOF_VOID_P 4
# endif
#endif
# if !defined(SIZEOF_VOID_P)
# if defined(__LP64__)
# define SIZEOF_VOID_P 8
# else
# define SIZEOF_VOID_P 4
# endif
# endif
// If there is no ElfW macro, let's define it by ourself.
#ifndef ElfW
# if SIZEOF_VOID_P == 4
# define ElfW(type) Elf32_##type
# elif SIZEOF_VOID_P == 8
# define ElfW(type) Elf64_##type
# else
# error "Unknown sizeof(void *)"
# endif
#endif
# ifndef ElfW
# if SIZEOF_VOID_P == 4
# define ElfW(type) Elf32_##type
# elif SIZEOF_VOID_P == 8
# define ElfW(type) Elf64_##type
# else
# error "Unknown sizeof(void *)"
# endif
# endif
namespace google {
// Gets the section header for the given name, if it exists. Returns true on
// success. Otherwise, returns false.
bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
ElfW(Shdr) *out);
bool GetSectionHeaderByName(int fd, const char* name, size_t name_len,
ElfW(Shdr) * out);
} // namespace google
#endif /* __ELF__ */
# endif /* __ELF__ */
namespace google {
@ -116,7 +116,7 @@ namespace google {
// counter "pc". The callback function should write output to "out"
// and return the size of the output written. On error, the callback
// function should return -1.
using SymbolizeCallback = int (*)(int, void *, char *, size_t, uint64_t);
using SymbolizeCallback = int (*)(int, void*, char*, size_t, uint64_t);
GLOG_EXPORT
void InstallSymbolizeCallback(SymbolizeCallback callback);
@ -130,8 +130,8 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
// file is opened successfully, returns the file descriptor. Otherwise,
// returns -1. |out_file_name_size| is the size of the file name buffer
// (including the null-terminator).
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t &,
uint64_t &, char *, size_t);
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&,
char*, size_t);
void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback);

View File

@ -42,7 +42,7 @@
#include "utilities.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
@ -52,17 +52,17 @@ using namespace google;
// Avoid compile error due to "cast between pointer-to-function and
// pointer-to-object is an extension" warnings.
#if defined(__GNUG__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
#endif
#if defined(HAVE_STACKTRACE)
#define always_inline
# define always_inline
#if defined(__ELF__) || defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
# if defined(__ELF__) || defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
// A wrapper function for Symbolize() to make the unit test simple.
static const char *TrySymbolize(void *pc) {
static const char* TrySymbolize(void* pc) {
static char symbol[4096];
if (Symbolize(pc, symbol, sizeof(symbol))) {
return symbol;
@ -70,24 +70,25 @@ static const char *TrySymbolize(void *pc) {
return nullptr;
}
}
#endif
# endif
# if defined(__ELF__)
# if defined(__ELF__)
// This unit tests make sense only with GCC.
// Uses lots of GCC specific features.
#if defined(__GNUC__) && !defined(__OPENCC__)
# if __GNUC__ >= 4
# define TEST_WITH_MODERN_GCC
# if defined(__i386__) && __i386__ // always_inline isn't supported for x86_64 with GCC 4.1.0.
# undef always_inline
# define always_inline __attribute__((always_inline))
# define HAVE_ALWAYS_INLINE
# endif // __i386__
# else
# endif // __GNUC__ >= 4
# define TEST_WITH_LABEL_ADDRESSES
#endif
# if defined(__GNUC__) && !defined(__OPENCC__)
# if __GNUC__ >= 4
# define TEST_WITH_MODERN_GCC
# if defined(__i386__) && __i386__ // always_inline isn't supported for
// x86_64 with GCC 4.1.0.
# undef always_inline
# define always_inline __attribute__((always_inline))
# define HAVE_ALWAYS_INLINE
# endif // __i386__
# else
# endif // __GNUC__ >= 4
# define TEST_WITH_LABEL_ADDRESSES
# endif
// Make them C linkage to avoid mangled names.
extern "C" {
@ -112,18 +113,18 @@ TEST(Symbolize, Symbolize) {
// reinterpret_cast<void *>(&func).
// Compilers should give us pointers to them.
EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
EXPECT_STREQ("nonstatic_func", TrySymbolize((void*)(&nonstatic_func)));
// The name of an internal linkage symbol is not specified; allow either a
// mangled or an unmangled name here.
const char *static_func_symbol =
TrySymbolize(reinterpret_cast<void *>(&static_func));
const char* static_func_symbol =
TrySymbolize(reinterpret_cast<void*>(&static_func));
#if !defined(_MSC_VER) || !defined(NDEBUG)
# if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(nullptr != static_func_symbol);
EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
strcmp("static_func()", static_func_symbol) == 0);
#endif
# endif
EXPECT_TRUE(nullptr == TrySymbolize(nullptr));
}
@ -141,14 +142,14 @@ void ATTRIBUTE_NOINLINE Foo::func(int x) {
// With a modern GCC, Symbolize() should return demangled symbol
// names. Function parameters should be omitted.
#ifdef TEST_WITH_MODERN_GCC
# ifdef TEST_WITH_MODERN_GCC
TEST(Symbolize, SymbolizeWithDemangling) {
Foo::func(100);
#if !defined(_MSC_VER) || !defined(NDEBUG)
EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func)));
#endif
# if !defined(_MSC_VER) || !defined(NDEBUG)
EXPECT_STREQ("Foo::func()", TrySymbolize((void*)(&Foo::func)));
# endif
}
#endif
# endif
// Tests that verify that Symbolize footprint is within some limit.
@ -167,9 +168,9 @@ TEST(Symbolize, SymbolizeWithDemangling) {
// calls Symbolize. The difference between the stack consumption of these
// two signals handlers should give us the Symbolize stack foorprint.
static void *g_pc_to_symbolize;
static void* g_pc_to_symbolize;
static char g_symbolize_buffer[4096];
static char *g_symbolize_result;
static char* g_symbolize_result;
static void EmptySignalHandler(int /*signo*/) {}
@ -188,7 +189,7 @@ const char kAlternateStackFillValue = 0x55;
// These helper functions look at the alternate stack buffer, and figure
// out what portion of this buffer has been touched - this is the stack
// consumption of the signal handler running on this alternate stack.
static ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) {
static ATTRIBUTE_NOINLINE bool StackGrowsDown(int* x) {
int y;
return &y < x;
}
@ -210,11 +211,10 @@ static int GetStackConsumption(const char* alt_stack) {
return -1;
}
#ifdef HAVE_SIGALTSTACK
# ifdef HAVE_SIGALTSTACK
// Call Symbolize and figure out the stack footprint of this call.
static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
static const char* SymbolizeStackConsumption(void* pc, int* stack_consumed) {
g_pc_to_symbolize = pc;
// The alt-signal-stack cannot be heap allocated because there is a
@ -282,19 +282,19 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
return g_symbolize_result;
}
#ifdef __ppc64__
# ifdef __ppc64__
// Symbolize stack consumption should be within 4kB.
const int kStackConsumptionUpperLimit = 4096;
#else
# else
// Symbolize stack consumption should be within 2kB.
const int kStackConsumptionUpperLimit = 2048;
#endif
# endif
TEST(Symbolize, SymbolizeStackConsumption) {
int stack_consumed;
const char* symbol;
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&nonstatic_func),
symbol = SymbolizeStackConsumption(reinterpret_cast<void*>(&nonstatic_func),
&stack_consumed);
EXPECT_STREQ("nonstatic_func", symbol);
EXPECT_GT(stack_consumed, 0);
@ -302,7 +302,7 @@ TEST(Symbolize, SymbolizeStackConsumption) {
// The name of an internal linkage symbol is not specified; allow either a
// mangled or an unmangled name here.
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func),
symbol = SymbolizeStackConsumption(reinterpret_cast<void*>(&static_func),
&stack_consumed);
CHECK(nullptr != symbol);
EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
@ -311,91 +311,91 @@ TEST(Symbolize, SymbolizeStackConsumption) {
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
}
#ifdef TEST_WITH_MODERN_GCC
# ifdef TEST_WITH_MODERN_GCC
TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
Foo::func(100);
int stack_consumed;
const char* symbol;
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&Foo::func),
symbol = SymbolizeStackConsumption(reinterpret_cast<void*>(&Foo::func),
&stack_consumed);
EXPECT_STREQ("Foo::func()", symbol);
EXPECT_GT(stack_consumed, 0);
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
}
#endif
# endif
#endif // HAVE_SIGALTSTACK
# endif // HAVE_SIGALTSTACK
// x86 specific tests. Uses some inline assembler.
extern "C" {
inline void* always_inline inline_func() {
void *pc = nullptr;
#ifdef TEST_WITH_LABEL_ADDRESSES
void* pc = nullptr;
# ifdef TEST_WITH_LABEL_ADDRESSES
pc = &&curr_pc;
curr_pc:
#endif
curr_pc:
# endif
return pc;
}
void* ATTRIBUTE_NOINLINE non_inline_func();
void* ATTRIBUTE_NOINLINE non_inline_func() {
void *pc = nullptr;
#ifdef TEST_WITH_LABEL_ADDRESSES
void* pc = nullptr;
# ifdef TEST_WITH_LABEL_ADDRESSES
pc = &&curr_pc;
curr_pc:
#endif
curr_pc:
# endif
return pc;
}
static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
#if defined(TEST_WITH_LABEL_ADDRESSES) && defined(HAVE_ATTRIBUTE_NOINLINE)
void *pc = non_inline_func();
const char *symbol = TrySymbolize(pc);
# if defined(TEST_WITH_LABEL_ADDRESSES) && defined(HAVE_ATTRIBUTE_NOINLINE)
void* pc = non_inline_func();
const char* symbol = TrySymbolize(pc);
#if !defined(_MSC_VER) || !defined(NDEBUG)
# if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "non_inline_func");
#endif
# endif
cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
#endif
# endif
}
static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
#if defined(TEST_WITH_LABEL_ADDRESSES) && defined(HAVE_ALWAYS_INLINE)
void *pc = inline_func(); // Must be inlined.
const char *symbol = TrySymbolize(pc);
# if defined(TEST_WITH_LABEL_ADDRESSES) && defined(HAVE_ALWAYS_INLINE)
void* pc = inline_func(); // Must be inlined.
const char* symbol = TrySymbolize(pc);
#if !defined(_MSC_VER) || !defined(NDEBUG)
# if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != nullptr);
CHECK_STREQ(symbol, __FUNCTION__);
#endif
# endif
cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
#endif
# endif
}
}
// Test with a return address.
static void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
#if defined(HAVE_ATTRIBUTE_NOINLINE)
void *return_address = __builtin_return_address(0);
const char *symbol = TrySymbolize(return_address);
# if defined(HAVE_ATTRIBUTE_NOINLINE)
void* return_address = __builtin_return_address(0);
const char* symbol = TrySymbolize(return_address);
#if !defined(_MSC_VER) || !defined(NDEBUG)
# if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "main");
#endif
# endif
cout << "Test case TestWithReturnAddress passed." << endl;
#endif
# endif
}
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
#ifdef _MSC_VER
#include <intrin.h>
#pragma intrinsic(_ReturnAddress)
#endif
# ifdef _MSC_VER
# include <intrin.h>
# pragma intrinsic(_ReturnAddress)
# endif
struct Foo {
static void func(int x);
@ -410,37 +410,37 @@ __declspec(noinline) void Foo::func(int x) {
TEST(Symbolize, SymbolizeWithDemangling) {
Foo::func(100);
const char* ret = TrySymbolize((void *)(&Foo::func));
const char* ret = TrySymbolize((void*)(&Foo::func));
#if defined(HAVE_DBGHELP) && !defined(NDEBUG)
# if defined(HAVE_DBGHELP) && !defined(NDEBUG)
EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret);
#endif
# endif
}
__declspec(noinline) void TestWithReturnAddress() {
void *return_address =
#ifdef __GNUC__ // Cygwin and MinGW support
__builtin_return_address(0)
#else
_ReturnAddress()
#endif
;
const char *symbol = TrySymbolize(return_address);
#if !defined(_MSC_VER) || !defined(NDEBUG)
void* return_address =
# ifdef __GNUC__ // Cygwin and MinGW support
__builtin_return_address(0)
# else
_ReturnAddress()
# endif
;
const char* symbol = TrySymbolize(return_address);
# if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "main");
#endif
# endif
cout << "Test case TestWithReturnAddress passed." << endl;
}
# endif // __ELF__
#endif // HAVE_STACKTRACE
# endif // __ELF__
#endif // HAVE_STACKTRACE
int main(int argc, char **argv) {
int main(int argc, char** argv) {
FLAGS_logtostderr = true;
InitGoogleLogging(argv[0]);
InitGoogleTest(&argc, argv);
#if defined(HAVE_SYMBOLIZE) && defined(HAVE_STACKTRACE)
# if defined(__ELF__)
# if defined(__ELF__)
// We don't want to get affected by the callback interface, that may be
// used to install some callback function at InitGoogle() time.
InstallSymbolizeCallback(nullptr);
@ -449,13 +449,13 @@ int main(int argc, char **argv) {
TestWithPCInsideNonInlineFunction();
TestWithReturnAddress();
return RUN_ALL_TESTS();
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
# elif defined(GLOG_OS_WINDOWS) || defined(GLOG_OS_CYGWIN)
TestWithReturnAddress();
return RUN_ALL_TESTS();
# else // GLOG_OS_WINDOWS
# else // GLOG_OS_WINDOWS
printf("PASS (no symbolize_unittest support)\n");
return 0;
# endif // __ELF__
# endif // __ELF__
#else
printf("PASS (no symbolize support)\n");
return 0;
@ -463,5 +463,5 @@ int main(int argc, char **argv) {
}
#if defined(__GNUG__)
#pragma GCC diagnostic pop
# pragma GCC diagnostic pop
#endif

View File

@ -29,33 +29,33 @@
//
// Author: Shinichiro Hamaji
#include "config.h"
#include "utilities.h"
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <csignal>
#include "config.h"
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# include <sys/time.h>
#endif
#include <ctime>
#if defined(HAVE_SYSCALL_H)
#include <syscall.h> // for syscall()
# include <syscall.h> // for syscall()
#elif defined(HAVE_SYS_SYSCALL_H)
#include <sys/syscall.h> // for syscall()
# include <sys/syscall.h> // for syscall()
#endif
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
# include <syslog.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h> // For geteuid.
# include <unistd.h> // For geteuid.
#endif
#ifdef HAVE_PWD_H
# include <pwd.h>
# include <pwd.h>
#endif
#ifdef __ANDROID__
#include <android/log.h>
# include <android/log.h>
#endif
#include "base/googleinit.h"
@ -75,9 +75,9 @@ bool IsGoogleLoggingInitialized() {
// The following APIs are all internal.
#ifdef HAVE_STACKTRACE
#include "stacktrace.h"
#include "symbolize.h"
#include "base/commandlineflags.h"
# include "base/commandlineflags.h"
# include "stacktrace.h"
# include "symbolize.h"
GLOG_DEFINE_bool(symbolize_stacktrace, true,
"Symbolize the stack trace in the tombstone");
@ -90,44 +90,44 @@ using DebugWriter = void(const char*, void*);
// For some environments, add two extra bytes for the leading "0x".
static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
static void DebugWriteToStderr(const char* data, void *) {
static void DebugWriteToStderr(const char* data, void*) {
// This one is signal-safe.
if (write(STDERR_FILENO, data, strlen(data)) < 0) {
// Ignore errors.
}
#if defined(__ANDROID__)
# if defined(__ANDROID__)
// ANDROID_LOG_FATAL as fatal error occurred and now is dumping call stack.
__android_log_write(ANDROID_LOG_FATAL,
glog_internal_namespace_::ProgramInvocationShortName(),
data);
#endif
# endif
}
static void DebugWriteToString(const char* data, void *arg) {
static void DebugWriteToString(const char* data, void* arg) {
reinterpret_cast<string*>(arg)->append(data);
}
#ifdef HAVE_SYMBOLIZE
# ifdef HAVE_SYMBOLIZE
// Print a program counter and its symbol name.
static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc,
const char * const prefix) {
static void DumpPCAndSymbol(DebugWriter* writerfn, void* arg, void* pc,
const char* const prefix) {
char tmp[1024];
const char *symbol = "(unknown)";
const char* symbol = "(unknown)";
// Symbolizes the previous address of pc because pc may be in the
// next function. The overrun happens when the function ends with
// a call to a function annotated noreturn (e.g. CHECK).
if (Symbolize(reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) {
symbol = tmp;
if (Symbolize(reinterpret_cast<char*>(pc) - 1, tmp, sizeof(tmp))) {
symbol = tmp;
}
char buf[1024];
std::snprintf(buf, sizeof(buf), "%s@ %*p %s\n", prefix,
kPrintfPointerFieldWidth, pc, symbol);
writerfn(buf, arg);
}
#endif
# endif
static void DumpPC(DebugWriter *writerfn, void *arg, void *pc,
const char * const prefix) {
static void DumpPC(DebugWriter* writerfn, void* arg, void* pc,
const char* const prefix) {
char buf[100];
std::snprintf(buf, sizeof(buf), "%s@ %*p\n", prefix, kPrintfPointerFieldWidth,
pc);
@ -135,26 +135,26 @@ static void DumpPC(DebugWriter *writerfn, void *arg, void *pc,
}
// Dump current stack trace as directed by writerfn
static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
static void DumpStackTrace(int skip_count, DebugWriter* writerfn, void* arg) {
// Print stack trace
void* stack[32];
int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1);
int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count + 1);
for (int i = 0; i < depth; i++) {
#if defined(HAVE_SYMBOLIZE)
# if defined(HAVE_SYMBOLIZE)
if (FLAGS_symbolize_stacktrace) {
DumpPCAndSymbol(writerfn, arg, stack[i], " ");
} else {
DumpPC(writerfn, arg, stack[i], " ");
}
#else
# else
DumpPC(writerfn, arg, stack[i], " ");
#endif
# endif
}
}
#ifdef __GNUC__
# ifdef __GNUC__
__attribute__((noreturn))
#endif
# endif
static void
DumpStackTraceAndExit() {
DumpStackTrace(1, DebugWriteToStderr, nullptr);
@ -163,15 +163,15 @@ DumpStackTraceAndExit() {
if (IsFailureSignalHandlerInstalled()) {
// Set the default signal handler for SIGABRT, to avoid invoking our
// own signal handler installed by InstallFailureSignalHandler().
#ifdef HAVE_SIGACTION
# ifdef HAVE_SIGACTION
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &sig_action, nullptr);
#elif defined(GLOG_OS_WINDOWS)
# elif defined(GLOG_OS_WINDOWS)
signal(SIGABRT, SIG_DFL);
#endif // HAVE_SIGACTION
# endif // HAVE_SIGACTION
}
abort();
@ -199,14 +199,15 @@ struct timeval {
long tv_sec, tv_usec;
};
// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
// Based on:
// http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
// See COPYING for copyright information.
static int gettimeofday(struct timeval *tv, void* /*tz*/) {
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlong-long"
#endif
#define EPOCHFILETIME (116444736000000000ULL)
static int gettimeofday(struct timeval* tv, void* /*tz*/) {
# ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
# define EPOCHFILETIME (116444736000000000ULL)
FILETIME ft;
ULARGE_INTEGER li;
uint64 tt;
@ -217,9 +218,9 @@ static int gettimeofday(struct timeval *tv, void* /*tz*/) {
tt = (li.QuadPart - EPOCHFILETIME) / 10;
tv->tv_sec = tt / 1000000;
tv->tv_usec = tt % 1000000;
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
# ifdef __GNUC__
# pragma GCC diagnostic pop
# endif
return 0;
}
@ -232,9 +233,7 @@ int64 CycleClock_Now() {
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
}
int64 UsecToCycles(int64 usec) {
return usec;
}
int64 UsecToCycles(int64 usec) { return usec; }
WallTime WallTime_Now() {
// Now, cycle clock is retuning microseconds since the epoch.
@ -242,9 +241,7 @@ WallTime WallTime_Now() {
}
static int32 g_main_thread_pid = getpid();
int32 GetMainThreadPid() {
return g_main_thread_pid;
}
int32 GetMainThreadPid() { return g_main_thread_pid; }
bool PidHasChanged() {
int32 pid = getpid();
@ -258,24 +255,24 @@ bool PidHasChanged() {
pid_t GetTID() {
// On Linux and MacOSX, we try to use gettid().
#if defined GLOG_OS_LINUX || defined GLOG_OS_MACOSX
#ifndef __NR_gettid
#ifdef GLOG_OS_MACOSX
#define __NR_gettid SYS_gettid
#elif ! defined __i386__
#error "Must define __NR_gettid for non-x86 platforms"
#else
#define __NR_gettid 224
#endif
#endif
# ifndef __NR_gettid
# ifdef GLOG_OS_MACOSX
# define __NR_gettid SYS_gettid
# elif !defined __i386__
# error "Must define __NR_gettid for non-x86 platforms"
# else
# define __NR_gettid 224
# endif
# endif
static bool lacks_gettid = false;
if (!lacks_gettid) {
#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
# if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
uint64_t tid64;
const int error = pthread_threadid_np(nullptr, &tid64);
pid_t tid = error ? -1 : static_cast<pid_t>(tid64);
#else
# else
auto tid = static_cast<pid_t>(syscall(__NR_gettid));
#endif
# endif
if (tid != -1) {
return tid;
}
@ -305,16 +302,13 @@ pid_t GetTID() {
const char* const_basename(const char* filepath) {
const char* base = strrchr(filepath, '/');
#ifdef GLOG_OS_WINDOWS // Look for either path separator in Windows
if (!base)
base = strrchr(filepath, '\\');
if (!base) base = strrchr(filepath, '\\');
#endif
return base ? (base+1) : filepath;
return base ? (base + 1) : filepath;
}
static string g_my_user_name;
const string& MyUserName() {
return g_my_user_name;
}
const string& MyUserName() { return g_my_user_name; }
static void MyUserNameInitializer() {
// TODO(hamaji): Probably this is not portable.
#if defined(GLOG_OS_WINDOWS)
@ -356,8 +350,7 @@ void DumpStackTraceToString(string* stacktrace) {
static const CrashReason* g_reason = nullptr;
void SetCrashReason(const CrashReason* r) {
sync_val_compare_and_swap(&g_reason,
reinterpret_cast<const CrashReason*>(0),
sync_val_compare_and_swap(&g_reason, reinterpret_cast<const CrashReason*>(0),
r);
}
@ -366,7 +359,7 @@ void InitGoogleLoggingUtilities(const char* argv0) {
<< "You called InitGoogleLogging() twice!";
const char* slash = strrchr(argv0, '/');
#ifdef GLOG_OS_WINDOWS
if (!slash) slash = strrchr(argv0, '\\');
if (!slash) slash = strrchr(argv0, '\\');
#endif
g_program_invocation_short_name = slash ? slash + 1 : argv0;
@ -377,7 +370,8 @@ void InitGoogleLoggingUtilities(const char* argv0) {
void ShutdownGoogleLoggingUtilities() {
CHECK(IsGoogleLoggingInitialized())
<< "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
<< "You called ShutdownGoogleLogging() without calling "
"InitGoogleLogging() first!";
g_program_invocation_short_name = nullptr;
#ifdef HAVE_SYSLOG_H
closelog();
@ -390,13 +384,13 @@ void ShutdownGoogleLoggingUtilities() {
// Make an implementation of stacktrace compiled.
#ifdef STACKTRACE_H
# include STACKTRACE_H
# if 0
# include STACKTRACE_H
# if 0
// For include scanners which can't handle macro expansions.
# include "stacktrace_libunwind-inl.h"
# include "stacktrace_x86-inl.h"
# include "stacktrace_x86_64-inl.h"
# include "stacktrace_powerpc-inl.h"
# include "stacktrace_generic-inl.h"
# endif
# 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

View File

@ -36,9 +36,9 @@
// printf macros for size_t, in the style of inttypes.h
#ifdef _LP64
#define __PRIS_PREFIX "z"
# define __PRIS_PREFIX "z"
#else
#define __PRIS_PREFIX
# define __PRIS_PREFIX
#endif
// Use these macros after a % in a printf format string
@ -58,22 +58,22 @@
#include "glog/logging.h"
#if defined(GLOG_OS_WINDOWS)
# include "port.h"
# include "port.h"
#endif
#include "config.h"
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
# include <unistd.h>
#endif
#if !defined(HAVE_SSIZE_T)
#if defined(GLOG_OS_WINDOWS)
#include <basetsd.h>
# if defined(GLOG_OS_WINDOWS)
# include <basetsd.h>
using ssize_t = SSIZE_T;
#else
# else
using ssize_t = std::ptrdiff_t;
#endif
# endif
#endif
// There are three different ways we can try to get the stack trace:
@ -99,45 +99,45 @@ using ssize_t = std::ptrdiff_t;
// Some code may do that.
#if defined(HAVE_LIBUNWIND)
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
#elif defined(HAVE_UNWIND)
# define STACKTRACE_H "stacktrace_unwind-inl.h"
# 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
# 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"
# define STACKTRACE_H "stacktrace_generic-inl.h"
#endif
#if defined(STACKTRACE_H)
# define HAVE_STACKTRACE
# define HAVE_STACKTRACE
#endif
#ifndef GLOG_NO_SYMBOLIZE_DETECTION
#ifndef HAVE_SYMBOLIZE
# ifndef HAVE_SYMBOLIZE
// defined by gcc
#if defined(__ELF__) && defined(GLOG_OS_LINUX)
# define HAVE_SYMBOLIZE
#elif defined(GLOG_OS_MACOSX) && defined(HAVE_DLADDR)
# 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)
# 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)
# 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)))
# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
#endif
namespace google {
@ -145,21 +145,21 @@ namespace google {
namespace glog_internal_namespace_ {
#if defined(__has_attribute)
#if __has_attribute(noinline)
# define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
# define HAVE_ATTRIBUTE_NOINLINE
#endif
# if __has_attribute(noinline)
# define ATTRIBUTE_NOINLINE __attribute__((noinline))
# define HAVE_ATTRIBUTE_NOINLINE
# endif
#endif
#if !defined(HAVE_ATTRIBUTE_NOINLINE)
#if defined(GLOG_OS_WINDOWS)
# define ATTRIBUTE_NOINLINE __declspec(noinline)
# define HAVE_ATTRIBUTE_NOINLINE
#endif
# if defined(GLOG_OS_WINDOWS)
# define ATTRIBUTE_NOINLINE __declspec(noinline)
# define HAVE_ATTRIBUTE_NOINLINE
# endif
#endif
#if !defined(HAVE_ATTRIBUTE_NOINLINE)
# define ATTRIBUTE_NOINLINE
# define ATTRIBUTE_NOINLINE
#endif
const char* ProgramInvocationShortName();
@ -184,20 +184,20 @@ const char* const_basename(const char* filepath);
// defined, we try the CPU specific logics (we only support x86 and
// x86_64 for now) first, then use a naive implementation, which has a
// race condition.
template<typename T>
template <typename T>
inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
return __sync_val_compare_and_swap(ptr, oldval, newval);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
T ret;
__asm__ __volatile__("lock; cmpxchg %1, (%2);"
:"=a"(ret)
// GCC may produces %sil or %dil for
// constraint "r", but some of apple's gas
// doesn't know the 8 bit registers.
// We use "q" to avoid these registers.
:"q"(newval), "q"(ptr), "a"(oldval)
:"memory", "cc");
: "=a"(ret)
// GCC may produces %sil or %dil for
// constraint "r", but some of apple's gas
// doesn't know the 8 bit registers.
// We use "q" to avoid these registers.
: "q"(newval), "q"(ptr), "a"(oldval)
: "memory", "cc");
return ret;
#else
T ret = *ptr;

View File

@ -34,7 +34,7 @@
#include "googletest.h"
#ifdef GLOG_USE_GFLAGS
#include <gflags/gflags.h>
# include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
#endif
@ -51,7 +51,7 @@ TEST(utilities, InitGoogleLoggingDeathTest) {
ASSERT_DEATH(InitGoogleLogging("foobar"), "");
}
int main(int argc, char **argv) {
int main(int argc, char** argv) {
InitGoogleLogging(argv[0]);
InitGoogleTest(&argc, argv);

View File

@ -49,14 +49,17 @@
using std::string;
GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this."
" Overridable by --vmodule.");
GLOG_DEFINE_int32(v, 0,
"Show all VLOG(m) messages for m <= this."
" Overridable by --vmodule.");
GLOG_DEFINE_string(vmodule, "", "per-module verbose level."
" Argument is a comma-separated list of <module name>=<log level>."
" <module name> is a glob pattern, matched against the filename base"
" (that is, name ignoring .cc/.h./-inl.h)."
" <log level> overrides any value given by --v.");
GLOG_DEFINE_string(
vmodule, "",
"per-module verbose level."
" Argument is a comma-separated list of <module name>=<log level>."
" <module name> is a glob pattern, matched against the filename base"
" (that is, name ignoring .cc/.h./-inl.h)."
" <log level> overrides any value given by --v.");
namespace google {
@ -75,18 +78,19 @@ GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len,
size_t p = 0;
size_t s = 0;
while (true) {
if (p == patt_len && s == str_len) return true;
if (p == patt_len && s == str_len) return true;
if (p == patt_len) return false;
if (s == str_len) return p+1 == patt_len && pattern[p] == '*';
if (pattern[p] == str[s] || pattern[p] == '?') {
if (s == str_len) return p + 1 == patt_len && pattern[p] == '*';
if (pattern[p] == str[s] || pattern[p] == '?') {
p += 1;
s += 1;
continue;
}
if (pattern[p] == '*') {
if (p+1 == patt_len) return true;
if (p + 1 == patt_len) return true;
do {
if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) {
if (SafeFNMatch_(pattern + (p + 1), patt_len - (p + 1), str + s,
str_len - s)) {
return true;
}
s += 1;
@ -177,10 +181,9 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
found = true;
}
info->vlog_level = log_level;
} else if (!found &&
SafeFNMatch_(info->module_pattern.c_str(),
info->module_pattern.size(),
module_pattern, pattern_len)) {
} else if (!found && SafeFNMatch_(info->module_pattern.c_str(),
info->module_pattern.size(),
module_pattern, pattern_len)) {
result = info->vlog_level;
found = true;
}
@ -216,8 +219,8 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
// NOTE: Individual VLOG statements cache the integer log level pointers.
// NOTE: This function must not allocate memory or require any locks.
bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
const char* fname, int32 verbose_level) {
bool InitVLOG3__(SiteFlag* site_flag, int32* level_default, const char* fname,
int32 verbose_level) {
MutexLock l(&vmodule_lock);
bool read_vmodule_flag = inited_vmodule;
if (!read_vmodule_flag) {
@ -240,13 +243,13 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
}
#endif
base = base ? (base+1) : fname;
base = base ? (base + 1) : fname;
const char* base_end = strchr(base, '.');
size_t base_length =
base_end ? static_cast<size_t>(base_end - base) : strlen(base);
// Trim out trailing "-inl" if any
if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
if (base_length >= 4 && (memcmp(base + base_length - 4, "-inl", 4) == 0)) {
base_length -= 4;
}
@ -260,8 +263,8 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
base, base_length)) {
site_flag_value = &info->vlog_level;
// value at info->vlog_level is now what controls
// the VLOG at the caller site forever
// value at info->vlog_level is now what controls
// the VLOG at the caller site forever
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
*/
#ifndef _WIN32
# error You should only be including windows/port.cc in a windows environment!
# error You should only be including windows/port.cc in a windows environment!
#endif
#include "port.h"
@ -47,7 +47,7 @@ struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
localtime_s(result, timep);
return result;
}
#endif // not HAVE_LOCALTIME_R
#endif // not HAVE_LOCALTIME_R
#ifndef HAVE_GMTIME_R
struct tm* gmtime_r(const std::time_t* timep, std::tm* result) {
gmtime_s(result, timep);

View File

@ -45,26 +45,26 @@
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
#endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
# endif
#include <direct.h> /* for _getcwd() */
#include <io.h> /* because we so often use open/close/etc */
#include <process.h> /* for _getpid() */
#include <windows.h>
#include <winsock.h> /* for gethostname */
# include <direct.h> /* for _getcwd() */
# include <io.h> /* because we so often use open/close/etc */
# include <process.h> /* for _getpid() */
# include <windows.h>
# include <winsock.h> /* for gethostname */
#include <cstdarg> /* template_dictionary.cc uses va_copy */
#include <cstring> /* for _strnicmp(), strerror_s() */
#include <ctime> /* for localtime_s() */
# include <cstdarg> /* template_dictionary.cc uses va_copy */
# include <cstring> /* for _strnicmp(), strerror_s() */
# include <ctime> /* for localtime_s() */
/* Note: the C++ #includes are all together at the bottom. This file is
* used by both C and C++ code, so we put all the C++ together.
*/
#include "glog/logging.h"
# include "glog/logging.h"
#ifdef _MSC_VER
# ifdef _MSC_VER
/* 4244: otherwise we get problems when substracting two size_t's to an int
* 4251: it's complaining about a private struct I've chosen not to dllexport
@ -76,84 +76,85 @@
* 4267: also subtracting two size_t to int
* 4722: Destructor never returns due to abort()
*/
#pragma warning(disable:4244 4251 4355 4715 4800 4996 4267 4312 4722)
# pragma warning(disable : 4244 4251 4355 4715 4800 4996 4267 4312 4722)
/* file I/O */
#define PATH_MAX 1024
#define popen _popen
#define pclose _pclose
#define R_OK 04 /* read-only (for access()) */
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
# define PATH_MAX 1024
# define popen _popen
# define pclose _pclose
# define R_OK 04 /* read-only (for access()) */
# define S_ISDIR(m) (((m)&_S_IFMT) == _S_IFDIR)
#define O_WRONLY _O_WRONLY
#define O_CREAT _O_CREAT
#define O_EXCL _O_EXCL
# define O_WRONLY _O_WRONLY
# define O_CREAT _O_CREAT
# define O_EXCL _O_EXCL
#ifndef __MINGW32__
# ifndef __MINGW32__
enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
#endif
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
# endif
# define S_IRUSR S_IREAD
# define S_IWUSR S_IWRITE
/* Not quite as lightweight as a hard-link, but more than good enough for us. */
#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false)
# define link(oldpath, newpath) CopyFileA(oldpath, newpath, false)
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
# define strcasecmp _stricmp
# define strncasecmp _strnicmp
/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */
/* VC11 provides std::hash */
#if defined(_MSC_VER) && (_MSC_VER < 1700)
#define hash hash_compare
#endif
# if defined(_MSC_VER) && (_MSC_VER < 1700)
# define hash hash_compare
# endif
/* Sleep is in ms, on windows */
#define sleep(secs) Sleep((secs) * 1000)
# define sleep(secs) Sleep((secs)*1000)
/* Windows doesn't support specifying the number of buckets as a
* hash_map constructor arg, so we leave this blank.
*/
#define CTEMPLATE_SMALL_HASHTABLE
# define CTEMPLATE_SMALL_HASHTABLE
#define DEFAULT_TEMPLATE_ROOTDIR ".."
# define DEFAULT_TEMPLATE_ROOTDIR ".."
// ----------------------------------- SYSTEM/PROCESS
typedef int pid_t;
#define getpid _getpid
# define getpid _getpid
#endif // _MSC_VER
# endif // _MSC_VER
// ----------------------------------- THREADS
#if defined(HAVE_PTHREAD)
# include <pthread.h>
#else // no PTHREAD
# if defined(HAVE_PTHREAD)
# include <pthread.h>
# else // no PTHREAD
typedef DWORD pthread_t;
typedef DWORD pthread_key_t;
typedef LONG pthread_once_t;
enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
#define pthread_self GetCurrentThreadId
#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2))
#endif // HAVE_PTHREAD
enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
# define pthread_self GetCurrentThreadId
# define pthread_equal(pthread_t_1, pthread_t_2) \
((pthread_t_1) == (pthread_t_2))
# endif // HAVE_PTHREAD
#ifndef HAVE_LOCALTIME_R
# ifndef HAVE_LOCALTIME_R
extern GLOG_EXPORT std::tm* localtime_r(const std::time_t* timep,
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);
#endif // not HAVE_GMTIME_R
# endif // not HAVE_GMTIME_R
inline char* strerror_r(int errnum, char* buf, std::size_t buflen) {
strerror_s(buf, buflen, errnum);
return buf;
}
#ifndef __cplusplus
# ifndef __cplusplus
/* I don't see how to get inlining for C code in MSVC. Ah well. */
#define inline
#endif
# define inline
# endif
#endif /* _WIN32 */
#endif /* _WIN32 */
#endif /* CTEMPLATE_WINDOWS_PORT_H_ */
#endif /* CTEMPLATE_WINDOWS_PORT_H_ */